damiaa 发表于 2024-5-27 21:39

【FireBeetle 2 ESP32 C6开发板】 4 mqtt uart透传

<div class='showpostmsg'> 本帖最后由 damiaa 于 2024-5-27 21:56 编辑

<div><strong><span style="font-size:22px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 【FireBeetle 2 ESP32 C6开发板】 4 mqtt uart透传</span></strong></div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">一、本实验用到esp32 的uart、 mqtt、freertos多任务和信号量。</span></strong></p>

<p><br />
<strong>1,首先我们 创建两个任务uart的收和发</strong></p>

<p><br />
</p>

<p>&nbsp;</p>

<p><strong>2,在创建信号量和共享数据区供mqtt和uart之间共享数据</strong></p>

<p><br />
Mqtt送 数据到uart用到了信号量,uart到mqtt就直接在uart任务里面发了。</p>

<p><br />
<strong>3,定义发送topic/topic/uarttomqtt<br />
和接收topic /topic/mqtttouartq0 /topic/mqtttouartq1 </strong></p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong>4,处理topic数据:</strong></p>

<p></p>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">二、部分代码</span></strong></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">串口相关</span></p>

<pre>
<code class="language-cpp">int sendData_uart0(const char* logName, const char* data,int len)
{
   // const int len = strlen(data);
    const int txBytes = uart_write_bytes(UART_NUM_0, data, len);
    ESP_LOGI(logName, "Wrote %d bytes", txBytes);
    return txBytes;
}
static void tx_task(void *arg)
{
    static const char *TX_TASK_TAG = "TX_TASK";
    esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);
    while (1) {
      if(MtoUsema.xMSet != NULL ){
            xSemaphoreTake(MtoUsema.xMSet, portMAX_DELAY );
            {
                if( MtoUsema.flag ==1)
                {
                     MtoUsema.flag =0;
                  sendData_uart0(TX_TASK_TAG,MtoUsema.buf, MtoUsema.len);
                     MtoUsema.len=0;
                }
            }
            xSemaphoreGive(MtoUsema.xMSet ); /* 互斥量必须归还! */
      }
      
      vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

static void rx_task(void *arg)
{
    static const char *RX_TASK_TAG = "RX_TASK";
    esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
    uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE + 1);
    while (1) {
      const int rxBytes = uart_read_bytes(UART_NUM_0, data, RX_BUF_SIZE, 1000 / portTICK_PERIOD_MS);
      if (rxBytes &gt; 0) {
            data = 0;
            ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data);
            ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);

            UtoMsema.len=rxBytes+1;
            snprintf(UtoMsema.buf,UtoMsema.len,"%s",data);
            UtoMsema.flag =1;
                  esp_mqtt_client_publish(client, "/topic/uarttomqtt", UtoMsema.buf, 0, 0, 0);
                }                     
    }
    free(data);
}
</code></pre>

<p>信号量的创建</p>

<pre>
<code class="language-cpp">typedef struct _SEMA
{
    SemaphoreHandle_t xMSet;
    char buf;
    char flag;
    int len;
}sema;
sema MtoUsema, UtoMsema;



....
while(1){
...

    MtoUsema.flag=0;
    MtoUsema.len=0;
    MtoUsema.xMSet=NULL;
    UtoMsema.flag=0;
    UtoMsema.len=0;
    UtoMsema.xMSet=NULL;
    for(int i=0;i&lt;300;i++)
    {
      MtoUsema.buf=0;
      UtoMsema.buf=0;
    }
    vSemaphoreCreateBinary(MtoUsema.xMSet );
    if(MtoUsema.xMSet != NULL )
    {
    }
    if( MtoUsema.xMSet != NULL ){printf("The semaphore xMSet1 was created successfully! can now be used.\n");}
    vSemaphoreCreateBinary(UtoMsema.xMSet );
    if(UtoMsema.xMSet != NULL )
    {
    }
    if( UtoMsema.xMSet != NULL ){printf("The semaphore xMSet2 was created successfully! can now be used.\n");}
...
}</code></pre>

<p>信号量的使用</p>

