Hello,
I am working on MQTT sample ncs\nrf\samples\nrf9160\mqtt_simple. I am sending data from UART and I2C to the mqtt server. For sending data I am using Workqueue thread. This program works properly. I am publishing data from UART and I2C on 2 different topics.
Now I added a button to send SMS on the button press in the above code. The above program works properly until the button press. On button press, UART data continues to send data to the mqtt server, but the I2C data stops.
The Code:
#define SERIAL_Q_SIZE 5 static struct work_data{ struct k_work work; u8_t data[1024]; u8_t data_len; }w_data[SERIAL_Q_SIZE]; void uart_cb(struct device *x) { uart_irq_update(x); int data_length = 0; static int pos, serial_in_count, tot_len = 0; if (uart_irq_rx_ready(x)) { data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf)); tot_len = tot_len + data_length; memcpy(&w_data[serial_in_count].data[pos], uart_buf, data_length); printk("Position is: %d\n", pos); //Check if last char is 'LF' if(uart_buf[data_length-1] == 10){ printk("last char is 'LF', call k_work_submit(), word number %d \n", serial_in_count); w_data[serial_in_count].data_len = tot_len - 1; k_work_submit(&w_data[serial_in_count].work); pos = 0; tot_len = 0; if(serial_in_count < SERIAL_Q_SIZE-1){ serial_in_count++; }else{ serial_in_count=0; } }else{ printk("last char is: %d\n", uart_buf[data_length-1]); pos = pos + data_length; } } //printk("%s", uart_buf); } void pub_uart_mqtt(struct k_work *item) { struct work_data *wrk_data = CONTAINER_OF(item, struct work_data, work); data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, wrk_data->data, wrk_data->data_len); } static int try_to_connect(struct mqtt_client *c) { int rc, i = 0; while (i++ < APP_CONNECT_TRIES && !connected) { client_init(c); rc = mqtt_connect(c); if (rc != 0) { printk("mqtt_connect %d\n", rc); k_sleep(APP_SLEEP_MSECS); continue; } rc = fds_init(c); if (rc != 0) { printk("ERROR: fds_init %d\n", rc); return -EINVAL; } if (poll(&fds, 1, K_SECONDS(CONFIG_MQTT_KEEPALIVE)) < 0) { printk("poll error: %d\n", errno); } mqtt_input(c); if (!connected) { mqtt_abort(c); } } if (connected) { return 0; } return -EINVAL; } static struct work_icm{ struct k_work work1; u8_t data1[1024]; }w_data1; static void mqtt_loop(void){ int rc; u32_t cnt = 0; printk("attempting to connect:\n "); rc = try_to_connect(&client); if (rc != 0) { return; } while (connected) { rc = poll(&fds, 1, K_SECONDS(CONFIG_MQTT_KEEPALIVE)); if (rc < 0) { printk("ERROR: poll %d\n", errno); break; } rc = mqtt_live(&client); if (rc != 0) { printk("ERROR: mqtt_live %d\n", rc); break; } if ((fds.revents & POLLIN) == POLLIN) { rc = mqtt_input(&client); if (rc != 0) { printk("ERROR: mqtt_input %d\n", rc); break; } } if ((fds.revents & POLLERR) == POLLERR) { printk("POLLERR\n"); break; } if ((fds.revents & POLLNVAL) == POLLNVAL) { printk("POLLNVAL\n"); break; } gpio_pin_write(dev, LED, cnt % 2); cnt++; if(button_press) { app_socket_start(); // To send SMS button_press = 0; } if(i2c_read(i2c_accel, ICM, sizeof(ICM), I2C_ACCEL_READ_ADDR) != 0) { printk("Error on i2c_read()\n"); } printk("Value from nrf52 = %s\r\n", ICM); memcpy(&w_data1.data1, ICM, sizeof(ICM)); k_work_submit(&w_data1.work1); // Code stops here // data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, ICM, strlen(ICM)); // If using this, then the code stops here. } rc = mqtt_disconnect(&client); if (rc) { printk("Could not disconnect MQTT client. Error: %d\n", rc); } } void pub_icm_mqtt(struct k_work *item) { struct work_icm *wrk_data = CONTAINER_OF(item, struct work_icm, work1); data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, wrk_data->data1, strlen(ICM)); } void main(void) { button_press=false; gpio_init(); // GPIO Initialization k_sleep(SLEEP_TIME1); init_uart(); // UART Initialization for(int i=0; i < SERIAL_Q_SIZE; i++){ k_work_init(&w_data[i].work, pub_uart_mqtt); } init_accelerometer(); // To initialize I2C_2 k_work_init(&w_data1.work1, pub_icm_mqtt); modem_configure(); while (1) { mqtt_loop(); k_sleep(SLEEP_TIME); } }
I have added just some part of the code.
The while(connected) loop stops on the button press. The UART data is still sent on the server, it means that nRF91 is connected to the mqtt server.
But If I don't publish the I2C data, the while(connected) loop continues to work on the button press also.
I suspect that the problem is in publishing the I2C data to the mqtt server or using k_work_submit in while(connected) loop.
So how can I publish the I2C data without stopping the while(connected) loop?