This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF9160 MQTT Serial

Hello All,

I am trying to publish the data gathered from UART using MQTT. So far I was able to get serial data in the inData buffer. I am not able to publish data automatically as soon as data is received on serial port. Can some one please help me out with the same. I would really appreciate it.

void mqtt_evt_handler(struct mqtt_client *const c,
		      const struct mqtt_evt *evt)
{
	int err;

	switch (evt->type) {
	case MQTT_EVT_CONNACK:
		if (evt->result != 0) {
			printk("MQTT connect failed %d\n", evt->result);
			break;
		}

		connected = true;
		printk("[%s:%d] MQTT client connected!\n", __func__, __LINE__);
		subscribe();
		break;

	case MQTT_EVT_DISCONNECT:
		printk("[%s:%d] MQTT client disconnected %d\n", __func__,
		       __LINE__, evt->result);

		connected = false;
		break;

	case MQTT_EVT_PUBLISH: {
		const struct mqtt_publish_param *p = &evt->param.publish;

		printk("[%s:%d] MQTT PUBLISH result=%d len=%d\n", __func__,
		       __LINE__, evt->result, p->message.payload.len);
		err = publish_get_payload(c, p->message.payload.len);
		if (err >= 0) {
			data_print("Received: ", inData,
				sizeof(inData));
			/* Echo back received data */
			data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
				inData, sizeof(inData));
		} else {
			printk("mqtt_read_publish_payload: Failed! %d\n", err);
			printk("Disconnecting MQTT client...\n");

			err = mqtt_disconnect(c);
			if (err) {
				printk("Could not disconnect: %d\n", err);
			}
		}
	} break;

	case MQTT_EVT_PUBACK:
		if (evt->result != 0) {
			printk("MQTT PUBACK error %d\n", evt->result);
			break;
		}

		printk("[%s:%d] PUBACK packet id: %u\n", __func__, __LINE__,
				evt->param.puback.message_id);
		break;

	case MQTT_EVT_SUBACK:
		if (evt->result != 0) {
			printk("MQTT SUBACK error %d\n", evt->result);
			break;
		}

		printk("[%s:%d] SUBACK packet id: %u\n", __func__, __LINE__,
				evt->param.suback.message_id);
		break;

	default:
		printk("[%s:%d] default: %d\n", __func__, __LINE__,
				evt->type);
		break;
	}
}

Parents
  • Hi,

     

    I am trying to publish the data gathered from UART using MQTT. So far I was able to get serial data in the inData buffer. I am not able to publish data automatically as soon as data is received on serial port. Can some one please help me out with the same. I would really appreciate it.

     How are you pushing the data from the uart to the mqtt module? Your uart_evt_handler will likely execute from an interrupt, which then needs to be scheduled to main priority before calling a mqtt_* prefixed function. I would recommend using a workqueue for such task: https://docs.zephyrproject.org/latest/reference/kernel/threads/workqueue.html?highlight=workqueue#

     

    Kind regards,

    Håkon

  • Thanks for the reply Håkon, The following is the code which I am using.

    void uart_cb(struct device *x)
    {
    	uart_irq_update(x);
    	int data_length = 0;
    
    	if (uart_irq_rx_ready(x)) {
    		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    		uart_buf[data_length] = 0;
    	}
    
            if(i==19 || *uart_buf == '?'){ 
            inData[i] = '\0';
            printk("%s\n",inData); // loopback
            i=0;
            data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,inData, sizeof(inData));
            }
            else{
            memcpy(&inData[i], uart_buf, 1); 
            i++;
            }
    }
    In the function uart_cb I make a string of 20 characters or a smaller string when UART sees "?". I store this string in inData variable and add null terminator to make it a string. Then I add data_publish function to publish the data. This doesn't seem to work. On the serial port, I get the loop back as mentioned in the code in comments but the publish function doesn't work. In addition to that once I try to write on serial port, the serial port doesn't responds back. Don't know what to do. Could you please help me out with this.

Reply
  • Thanks for the reply Håkon, The following is the code which I am using.

    void uart_cb(struct device *x)
    {
    	uart_irq_update(x);
    	int data_length = 0;
    
    	if (uart_irq_rx_ready(x)) {
    		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    		uart_buf[data_length] = 0;
    	}
    
            if(i==19 || *uart_buf == '?'){ 
            inData[i] = '\0';
            printk("%s\n",inData); // loopback
            i=0;
            data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,inData, sizeof(inData));
            }
            else{
            memcpy(&inData[i], uart_buf, 1); 
            i++;
            }
    }
    In the function uart_cb I make a string of 20 characters or a smaller string when UART sees "?". I store this string in inData variable and add null terminator to make it a string. Then I add data_publish function to publish the data. This doesn't seem to work. On the serial port, I get the loop back as mentioned in the code in comments but the publish function doesn't work. In addition to that once I try to write on serial port, the serial port doesn't responds back. Don't know what to do. Could you please help me out with this.

Children
Related