Hi There,
I have a problem related to I2C transmission. Everything is configurated ok. I can communicate with a capacitive sensor but this sensor deactivate when the stop sequence SCL rise before SDA line. You can see at figure below the point A the line SCL is normal, but at the point B an C remain in last state.
I am using NRF52840 (dongle) with the Capacitive Sensor Azoteq IQS227


Is there how to setup the I2C CLK to control this?
Here is the code:
#include <soc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/settings/settings.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/usb/usb_device.h>
#include "uart_async_adapter.h"
#include <bluetooth/services/nus.h>
#include <dk_buttons_and_leds.h>
// Special Routines
#include "includes/variables.h"
#include "includes/special.h"
#define LOG_MODULE_NAME peripheral_uart
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#define STACKSIZE CONFIG_BT_NUS_THREAD_STACK_SIZE
#define PRIORITY 7
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
#define KEY_PASSKEY_ACCEPT DK_BTN1_MSK
#define KEY_PASSKEY_REJECT DK_BTN2_MSK
#define UART_BUF_SIZE CONFIG_BT_NUS_UART_BUFFER_SIZE
#define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
#define UART_WAIT_FOR_RX CONFIG_BT_NUS_UART_RX_WAIT_TIME
static K_SEM_DEFINE(ble_init_ok, 0, 1);
static struct bt_conn *current_conn;
static struct bt_conn *auth_conn;
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
static const struct bt_data sd[] = {
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL),
};
#if CONFIG_BT_NUS_UART_ASYNC_ADAPTER
UART_ASYNC_ADAPTER_INST_DEFINE(async_adapter);
#else
static const struct device *const async_adapter;
#endif
/*Device i2c*/
//static const struct device *i2c;
#define I2C0_NODE DT_NODELABEL(mysensor)
static const struct i2c_dt_spec dev_i2c = I2C_DT_SPEC_GET(I2C0_NODE);
/* The devicetree node identifier for the "led0" alias. */
#define LED3_NODE DT_ALIAS(led3)
#define LED0_NODE DT_ALIAS(led0)
#define UART_BUF_SIZE 100
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec led_blue = GPIO_DT_SPEC_GET(LED3_NODE, gpios);
#define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
#define UART_WAIT_FOR_RX 50
static const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0));
static struct k_work_delayable uart_work;
struct uart_data_t
{
void *fifo_reserved;
uint8_t data[UART_BUF_SIZE];
uint16_t len;
};
struct uart_data_t *buf_extra;
uint32_t buff_extra_index=0;
uint32_t buff_marker=0;
static K_FIFO_DEFINE(fifo_uart_tx_data);
static K_FIFO_DEFINE(fifo_uart_rx_data);
static K_FIFO_DEFINE(command_rx);
static K_FIFO_DEFINE(command_tx);
// SEMAPHORES FOR THREADS
static K_SEM_DEFINE(BUTTON1_pressed, 0, 1);
static K_SEM_DEFINE(led_init_ok, 0, 1);
static K_SEM_DEFINE(motor_output, 0, 1);
static K_SEM_DEFINE(digital0_external_on, 0, 1);
static K_SEM_DEFINE(digital0_external_on_ready, 0, 1);
static K_SEM_DEFINE(digital1_external_on, 0, 1);
static K_SEM_DEFINE(digital1_external_on_ready, 0, 1);
static K_SEM_DEFINE(i2c_signal, 0, 1);
static K_SEM_DEFINE(i2c_init_ok, 0, 1);
//DIGITAL OUTPUT
#define DIG_0_NODE DT_ALIAS(dg0)
static const struct gpio_dt_spec digital_dig0 = GPIO_DT_SPEC_GET_OR(DIG_0_NODE, gpios, {0});
#define DIG_OUT_0_ADR &digital_dig0
#define DIG_OUT_0 digital_dig0
#define DIG_1_NODE DT_ALIAS(dg1)
static const struct gpio_dt_spec digital_dig1 = GPIO_DT_SPEC_GET_OR(DIG_1_NODE, gpios, {0});
#define DIG_OUT_1_ADR &digital_dig1
#define DIG_OUT_1 digital_dig1
//DIGITAL INPUT
#define DIG_IN_0_NODE DT_ALIAS(in0)
static const struct gpio_dt_spec digital_dig_in0 = GPIO_DT_SPEC_GET_OR(DIG_IN_0_NODE, gpios, {0});
static struct gpio_callback digital_cb_data_dig_in0;
#define DIG_0_ADR &digital_dig_in0
#define DIG_0 digital_dig_in0
#define DIG_0_CB &digital_cb_data_dig_in0
#define DIG_IN_1_NODE DT_ALIAS(in1)
static const struct gpio_dt_spec digital_dig_in1 = GPIO_DT_SPEC_GET_OR(DIG_IN_1_NODE, gpios, {0});
static struct gpio_callback digital_cb_data_dig_in1;
#define DIG_1_ADR &digital_dig_in1
#define DIG_1 digital_dig_in1
#define DIG_1_CB &digital_cb_data_dig_in1
//ADC
#if !DT_NODE_EXISTS(DT_N_S_soc_S_adc_40007000) || \
!DT_NODE_HAS_PROP(DT_N_S_soc_S_adc_40007000, io_channels)
#error "No suitable devicetree overlay specified"
#endif
#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
static const struct adc_dt_spec adc_channels[] = { DT_FOREACH_PROP_ELEM(DT_N_S_soc_S_adc_40007000, io_channels, DT_SPEC_AND_COMMA)
};
/*BLE ROUTINES START */
static void connected(struct bt_conn *conn, uint8_t err)
{
char addr[BT_ADDR_LE_STR_LEN];
if (err) {
if (DEBUG_BLE)printf("Connection failed (err %u)\n", err);
return;
}
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (DEBUG_BLE)printf("Connected %s \n", addr);
current_conn = bt_conn_ref(conn);
dk_set_led_on(CON_STATUS_LED);
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (DEBUG_BLE)printf("Disconnected: %s (reason %u)\n", addr, reason);
if (auth_conn) {
bt_conn_unref(auth_conn);
auth_conn = NULL;
}
if (current_conn) {
bt_conn_unref(current_conn);
current_conn = NULL;
dk_set_led_off(CON_STATUS_LED);
}
}
#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
static void security_changed(struct bt_conn *conn, bt_security_t level,
enum bt_security_err err)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (!err) {
if (DEBUG_BLE)printf("Security changed: %s level %u\n", addr, level);
} else {
if (DEBUG_BLE)printf("Security failed: %s level %u err %d\n", addr,
level, err);
}
}
#endif
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
.security_changed = security_changed,
#endif
};
#if defined(CONFIG_BT_NUS_SECURITY_ENABLED)
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("Passkey for %s: %06u", addr, passkey);
}
static void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey)
{
char addr[BT_ADDR_LE_STR_LEN];
auth_conn = bt_conn_ref(conn);
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("Passkey for %s: %06u", addr, passkey);
LOG_INF("Press Button 1 to confirm, Button 2 to reject.");
}
static void auth_cancel(struct bt_conn *conn)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("Pairing cancelled: %s", addr);
}
static void pairing_complete(struct bt_conn *conn, bool bonded)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("Pairing completed: %s, bonded: %d", addr, bonded);
}
static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("Pairing failed conn: %s, reason %d", addr, reason);
}
static struct bt_conn_auth_cb conn_auth_callbacks = {
.passkey_display = auth_passkey_display,
.passkey_confirm = auth_passkey_confirm,
.cancel = auth_cancel,
};
static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
.pairing_complete = pairing_complete,
.pairing_failed = pairing_failed
};
#else
static struct bt_conn_auth_cb conn_auth_callbacks;
static struct bt_conn_auth_info_cb conn_auth_info_callbacks;
#endif
/*BLE INSTRUCTION DECISION*/
void ble_instruction(uint8_t command){
//receive an instruction command and executes
switch(command){
case CMD_STOP:
gpio_pin_set_dt(&digital_dig0, MOTOR_OFF); //LED
gpio_pin_set_dt(&digital_dig1, OFF);//CAPACITIVE SENSOR OFF
break;
case CMD_START:
gpio_pin_set_dt(&digital_dig0, MOTOR_ON);//LED
gpio_pin_set_dt(&digital_dig1, ON);//CAPACITIVE SENSOR ON
break;
case CMD_SEND_A:
k_sem_give(&i2c_signal);
break;
}
}
/*SENDING OK*/
static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data, uint16_t len)
{
int err;
char addr[BT_ADDR_LE_STR_LEN] = {0};
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, ARRAY_SIZE(addr));
if (DEBUG_BLE)printf("Received data from: %s\n", addr);
for (uint16_t pos = 0; pos != len;) {
struct uart_data_t *tx = k_malloc(sizeof(*tx));
if (!tx) {
if (DEBUG_BLE)printf("Not able to allocate UART send data buffer 1\n");
return;
}
/* Keep the last byte of TX buffer for potential LF char. */
size_t tx_data_size = sizeof(tx->data) - 1;
if ((len - pos) > tx_data_size) {
tx->len = tx_data_size;
} else {
tx->len = (len - pos);
}
memcpy(tx->data, &data[pos], tx->len);
pos += tx->len;
/* Append the LF character when the CR character triggered
* transmission from the peer.
*/
if ((pos == len) && (data[len - 1] == '\r')) {
tx->data[tx->len] = '\n';
tx->len++;
}
err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
//receive an instruction from BLE
ble_instruction(tx->data[0]);
uint16_t i=0;
while(i<tx->len){
printf("Received from BLE:%c",tx->data[i]);
i++;
}
printf("\n");
//clear the buffer here.....
if (err) {
k_fifo_put(&fifo_uart_tx_data, tx);
}
}
}
static struct bt_nus_cb nus_cb = {
.received = bt_receive_cb,
};
void error(void)
{
dk_set_leds_state(DK_ALL_LEDS_MSK, DK_NO_LEDS_MSK);
while (true) {
/* Spin for ever */
k_sleep(K_MSEC(1000));
}
}
#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
static void num_comp_reply(bool accept)
{
if (accept) {
bt_conn_auth_passkey_confirm(auth_conn);
LOG_INF("Numeric Match, conn %p", (void *)auth_conn);
} else {
bt_conn_auth_cancel(auth_conn);
LOG_INF("Numeric Reject, conn %p", (void *)auth_conn);
}
bt_conn_unref(auth_conn);
auth_conn = NULL;
}
void button_changed(uint32_t button_state, uint32_t has_changed)
{
uint32_t buttons = button_state & has_changed;
if (auth_conn) {
if (buttons & KEY_PASSKEY_ACCEPT) {
num_comp_reply(true);
}
if (buttons & KEY_PASSKEY_REJECT) {
num_comp_reply(false);
}
}
}
#endif /* CONFIG_BT_NUS_SECURITY_ENABLED */
static void configure_gpio(void)
{
int err;
#ifdef CONFIG_BT_NUS_SECURITY_ENABLED
err = dk_buttons_init(button_changed);
if (err) {
printf("Cannot init buttons (err: %d)\n", err);
}
#endif /* CONFIG_BT_NUS_SECURITY_ENABLED */
err = dk_leds_init();
if (err) {
printf("Cannot init LEDs (err: %d)\n", err);
}
}
/*BLE ROUTINES END*/
void envia_ble_temp(Values_Temp *data){
char To_Send[40];
snprintf(To_Send,sizeof(To_Send), "NTC1=%02.1f", data->value[0]);
uint16_t size = strlen(To_Send);
if (current_conn)bt_nus_send(NULL, To_Send, size);
}
void envia_ble_ampere(float *data){
char To_Send[40];
snprintf(To_Send,sizeof(To_Send), "%02.2f ampere", *data);
uint16_t size = strlen(To_Send);
if (current_conn)bt_nus_send(NULL, To_Send, size);
}
void envia_ble_msg(char *data){
char To_Send[40];
snprintf(To_Send,sizeof(To_Send), "%s",data);
uint16_t size = strlen(To_Send);
if (current_conn)bt_nus_send(NULL, To_Send, size);
}
void digital_0_call_back(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
if (k_sem_count_get(&digital0_external_on_ready)){
k_sem_take(&digital0_external_on_ready,K_NO_WAIT);
k_sem_give(&digital0_external_on);
}
}
void digital_1_call_back(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
if (k_sem_count_get(&digital1_external_on_ready)){
k_sem_take(&digital1_external_on_ready,K_NO_WAIT);
k_sem_give(&digital1_external_on);
}
}
void configure_digital_inputs(void)
{
gpio_pin_configure_dt(DIG_0_ADR, GPIO_INPUT);
gpio_pin_interrupt_configure_dt(DIG_0_ADR, GPIO_INT_EDGE_TO_ACTIVE);
gpio_init_callback(DIG_0_CB, digital_0_call_back, BIT(DIG_0.pin));
gpio_add_callback(DIG_0.port, DIG_0_CB);
printf("Set up Digital Input at %s pin %d\n", DIG_0.port->name, DIG_0.pin);
gpio_pin_configure_dt(DIG_1_ADR, GPIO_INPUT);
gpio_pin_interrupt_configure_dt(DIG_1_ADR, GPIO_INT_EDGE_TO_ACTIVE);
gpio_init_callback(DIG_1_CB, digital_1_call_back, BIT(DIG_1.pin));
gpio_add_callback(DIG_1.port, DIG_1_CB);
printf("Set up Digital Input at %s pin %d\n", DIG_1.port->name, DIG_1.pin);
}
void led_init(){
int ret;
if (!device_is_ready(led.port)) {
return;
}
if (!device_is_ready(led_blue.port)) {
return;
}
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
return;
}
ret = gpio_pin_configure_dt(&led_blue, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
return;
}
k_sem_give(&led_init_ok);
}
void blink_output(struct gpio_dt_spec *digital_output, uint8_t times)
{
uint8_t i = 0;
while (i < times)
{
gpio_pin_set_dt(digital_output, ON);
k_sleep(K_MSEC(50));
gpio_pin_set_dt(digital_output, OFF);
k_sleep(K_MSEC(50));
i++;
}
}
void configure_digital_outputs(void)
{
gpio_pin_configure_dt(&digital_dig0, GPIO_OUTPUT);
printf("Set up Digital Output at %s pin %d\n", DIG_OUT_0.port->name, DIG_OUT_0.pin);
gpio_pin_configure_dt(&digital_dig1, GPIO_OUTPUT);
printf("Set up Digital Output at %s pin %d\n", DIG_OUT_1.port->name, DIG_OUT_1.pin);
}
void turn_off_all_digital_ports(void)
{
gpio_pin_set_dt(&digital_dig0, OFF);
gpio_pin_set_dt(&digital_dig1, MOTOR_OFF);
}
void turn_on_motor(void)
{
gpio_pin_set_dt(&digital_dig0, MOTOR_ON); //MOTOR
}
void turn_off_motor(void)
{
gpio_pin_set_dt(&digital_dig0, MOTOR_OFF); //MOTOR
}
void initial_message(void)
{
printf("#########################\n"); //TEST SERIAL
printf("OASE - ACQUA LEVEL SENSOR\n"); //TEST SERIAL
printf("#########################\n"); //TEST SERIAL
}
void iqs_pn(void){
uint8_t sensor_regs[2] ={0x00,0x00};
uint8_t reading[2]= {0};
int ret=1;
ret = i2c_write_read_dt(&dev_i2c,&sensor_regs[0],1,&reading[0],1);
printf("Capacitive Sensor Number: %d \n", reading[0]);
}
void i2c_init(void){
uint8_t sensor_regs[2] ={0x0F,0x00};
uint8_t reading[2]= {0};
int ret,ret_b=0;
if (!device_is_ready(dev_i2c.bus)) {
printf("I2C bus %s is not ready!\n\r",dev_i2c.bus->name);
}else printf("I2C bus %s OK ready!\n\r",dev_i2c.bus->name);
/*
From after 2ms after Power On
Till 17ms after Power On
(Thus, 15ms wide)
2ms < Window < 17ms
Your microcontroller should poll the IQS227/8 in this window to ensure it can enter Test Mode.
By polling the device within ttest_mode AND receiving an “ACK” (acknowledge), test mode will be entered.
Confirm this by the following:
Write 0x0F (register address to confirm test mode)
Read data If data = 0xA5, then test mode = True
If only a NACK is received, repeat the polling by address until receiving an “ACK”
If no “ACK” is achieved, review the ttest_mode time to ensure polling is done within the correct
window.
*/
gpio_pin_set_dt(&digital_dig1, SENSOR_CAPACITIVE_OFF);//CAPACITIVE SENSOR OFF
k_sleep(K_MSEC(500));
gpio_pin_set_dt(&digital_dig1, SENSOR_CAPACITIVE_ON);//CAPACITIVE SENSOR ON
k_sleep(K_MSEC(4)); //WAIT 2ms
while (reading[0]!=0xA5){
ret = i2c_write_read_dt(&dev_i2c,&sensor_regs[0],1,&reading[0],1);
if (ret != 0){reading[0]=0x00;}
}
ret = i2c_write_read_dt(&dev_i2c,&sensor_regs[0],1,&reading[0],1);
k_sleep(K_MSEC(2)); //WAIT 100ms
ret = i2c_write_read_dt(&dev_i2c,&sensor_regs[0],1,&reading[0],1);
k_sleep(K_MSEC(2)); //WAIT 100ms
ret = i2c_write_read_dt(&dev_i2c,&sensor_regs[0],1,&reading[0],1);
k_sleep(K_MSEC(2)); //WAIT 100ms
///PROBLEMA é ALTERAR O STOP BIT ( TEM QUE FAZER ELE FICAR ALTO NO FINAL DA COMUNICACAO)
sensor_regs[0]=0xFC;
sensor_regs[1]=0x10;
ret = i2c_write_dt(&dev_i2c,&sensor_regs,2);
k_sleep(K_MSEC(10)); //WAIT 100ms
//iqs_pn();
//release the thread
k_sem_give(&i2c_init_ok);
}
void main(void)
{
k_sleep(K_MSEC(2000));
printf("Start\n");
configure_digital_outputs();
configure_gpio();
configure_digital_inputs();
led_init();
int blink_status = 0;
int err = 0;
k_sem_give(&digital0_external_on_ready); // TURN ON DIGITAL0 INPUT
k_sem_give(&digital1_external_on_ready); // TURN ON DIGITAL1 INPUT
i2c_init();
if (IS_ENABLED(CONFIG_BT_NUS_SECURITY_ENABLED)) {
err = bt_conn_auth_cb_register(&conn_auth_callbacks);
if (err) {
if (DEBUG_BLE)printf("Failed to register authorization callbacks.\n");
return 0;
}
err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
if (err) {
if (DEBUG_BLE)printf("Failed to register authorization info callbacks.\n");
return 0;
}
}
err = bt_enable(NULL);
if (err) {
error();
}
if (DEBUG_BLE)printf("Bluetooth initialized\n");
k_sem_give(&ble_init_ok);
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
err = bt_nus_init(&nus_cb);
if (err) {
if (DEBUG_BLE)printf("Failed to initialize UART service (err: %d)\n", err);
return 0;
}
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd,
ARRAY_SIZE(sd));
if (err) {
if (DEBUG_BLE)printf("Advertising failed to start (err %d)\n", err);
return 0;
}
for (;;) {
dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
}
}
void led_thread(void){
int ret;
k_sem_take(&led_init_ok,K_FOREVER); // wait for led to be configured
k_sem_take(&BUTTON1_pressed,K_FOREVER); //init after button pressed
while (1) {
//ret = gpio_pin_toggle_dt(&led);
//ret = gpio_pin_toggle_dt(&led_blue);
k_msleep(SLEEP_TIME_MS);
}
}
void adc_thread(void)
{
int err;
/*CHANNEL 0 IN USE
CHANNEL 5 NOT IN USE
*/
//char Name[] = "TESTE 123";
//uint16_t size;
Values_Temp AD_Value;
float voltageUc;
int32_t ad_valor[3];
float dif;
uint16_t buf;
struct adc_sequence sequence = {
.buffer = &buf,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(buf),
};
/* Configure channels individually prior to sampling. */
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
//for (size_t i = 0U; i < 3; i++) {
if (!device_is_ready(adc_channels[i].dev)) {
printf("ADC controller device %s not ready\n", adc_channels[i].dev->name);
}
err = adc_channel_setup_dt(&adc_channels[i]);
if (err < 0) {
printf("Could not setup channel #%d (%d)\n", i, err);
}
}
while (1) {
//printf("ADC reading[%u]:\n", count++);
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
//for (size_t i = 0U; i < 3; i++) {
int32_t val_mv;
//printf("- %s, channel %d: ",adc_channels[i].dev->name,adc_channels[i].channel_id);
(void)adc_sequence_init_dt(&adc_channels[i], &sequence);
err = adc_read(adc_channels[i].dev, &sequence);
if (err < 0) {
printf("Could not read (%d)\n", err);
continue;
}
/*
* If using differential mode, the 16 bit value
* in the ADC sample buffer should be a signed 2's
* complement value.
*/
if (adc_channels[i].channel_cfg.differential) {
val_mv = (int32_t)((int16_t)buf);
} else {
val_mv = (int32_t)buf;
}
//printf("%"PRId32, val_mv);
ad_valor[i]=val_mv;
err = adc_raw_to_millivolts_dt(&adc_channels[i],
&val_mv);
/* conversion to mV may not be supported, skip if not */
if (err < 0) {
printf(" (value in mV not available)\n");
} else {
//printf(" = %"PRId32" mV ", val_mv);
}
if (i<2){
//if(DEBUG)printf("NTC%d=%2.1f \n",0,ntc_temperature(ad_valor[0],0));
//if(DEBUG)printf("NTC%d=%2.1f ",1,ntc_temperature(ad_valor[1],1));
if(DEBUG)AD_Value.value[i] = ntc_temperature(ad_valor[i],i);
}
}
printf("NTC%d=%2.1f ",0,ntc_temperature(ad_valor[0],0));
uint16_t conversao_corrente = ad_valor[1];
voltageUc = conversao_corrente * (ADC_VOLTAGE_REF/(ADC_RESOLUTION-1));
float current= (voltageUc-0.3)*2.1834; //200mV=1A
if (current<=0.1)current=0;
if(DEBUG)printf("Current Sensor=%2.2f A voltage=%2.2f\n",current,voltageUc);
//envia_ble_temp(&AD_Value);
envia_ble_ampere(¤t);
k_sleep(K_MSEC(ADC_INTERVAL));
if(CLEAR_SCREEN)printf("%c%c",0x1b,0x63); //clear screen
}
}
void shoot_minute_thread(void)
{
// each one minute this thread will shot.
uint64_t actual_time = k_uptime_get() / 1000;
signed int h, m, s, last_minute;
h = (actual_time / 3600);
m = (actual_time - (3600 * h)) / 60;
s = (actual_time - (3600 * h) - (m * 60));
last_minute = m;
// time_print ();
//k_sem_take(&timer_init,K_FOREVER); //wait init
while (1)
{
actual_time = k_uptime_get() / 1000;
h = (actual_time / 3600);
m = (actual_time - (3600 * h)) / 60;
s = (actual_time - (3600 * h) - (m * 60));
if (m == (last_minute + 1))
{
last_minute = m;
if (m == 59)
{
last_minute = -1;
}
if (h == 24)
{
h = 0;
} // only up to 23:59:59h
// START RUN THE MINUTE ROUTINE
//k_sem_give(&circular_buffer_sh);
printf("Minute Cycle thread \n");
}
k_sleep(K_MSEC(100));
}
}
void motor_control_on_thread(void){
char msg_on[]= "MOTOR ON";
char msg_off[]= "MOTOR OFF";
while(1){
if(!k_sem_count_get(&motor_output)){
turn_off_motor();
envia_ble_msg(&msg_off);
printf("%s\n",msg_off);
}
k_sem_take(&motor_output,K_FOREVER);
turn_on_motor();
envia_ble_msg(&msg_on);
printf("%s\n",msg_on);
k_sleep(K_MSEC(PUMP_ON_TIME*1000*0.90));
k_sem_take(&motor_output,K_NO_WAIT);
k_sleep(K_MSEC(PUMP_ON_TIME*1000*0.10));
}
}
void ble_write_thread(void)
{
/* Don't go any further until BLE is initialized */
k_sem_take(&ble_init_ok, K_FOREVER);
for (;;) {
/* Wait indefinitely for data to be sent over bluetooth */
struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data,
K_FOREVER);
if (bt_nus_send(NULL, buf->data, buf->len)) {
if (DEBUG_BLE)printf("Failed to send data over BLE connection2 \n");
}
k_free(buf);
}
}
void digital0_input_thread(void){
char msg[]="WATER DETECTED";
while(1){
k_sem_take(&digital0_external_on,K_FOREVER);
envia_ble_msg(msg);
printf("%s\n",msg);
k_sem_give(&motor_output);
k_sleep(K_MSEC(DIGITAL0_INPUT_DELAY));
k_sem_give(&digital0_external_on_ready);
}
}
void digital1_input_thread(void){
char msg[]="WATER MAX LEVEL";
while(1){
k_sem_take(&digital1_external_on,K_FOREVER);
envia_ble_msg(msg);
printf("%s\n",msg);
k_sleep(K_MSEC(DIGITAL1_INPUT_DELAY));
k_sem_give(&digital1_external_on_ready);
}
}
void i2c_control_thread(void){
/*
https://academy.nordicsemi.com/courses/nrf-connect-sdk-fundamentals/lessons/lesson-6-serial-com-i2c/topic/i2c-driver/
*/
uint8_t device_id=I2C_DEVICE_ID;
uint8_t *value;
uint8_t ret;
uint8_t config[8] = {0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};
uint8_t sensor_regs[2] ={0x02,0x00};
uint8_t temp_reading[2]= {0};
k_sem_take(&i2c_init_ok,K_FOREVER);
while(1){
//i2c_write_dt(&dev_i2c, &config, sizeof(config));
k_sleep(K_MSEC(3));
}
}
// THREADS START
//K_THREAD_DEFINE(digital0_input_id, 2048, digital0_input_thread, NULL, NULL, NULL, 2, 0, 0);
//K_THREAD_DEFINE(digital1_input_id, 2048, digital1_input_thread, NULL, NULL, NULL, 2, 0, 0);
K_THREAD_DEFINE(i2c_control_thread_id, 2048, i2c_control_thread, NULL, NULL, NULL, 2, 0, 0);
K_THREAD_DEFINE(led_thread_id, 2048, led_thread, NULL, NULL, NULL, 2, 0, 0);
K_THREAD_DEFINE(adc_thread_id, 2048, adc_thread, NULL, NULL,NULL, 2, 0, 0);
K_THREAD_DEFINE(shoot_minute_thread_id, 2048, shoot_minute_thread, NULL, NULL,NULL, 2, 0, 0);
K_THREAD_DEFINE(motor_control_on_id, 2048, motor_control_on_thread, NULL, NULL,NULL, 2, 0, 0);
K_THREAD_DEFINE(ble_write_thread_id, 4096, ble_write_thread, NULL, NULL,NULL, PRIORITY, 0, 0);
&rng_hci {
status = "disabled";
};
/ {
aliases {
dg0 = &dig0;
dg1 = &dig1;
adc = &adc;
in0 = &in0;
in1 = &in1;
i2c0 =&i2c0;
};
};
/{
chosen {
nordic,nrf-adc = &adc;
nordic,nus-uart = &uart0;
zephyr,shell-uart = &uart0;
zephyr,uart-mcumgr = &uart0;
zephyr,bt-mon-uart = &uart0;
zephyr,bt-c2h-uart = &uart0;
};
output_digital {
compatible = "gpio-keys";
dig0: dig_0 {
label = "Digital Output 0";
};
dig1: dig_1 {
label = "Digital Output 1";
};
};
input_digital {
compatible = "gpio-keys";
in0: in0 {
label = "Data Digital Input 0";
};
in1: in1 {
label = "Clock Digital Input 1";
};
};
};
// 0.10 DATA
// 0.09 CLOCK
&adc {
#address-cells = <1>;
#size-cells = <0>;
io-channels = <&adc 0>, <&adc 5>;
channel@0 {
reg = <0>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_AIN0>; /* P0.03 */
zephyr,resolution = <14>;
zephyr,oversampling = <8>;
};
channel@5 {
reg = <5>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_AIN5>;
zephyr,resolution = <14>;
zephyr,oversampling = <8>;
};
};
&sw_pwm {
status = "disabled";
};
&dig0 {
gpios = <&gpio0 13 0>; // MOTOR
};
&dig1 {
gpios = <&gpio1 0 0>; // OPTIONAL
};
&in0 {
gpios = < &gpio0 16 (GPIO_PULL_UP | GPIO_ACTIVE_LOW) >;
};
&in1 {
gpios = < &gpio0 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW) >;
};
&i2c0 {
compatible = "nordic,nrf-twim";
status = "okay";
label="I2C_0";
pinctrl-names = "default", "sleep";
clock-frequency = <I2C_BITRATE_FAST>; //maximum 400khz
mysensor:mysensor@44{
compatible = "i2c-device";
reg = < 0x44 >;
label = "MYSENSOR";
};
};
&i2c0_default {
group1 {
psels = <NRF_PSEL(TWIM_SDA, 0, 10)>, <NRF_PSEL(TWIM_SCL, 0, 9)>;
};
};
&i2c0_sleep {
group1 {
psels = <NRF_PSEL(TWIM_SDA, 0, 10)>, <NRF_PSEL(TWIM_SCL, 0, 9)>;
};
};
CONFIG_UART_ASYNC_API=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_BT=y CONFIG_FLASH=y CONFIG_FLASH_MAP=y ####NEW CONFIGURATIONS CONFIG_NRFX_UARTE0=y CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="Oase R&D Control-Dongle2" CONFIG_BT_DEVICE_APPEARANCE=833 # Enable the NUS service CONFIG_BT_NUS=y # Enable bonding CONFIG_BT_SETTINGS=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_NVS=y CONFIG_SETTINGS=y # Enable DK LED and Buttons library CONFIG_DK_LIBRARY=y # This example requires more workqueue stack # Config logger CONFIG_LOG=y CONFIG_USE_SEGGER_RTT=y CONFIG_LOG_BACKEND_RTT=y CONFIG_LOG_BACKEND_UART=n CONFIG_LOG_PRINTK=n CONFIG_ASSERT=y CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR=y CONFIG_UART_0_INTERRUPT_DRIVEN=n CONFIG_I2C=y
Thanks in advance,
Flavio.