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.