【X806开发板试用】串口数据透传阿里云IOT

news/2024/11/28 11:33:58/

上成果

在这里插入图片描述

阿里云对接需要用的是PRODUCTKEY,DEVICENAME和DEVICESECRET,开始直接用MQTT的例子硬怼,没成功,后面看了文档,发现阿里云对接的client_id,username和password是通过三要素生成的。
在这里插入图片描述

找了一下代码,发现再device/xradio/xr806/xr_skylark/src/net/cloud/aliyun下面有阿里云的东西,遂打开看了一下,刚好有加密过程。就直接拿过来用了,不过这里出现了一点小插曲,一直引用不到里面的接口。折腾了半天不行,一怒之下,给复制出来了。

代码

创建app站内有很多文章就不再赘述,创建好以后代码结构如下:
在这里插入图片描述

其中,inc是把device/xradio/xr806/xr_skylark/include/net/cloud/aliyun下面的inc复制出来的;
src下面的aliyun,是直接把
device/xradio/xr806/xr_skylark/src/net/cloud/aliyun
复制出来的;

wifi,mqtt,uart的都有例子,就拿过来,改一改。大体流程是
先初始化wifi,连接wifi成功获取到网络权限以后,初始化mqtt的task,待mqtt的task连接到阿里云iot以后,初始化uart task,初始化OK以后开始轮询接收uart1数据,并透传给阿里云。

不BB了,直接上代码:
ohosdemo下的BUILD.gn

