本帖最后由 damiaa 于 2024-5-27 21:56 编辑
【FireBeetle 2 ESP32 C6开发板】 4 mqtt uart透传
一、本实验用到esp32 的uart、 mqtt、freertos多任务和信号量。
1,首先我们 创建两个任务uart的收和发
2,在创建信号量和共享数据区供mqtt和uart之间共享数据
Mqtt送 数据到uart用到了信号量,uart到mqtt就直接在uart任务里面发了。
3,定义发送topic/topic/uarttomqtt
和接收topic /topic/mqtttouartq0 /topic/mqtttouartq1
4,处理topic数据:
二、部分代码
串口相关
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 > 0) {
data[rxBytes] = 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);
}
信号量的创建
typedef struct _SEMA
{
SemaphoreHandle_t xMSet;
char buf[300];
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<300;i++)
{
MtoUsema.buf[i]=0;
UtoMsema.buf[i]=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");}
...
}
信号量的使用
...
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
if( MtoUsema.xMSet != NULL ){
xSemaphoreTake( MtoUsema.xMSet, portMAX_DELAY );
{
MtoUsema.len=event->data_len%300+1;
snprintf( MtoUsema.buf, MtoUsema.len,"%s",event->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);
}
}
mqtt事件响应
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->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->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->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
if( MtoUsema.xMSet != NULL ){
xSemaphoreTake( MtoUsema.xMSet, portMAX_DELAY );
{
MtoUsema.len=event->data_len%300+1;
snprintf( MtoUsema.buf, MtoUsema.len,"%s",event->data);
MtoUsema.flag =1;
}
xSemaphoreGive( MtoUsema.xMSet ); /* 互斥量必须归还! */
}
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
}
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
}
三、实验结果如下:
Mqtt到uart
Uart到mqtt
谢谢。