<pre>
<code class="language-cpp">...
case MQTT_EVENT_DATA:
      ESP_LOGI(TAG, "MQTT_EVENT_DATA");
      printf("TOPIC=%.*s\r\n", event-&gt;topic_len, event-&gt;topic);
      printf("DATA=%.*s\r\n", event-&gt;data_len, event-&gt;data);
      
      if( MtoUsema.xMSet != NULL ){
            xSemaphoreTake( MtoUsema.xMSet, portMAX_DELAY );
            {
                MtoUsema.len=event-&gt;data_len%300+1;
                snprintf( MtoUsema.buf, MtoUsema.len,"%s",event-&gt;data);
                MtoUsema.flag =1;
            }
            xSemaphoreGive( MtoUsema.xMSet ); /* 互斥量必须归还! */
      }
      break;

...
static void tx_task(void *arg)
{
    static const char *TX_TASK_TAG = "TX_TASK";
    esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);
    while (1) {
      if(MtoUsema.xMSet != NULL ){
            xSemaphoreTake(MtoUsema.xMSet, portMAX_DELAY );
            {
                if( MtoUsema.flag ==1)
                {
                     MtoUsema.flag =0;
                  sendData_uart0(TX_TASK_TAG,MtoUsema.buf, MtoUsema.len);
                     MtoUsema.len=0;
                }
            }
            xSemaphoreGive(MtoUsema.xMSet ); /* 互斥量必须归还! */
      }
      vTaskDelay(2000 / portTICK_PERIOD_MS);
    }
}</code></pre>

<p>&nbsp;</p>

<p>mqtt事件响应</p>

<pre>
<code class="language-cpp">static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event-&gt;client;
    int msg_id;
    switch ((esp_mqtt_event_id_t)event_id) {
    case MQTT_EVENT_CONNECTED:
      ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
      msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "eeworld DFRobtGitrNrrylr2esp32-c6 test qos1", 0, 1, 0);
      ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

      msg_id = esp_mqtt_client_subscribe(client, "/topic/mqtttouartq0", 0);
      ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

      msg_id = esp_mqtt_client_subscribe(client, "/topic/mqtttouartq1", 1);
      ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

      break;
    case MQTT_EVENT_DISCONNECTED:
      ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
      break;

    case MQTT_EVENT_SUBSCRIBED:
      ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event-&gt;msg_id);
      msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "eeworld DFRobtGitrNrrylr2esp32-c6 test qos0", 0, 0, 0);
      ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
      break;
    case MQTT_EVENT_UNSUBSCRIBED:
      ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event-&gt;msg_id);
      break;
    case MQTT_EVENT_PUBLISHED:
      ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event-&gt;msg_id);
      break;
    case MQTT_EVENT_DATA:
      ESP_LOGI(TAG, "MQTT_EVENT_DATA");
      printf("TOPIC=%.*s\r\n", event-&gt;topic_len, event-&gt;topic);
      printf("DATA=%.*s\r\n", event-&gt;data_len, event-&gt;data);
      
      if( MtoUsema.xMSet != NULL ){
            xSemaphoreTake( MtoUsema.xMSet, portMAX_DELAY );
            {
                MtoUsema.len=event-&gt;data_len%300+1;
                snprintf( MtoUsema.buf, MtoUsema.len,"%s",event-&gt;data);
                MtoUsema.flag =1;
            }
            xSemaphoreGive( MtoUsema.xMSet ); /* 互斥量必须归还! */
      }
      break;
    case MQTT_EVENT_ERROR:
      ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
      if (event-&gt;error_handle-&gt;error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
            log_error_if_nonzero("reported from esp-tls", event-&gt;error_handle-&gt;esp_tls_last_esp_err);
            log_error_if_nonzero("reported from tls stack", event-&gt;error_handle-&gt;esp_tls_stack_err);
            log_error_if_nonzero("captured as transport's socket errno",event-&gt;error_handle-&gt;esp_transport_sock_errno);
            ESP_LOGI(TAG, "Last errno string (%s)", strerror(event-&gt;error_handle-&gt;esp_transport_sock_errno));

      }
      break;
    default:
      ESP_LOGI(TAG, "Other event id:%d", event-&gt;event_id);
      break;
    }
}
</code></pre>

<p>&nbsp;</p>

<p><strong><span style="font-size:18px;">三、实验结果如下:</span></strong></p>

<p>&nbsp;</p>

<div>Mqtt到uart</div>

<div></div>

<div>Uart到mqtt</div>

<div></div>

<div>&nbsp;</div>

<div>ed7bc70950a4666c0a597c96e1aa5e9b<br />
&nbsp;</div>

<div>&nbsp;</div>

<div>谢谢。</div>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页: [1]
查看完整版本: 【FireBeetle 2 ESP32 C6开发板】 4 mqtt uart透传