group("ohosdemo") {deps = [#"hello_demo:app_hello","mqtt2uart_demo:app_uart2mqtt",]
}

mqtt2uart_demo下的BUILD.gn


import("//device/xradio/xr806/liteos_m/config.gni")static_library("app_uart2mqtt") {configs = []sources = ["src/main.c","src/aliyun/alink_auth.c","src/aliyun/alink_ca.c","src/aliyun/alink_cjson_get.c","src/aliyun/alink_mqtt_client.c","src/aliyun/alink_utils.c",]cflags = board_cflagsinclude_dirs = board_include_dirsinclude_dirs += ["inc","//kernel/liteos_m/kernel/arch/include","//base/iot_hardware/peripheral/interfaces/kits",".","//utils/native/lite/include","//foundation/communication/wifi_lite/interfaces/wifiservice","//device/xradio/xr806/xr_skylark/project"]
}

main.c

#include <string.h>
#include "ohos_init.h"
#include "kernel/os/os.h"#include "iot_gpio.h"
#include "wifi_device.h"
#include "common/framework/net_ctrl.h"
#include "mqtt_client.h"
#include "driver/chip/hal_uart.h"#include "iot_uart.h"
static OS_Thread_t g_main_thread;
static OS_Thread_t g_mqtt_thread;
static OS_Thread_t g_uart_thread;#define WIFI_DEVICE_CONNECT_AP_SSID "XXXXX"//这里填你家路由器的SSID
#define WIFI_DEVICE_CONNECT_AP_PSK "XXXXX"//这里填你家路由器的PWD#define MQTT_CLIENT_ID "2022666"
#define MQTT_HOST_NAME "iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define MQTT_PORT      "1883"
#define MQTT_PRODUCTKEY  "a1oz5VdCSZk"
#define MQTT_DEVICENAME  "DHTER000S"
#define MQTT_DEVICESECRET  "8368b89e723216bccb471434969391e5"
#define MQTT_SECUREMODE "2"#define MQTT_RECV_TOPIC MQTT_PRODUCTKEY"/"MQTT_DEVICENAME"/user/get" //下发TOPIC
#define MQTT_UPDATE_TOPIC MQTT_PRODUCTKEY"/"MQTT_DEVICENAME"/user/update"//上报TOPIC#define MQTT_BUF_SIZE (2*1024)static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer;
static Client mqtt_demo_client;
static Network mqtt_demo_network;#define UART_BUFFER_MAXSIZE 100static int mqtt_demo_publish(char *topic, char *msg) ;static int mqtt_demo_init(void) {char *send_buf;char *recv_buf;mqtt_para_init();aliot_device_info(MQTT_PRODUCTKEY,MQTT_DEVICENAME,MQTT_DEVICESECRET,MQTT_CLIENT_ID,MQTT_SECUREMODE);printf("str_clientID = %s\n", xr_devc_info.client_id);printf("str_user_name = %s\n", xr_devc_info.user_name);printf("sha1_pwd = %s\n", xr_devc_info.password);mqtt_demo_connectData.clientID.cstring = xr_devc_info.client_id;mqtt_demo_connectData.keepAliveInterval = 30; // 30smqtt_demo_connectData.cleansession = 0;mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1send_buf = malloc(MQTT_BUF_SIZE);if (send_buf == NULL) {printf("no memory\n");return -1;}recv_buf = malloc(MQTT_BUF_SIZE);if (recv_buf == NULL) {free(send_buf);printf("no memory\n");return -1;}/* init network */NewNetwork(&mqtt_demo_network);/* init mqtt client object */MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000,(unsigned char *)send_buf, MQTT_BUF_SIZE,(unsigned char *)recv_buf, MQTT_BUF_SIZE);/* set username and password */mqtt_demo_connectData.username.cstring = xr_devc_info.user_name;mqtt_demo_connectData.password.cstring = xr_devc_info.password;return 0;
}static int mqtt_demo_connect(char *host_name, char *host_port) {int ret = -1;ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port));if (ret != 0) {printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port);goto exit;}ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData);if (ret != 0) {printf("mqtt connect faild, ret:%d\n", ret);mqtt_demo_network.disconnect(&mqtt_demo_network);goto exit;}printf("mqtt connected\n");
exit:return ret;
}static void mqtt_demo_msg_cb(MessageData *data) {printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len,data->topicName->lenstring.data, data->message->payloadlen,(char *)data->message->payload);
}static int mqtt_demo_subscribe(char *topic) {int ret = -1;if (mqtt_demo_client.isconnected) {ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb);if (ret != 0)printf("mqtt subscribe faild ret:%d\n", ret);}return ret;
}static int mqtt_demo_unsubscribe(char *topic) {int ret = -1;if (mqtt_demo_client.isconnected) {ret = MQTTUnsubscribe(&mqtt_demo_client, topic);if (ret != 0)printf("mqtt unsubscribe faild, ret:%d\n", ret);}return ret;
}static int mqtt_demo_publish(char *topic, char *msg) {int ret = -1;MQTTMessage message;memset(&message, 0, sizeof(message));message.qos = 0;message.retained = 0; /* disable retain the message in server */message.payload = msg;message.payloadlen = strlen(msg);ret = MQTTPublish(&mqtt_demo_client, topic, &message);if (ret != 0)printf("mqtt publish faild, ret:%d\n", ret);return ret;
}static int mqtt_demo_disconnect(void) {int ret = -1;if (mqtt_demo_client.isconnected) {ret = MQTTDisconnect(&mqtt_demo_client);if (ret != 0)printf("mqtt disconnect fail, ret:%d\n", ret);mqtt_demo_network.disconnect(&mqtt_demo_network);}return ret;
}static void mqtt_demo_deinit(void) {if (mqtt_demo_client.buf) {free(mqtt_demo_client.buf);mqtt_demo_client.buf = NULL;}if (mqtt_demo_client.readbuf) {free(mqtt_demo_client.readbuf);mqtt_demo_client.readbuf = NULL;}
}static void uart_task(void *arg)
{int ret;unsigned int uart_id = 1;unsigned int uart_len;unsigned char uart_rx_buffer[UART_BUFFER_MAXSIZE];unsigned char uart_tx_buffer[UART_BUFFER_MAXSIZE];static IotUartAttribute uart_param = { 115200,IOT_UART_DATA_BIT_8,IOT_UART_STOP_BIT_1,IOT_UART_PARITY_NONE,0,0,0 };printf("uart%d test start\r\n", uart_id);IoTUartInit(uart_id, &uart_param);IoTUartWrite(uart_id, "uart1 init OK\r\n", 15);while (1) {memset((char *)uart_rx_buffer, 0, UART_BUFFER_MAXSIZE);ret = IoTUartRead(uart_id, uart_rx_buffer, UART_BUFFER_MAXSIZE);if (ret > 0) {printf("recv len=%d, data:%s\r\n", ret, uart_rx_buffer);if(0 == mqtt_demo_publish(MQTT_UPDATE_TOPIC, uart_rx_buffer)){memset(uart_tx_buffer, 0, UART_BUFFER_MAXSIZE);uart_len = snprintf((char *)uart_tx_buffer,UART_BUFFER_MAXSIZE,"uart%d send data:[%s] OK\r\n", uart_id, uart_rx_buffer);IoTUartWrite(uart_id, uart_tx_buffer, uart_len);}else{printf("Publish data failed!!\n");}}OS_MSleep(100); //100ms}exit:IoTUartDeinit(uart_id);OS_ThreadDelete(&g_uart_thread);printf("uart%d test end\r\n", uart_id);
}static void mqtt_task(void *arg)   {int ret;int reconnect_times = 0;mqtt_demo_init();ret = mqtt_demo_connect(MQTT_HOST_NAME, MQTT_PORT);if (ret != 0)goto exit;ret = mqtt_demo_subscribe(MQTT_RECV_TOPIC);if (ret != 0)goto exit;mqtt_demo_publish(MQTT_UPDATE_TOPIC, "mqtt init OK");if (!OS_ThreadIsValid(&g_uart_thread)) {OS_ThreadCreate(&g_uart_thread, "uart_task",uart_task, (void *)NULL,  OS_THREAD_PRIO_APP, (8 * 1024));}while (1) {ret = MQTTYield(&mqtt_demo_client, 500);if (ret != 0) {printf("mqtt yield err, ret:%d\n", ret);
reconnect:printf("mqtt reconnect\n");mqtt_demo_disconnect();ret = mqtt_demo_connect(MQTT_HOST_NAME, MQTT_PORT);if (ret != 0) {reconnect_times++;if (reconnect_times > 5)goto exit;OS_MSleep(5000); //5sgoto reconnect;}}}exit:printf("mqtt disconnect\n");mqtt_demo_unsubscribe(MQTT_RECV_TOPIC);mqtt_demo_disconnect();mqtt_demo_deinit();OS_ThreadDelete(&g_mqtt_thread);
}static void net_cb(uint32_t event, uint32_t data, void *arg) {uint16_t type = EVENT_SUBTYPE(event);switch (type) {case NET_CTRL_MSG_NETWORK_UP:printf("NET_CTRL_MSG_NETWORK_UP\n");if (!OS_ThreadIsValid(&g_mqtt_thread)) {OS_ThreadCreate(&g_mqtt_thread, "connect_to_server_task",mqtt_task, (void *)NULL,  OS_THREAD_PRIO_APP, (8 * 1024));}break;case NET_CTRL_MSG_NETWORK_DOWN:break;default:break;}
}static void MainThread(void *arg)   {printf("MainThread start\r\n");if (WIFI_SUCCESS != EnableWifi()) {printf("Error: EnableWifi fail\n");return;}OS_Sleep(1);if (WIFI_SUCCESS != Scan()) {printf("Error: Scan fail.\n");return;}OS_Sleep(3);//这里为了方便用延时,实际用回调更好,否则3秒可能不够const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID;const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK;WifiScanInfo scan_results[30];unsigned int scan_num = 30;if (WIFI_SUCCESS != GetScanInfoList(scan_results, &scan_num)) {printf("Error: GetScanInfoList fail.\n");return;}WifiDeviceConfig config = { 0 };int netId = 0;int i;for (i = 0; i < scan_num; i++) {printf("ssid: %s    ", scan_results[i].ssid);printf("securityType: %d\n", scan_results[i].securityType);if (0 == strcmp(scan_results[i].ssid, ssid_want_connect)) {memcpy(config.ssid, scan_results[i].ssid,WIFI_MAX_SSID_LEN);memcpy(config.bssid, scan_results[i].bssid,WIFI_MAC_LEN);strcpy(config.preSharedKey, psk);config.securityType = scan_results[i].securityType;config.wapiPskType = WIFI_PSK_TYPE_ASCII;config.freq = scan_results[i].frequency;break;}}if (i >= scan_num) {printf("Error: No found ssid in scan_results\n");return;}if (WIFI_SUCCESS != AddDeviceConfig(&config, &netId)) {printf("Error: AddDeviceConfig Fail\n");return;}printf("Config Success\n");if (WIFI_SUCCESS != ConnectTo(netId)) {printf("Error: ConnectTo Fail\n");return;}observer_base *net_ob;net_ob = sys_callback_observer_create(CTRL_MSG_TYPE_NETWORK, NET_CTRL_MSG_ALL, net_cb, NULL);if (net_ob == NULL)return;if (sys_ctrl_attach(net_ob) != 0)return;while (1) {OS_MSleep(500);}
}void UART2MQTTMain(void) {if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {printf("[ERR] Create MainThread Failed\n");}
}
SYS_RUN(UART2MQTTMain);

遇到的问题

1.aliyun的lib引用不到
偷懒,直接复制出来的;
2.mqtt yield err, ret:-1
抓包发现,有时候发的keepalive包没有得到响应,怀疑是本地网络不好,后来连上家里的wifi就没问题了。
做了一个简单的修改,发包一次不响应过会再发一次。三次收不到才认为是短线,才发起reconnect。
文件:MQTTClient.c
函数:int keepalive(Client* c)

修改如下:

if (expired(&c->last_sent) || expired(&c->last_received)){if (c->ping_outstanding){MQTT_WARN("PINGRESP not received in keepalive interval %d.\n",c->ping_outstanding);if(c->ping_outstanding <= 3){Timer timer;InitTimer(&timer);countdown_ms(&timer, 1000);int len = MQTTSerialize_pingreq(c->buf, c->buf_size);if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packetc->ping_outstanding++;}else{rc = FAILURE; /* PINGRESP not received in keepalive interval */}}else{Timer timer;InitTimer(&timer);countdown_ms(&timer, 1000);int len = MQTTSerialize_pingreq(c->buf, c->buf_size);if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packetc->ping_outstanding = 1;}}

待优化

  1. 串口透传部分目前是接过来数据就上传,没有加缓冲,数据量大时候,可能会丢数据可以加一下队列;
  2. aliyun部分代码引用最好不要复制,引用原位置代码最好;

http://www.ppmy.cn/news/1360325.html

相关文章

RIFFA架构

用户侧通过Channel和Riffa交联&#xff0c;Channel是被用来处理异步时钟域&#xff0c;其含有FIFO来接收发送数据。 RX引擎用来提取和多路分解收到的PCIe负载数据。TX引擎用来将负载数据格式化为PCIe包&#xff0c;并且提供对PCIe链路的多路复用访问。 pcie链路配置决定了数据…

数据结构-Stack栈

一,栈的简单认识 栈是一种线性数据结构,但是与数组不同的是,只能从栈顶存入元素,或者删除元素.详细的操作下会阐述. (栈是一种后进先出的数据结构) 二,栈的具体实现. Stack<E> 1,void push(E) //栈顶插入元素 2,E pop () //栈顶删除元素,返回值时删除的栈顶元素 3,E …

协议的概念+本质+作用+最终表现形式,网络问题(技术+应用+解决的协议+存在原因),主机的对称性

目录 协议 概念 示例 -- 摩斯密码 本质 作用 网络问题 引入 技术问题 应用问题 主机的对称性 问题对应的协议 问题出现的原因 理解协议(代码层面) 举例 -- 快递单 协议的最终表现形式 协议被双方主机认知的基础 协议 概念 协议是在计算机通信和数据传输中规定通…

个人博客系列-项目部署-nginx(3)

使用Nginx uwsgi进行部署django项目 一. 检查项目是否可以运行 启动项目 python manage.py runserver 0.0.0.0:8099输入ip:8099 查看启动页面 出现上述页面表示运行成功 二. 安装uwsgi并配置 2.1 下载uwsgi pip install uwsgi新建文件test.py写入内容&#xff0c;测试一…

#LLM入门|Prompt#1.8_聊天机器人_Chatbot

聊天机器人设计 以会话形式进行交互&#xff0c;接受一系列消息作为输入&#xff0c;并返回模型生成的消息作为输出。原本设计用于简便多轮对话&#xff0c;但同样适用于单轮任务。 设计思路 个性化特性&#xff1a;通过定制模型的训练数据和参数&#xff0c;使机器人拥有特…

七分钟交友匿名聊天室源码

应用介绍 本文来自&#xff1a;七分钟交友匿名聊天室源码 - 源码1688 简介&#xff1a; 多人在线聊天交友工具&#xff0c;无需注册即可畅所欲言&#xff01;你也可以放心讲述自己的故事&#xff0c;说出自己的秘密&#xff0c;因为谁也不知道对方是谁。 运行说明&#xff…

C# cass10 面积计算

运行环境Visual Studio 2022 c# cad2016 cass10 通过面积计算得到扩展数据&#xff0c;宗地面积 &#xff0c;房屋占地面积&#xff0c;房屋使用面积 一、主要步骤 获取当前AutoCAD应用中的活动文档、数据库和编辑器对象。创建一个选择过滤器&#xff0c;限制用户只能选择&q…

python中多线程使用

前言 记录下Python中多线程使用 标题 前言简介使用demo 简介 Python 中的多线程主要通过 threading 模块来实现。多线程是一种并发编程的方式&#xff0c;允许程序在同一时间执行多个线程&#xff0c;每个线程执行不同的任务。然而需要注意的是&#xff0c;在 Python 中由于 …