打印
[RISC-V MCU 创新应用比赛]

CH32V103驱动ESP8266连接阿里云物联网平台

[复制链接]
13533|70
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创#
这次要做的项目就是要通过CH32V103驱动ESP8266芯片,通过MQTT协议连接阿里云的物联网平台,并把温湿度数据和火警信息传递到阿里云的物联网平台。
此次用到的硬件CH32V103 ESP8266模块 DHT11芯片 火焰传感器。
怎么读取ESP8266和火焰传感器就见上一个贴子https://bbs.21ic.com/icview-3156850-1-1.html
购买一个esp8266模块首先是需要对ESP8266的AT固件进行升级,使用的工具为flash_download_tool_v3.8.5

这个文件太大了,不能上传过来,给一个链接把。https://www.espressif.com/zh-han ... d_type_tid%5B%5D=14
使用的固件版本是Ai-Thinker_ESP8266_DOUT_8Mbit_v1.5.4.1-a_20171130。这个在官网也有下载的。
这个可以放在这里 Ai-Thinker_ESP8266_DOUT_8Mbit_v1.5.4.1-a_20171130.rar (291.3 KB)
程序下载的配置方式为


硬件第一步的问题解决了。下载开始在阿里云物联网平台搭建一个设备平台。
1 搭建阿里云物联网平台
注册好了阿里云以后,就是怎么搭建环境了。

进入物联网平台以后,首先需要创建产品。如上图所示

输入产品名称以后,选择自定义类型,这个不是必须的,点击确认。

点击查看设备,需要对设备的功能自定义进行配置。

找到功能自定义一栏,编辑草稿。需要添加自己定义的功能。


点击自定义功能,弹出下面的菜单。


对照下图添加功能名称和标识符,这个标识符是唯一的,不能重复。


然后发布就可以了,这个就完成了功能设计的最要的一些步骤了。



点击添加设备,弹出如下的菜单。需要选择产品,并输入设备名称,这个只能为英文。


添加设备成功以后,点击查看设备,进入需要用的三元素



这个就是连接阿里云物联网平台的三元素。后面需要用到的。若使用一机一密认证方式,设备上需要烧写product_key、device_name和device_secret

当设备平台搭建好以后,需要在iot studio 搭建显示界面。


点击新建web应用,并输入下面的设备名称。如果没有绑定设备,需要在iot studio里面绑定之前建好的产品和设备。

这些内容随便输入了。


点击编辑,进入编辑界面,对相关的界面进行配置。


从右侧控件栏中,添加仪表 和指示灯 曲线图等三个空间。


选中空间,在右侧属性一栏对相关数据进行配置。


这里仅仅展示一个温度显示的控件和数据的绑定过程。


搭建好后,点击预览就可在网页端查看相关的数据了。
2、搭建硬件平台。
外设和硬件对应的IO。
ESP8266:串口2
TX-----------PA3
RX------------PA2

火焰传感器:
IO----------PA1

DHT11:
IO----------PB10
至于MQTT是怎么通信的这里就不再赘述了,还是去百度一下吧。当然了不懂里面的规则也是无所谓的。流程都是一样的。
初始化ESP8266
首先需要配置ESP8266为AP模式,连接上家里的路由器,才能与外部网络进行通信。 ssid,  pswd分别为路由器的名称和密码。后面才能开始进行阿里云的连接通信了,使用的TCP的通信模式。
uint8_t ESP8266_ConnectAP(char* ssid,char* pswd)
{
    uint8_t cnt=5;
    while(cnt--)
    {
        memset(usart2_rxbuf,0,sizeof(usart2_rxbuf));
        ESP8266_ATSendString("AT+CWMODE_CUR=1\r\n");              //设置为STATION模式
        if(FindStr((char*)usart2_rxbuf,"OK",200) != 0)
        {
            break;
        }
    }
    if(cnt == 0)
        return 0;

    cnt=2;
    while(cnt--)
    {
        memset(usart2_txbuf,0,sizeof(usart2_txbuf));//清空发送缓冲
        memset(usart2_rxbuf,0,sizeof(usart2_rxbuf));//清空接收缓冲
        sprintf((char*)usart2_txbuf,"AT+CWJAP_CUR=\"%s\",\"%s\"\r\n",ssid,pswd);//连接目标AP
        ESP8266_ATSendString((char*)usart2_txbuf);
        if(FindStr((char*)usart2_rxbuf,"OK",8000)!=0)                      //连接成功且分配到IP
        {
            return 1;
        }
    }
    return 0;
}


MQTT通信阿里云需要明确是阿里云的三元素,就是加密的部分。
char ClientID[128]; 
char Username[128];  
char Passward[128];     
密码就是用户名和产品,加上DeviceSecret的组合。
接入域名为 ${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com,端口固定为1883

ClientId由客户端ID(clientId)、安全模式(securemode)、签名算法类型(signmethod)和时间戳(timestamp)拼接而成。
例如${YourProductKey}|securemode=3,signmethod=hmacmd5|
来看个列表

在这里进行http://encode.chahuo.com/加密的过程。

获得的ID 用户名称和密码都填写到 ClientID  Username  Passward三个里面
使用的ESP8266的AT进行TCP的连接
ESP8266_ConnectServer("TCP",ServerIP,1883)

具体AT的操作代码如下所示,使用的透传方式,就是需要在发送send指令了。
uint8_t ESP8266_ConnectServer(char* mode,char* ip,uint16_t port)
{
    uint8_t cnt;

    ESP8266_ExitUnvarnishedTrans();                   //多次连接需退出透传
    Delay_Ms(500);

    //连接服务器
    cnt=2;
    while(cnt--)
    {
        memset(usart2_txbuf,0,sizeof(usart2_txbuf));//清空发送缓冲
        memset(usart2_rxbuf,0,sizeof(usart2_rxbuf));//清空接收缓冲
        sprintf((char*)usart2_txbuf,"AT+CIPSTART=\"%s\",\"%s\",%d\r\n",mode,ip,port);
        ESP8266_ATSendString((char*)usart2_txbuf);
        if(FindStr((char*)usart2_rxbuf,"CONNECT",8000) !=0 )
        {
                                        printf("%s",(char*)usart2_rxbuf);
            break;
        }
    }
    if(cnt == 0)
        return 0;
    //设置透传模式
    if(ESP8266_OpenTransmission()==0) return 0;
    //开启发送状态
    cnt=2;
    while(cnt--)
    {
        memset(usart2_rxbuf,0,sizeof(usart2_rxbuf)); //清空接收缓冲
        ESP8266_ATSendString("AT+CIPSEND\r\n");//开始处于透传发送状态
        if(FindStr((char*)usart2_rxbuf,">",200)!=0)
        {
            return 1;
        }
    }
    return 0;
}


TCP通信以后,需要进行MQTT通信录。
MQTT_Connect(ClientID, Username, Passward)


MQTT的连接代码
//MQTT连接服务器的打包函数
uint8_t MQTT_Connect(char *ClientID,char *Username,char *Password)
{
        //char temp[200];
        int ClientIDLen = strlen(ClientID);
        int UsernameLen = strlen(Username);
        int PasswordLen = strlen(Password);
        int DataLen;
        MQTT_TxLen=0;
        //可变报头+Payload  每个字段包含两个字节的长度标识
  DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);
        //固定报头
        //控制报文类型
  usart2_txbuf[MQTT_TxLen++] = 0x10;                //MQTT Message Type CONNECT
        //剩余长度(不包括固定头部)
        do{
                uint8_t encodedByte = DataLen % 128;
                DataLen = DataLen / 128;
                // if there are more data to encode, set the top bit of this byte
                if ( DataLen > 0 )
                        encodedByte = encodedByte | 128;
                usart2_txbuf[MQTT_TxLen++] = encodedByte;
        }while ( DataLen > 0 );
        //可变报头
        //协议名
        usart2_txbuf[MQTT_TxLen++] = 0;                        // Protocol Name Length MSB
        usart2_txbuf[MQTT_TxLen++] = 4;                        // Protocol Name Length LSB
        usart2_txbuf[MQTT_TxLen++] = 'M';                // ASCII Code for M
        usart2_txbuf[MQTT_TxLen++] = 'Q';                // ASCII Code for Q
        usart2_txbuf[MQTT_TxLen++] = 'T';                // ASCII Code for T
        usart2_txbuf[MQTT_TxLen++] = 'T';                // ASCII Code for T
        //协议级别
        usart2_txbuf[MQTT_TxLen++] = 4;                        // MQTT Protocol version = 4
        //连接标志
        usart2_txbuf[MQTT_TxLen++] = 0xc2;                // conn flags
        usart2_txbuf[MQTT_TxLen++] = 0;                        // Keep-alive Time Length MSB
        usart2_txbuf[MQTT_TxLen++] = 60;                // Keep-alive Time Length LSB  60S心跳包
        usart2_txbuf[MQTT_TxLen++] = BYTE1(ClientIDLen);// Client ID length MSB
        usart2_txbuf[MQTT_TxLen++] = BYTE0(ClientIDLen);// Client ID length LSB
        memcpy(&usart2_txbuf[MQTT_TxLen],ClientID,ClientIDLen);
        MQTT_TxLen += ClientIDLen;
        if(UsernameLen > 0)
        {   
                usart2_txbuf[MQTT_TxLen++] = BYTE1(UsernameLen);                //username length MSB
                usart2_txbuf[MQTT_TxLen++] = BYTE0(UsernameLen);            //username length LSB
                memcpy(&usart2_txbuf[MQTT_TxLen],Username,UsernameLen);
                MQTT_TxLen += UsernameLen;
        }
        if(PasswordLen > 0){   
                usart2_txbuf[MQTT_TxLen++] = BYTE1(PasswordLen);                //password length MSB
                usart2_txbuf[MQTT_TxLen++] = BYTE0(PasswordLen);            //password length LSB
                memcpy(&usart2_txbuf[MQTT_TxLen],Password,PasswordLen);
                MQTT_TxLen += PasswordLen;
        }
        uint8_t cnt=2;
        uint8_t wait;
        while(cnt--){
                memset(usart2_rxbuf,0,sizeof(usart2_rxbuf));
                MQTT_SendBuf(usart2_txbuf,MQTT_TxLen);
                wait=30;//等待3s时间
                while(wait--){
                        //CONNECT
                        if(usart2_rxbuf[0]==parket_connetAck[0] && usart2_rxbuf[1]==parket_connetAck[1]) //连接成功
建立连接以后,就是需要发布话题了。发布话题的代码如下所示:
uint8_t MQTT_PublishData(char *topic, char *message, uint8_t qos)
{  
        int topicLength = strlen(topic);   
        int messageLength = strlen(message);     
        static uint16_t id=0;
        int DataLen;
        MQTT_TxLen=0;
        //有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度
        //QOS为0时没有标识符
        //数据长度             主题名   报文标识符   有效载荷
        if(qos)        DataLen = (2+topicLength) + 2 + messageLength;      
        else        DataLen = (2+topicLength) + messageLength;   

    //固定报头
        //控制报文类型
        usart2_txbuf[MQTT_TxLen++] = 0x30;    // MQTT Message Type PUBLISH

        //剩余长度
        do
        {
                uint8_t encodedByte = DataLen % 128;
                DataLen = DataLen / 128;
                // if there are more data to encode, set the top bit of this byte
                if ( DataLen > 0 )
                        encodedByte = encodedByte | 128;
                usart2_txbuf[MQTT_TxLen++] = encodedByte;
        }while ( DataLen > 0 );       
       
        usart2_txbuf[MQTT_TxLen++] = BYTE1(topicLength);//主题长度MSB
        usart2_txbuf[MQTT_TxLen++] = BYTE0(topicLength);//主题长度LSB
        memcpy(&usart2_txbuf[MQTT_TxLen],topic,topicLength);//拷贝主题
        MQTT_TxLen += topicLength;
        
        //报文标识符
        if(qos)
        {
                        usart2_txbuf[MQTT_TxLen++] = BYTE1(id);
                        usart2_txbuf[MQTT_TxLen++] = BYTE0(id);
                        id++;
        }
        memcpy(&usart2_txbuf[MQTT_TxLen],message,messageLength);
  MQTT_TxLen += messageLength;
        
        MQTT_SendBuf(usart2_txbuf,MQTT_TxLen);
  return MQTT_TxLen;
}
这个就是整个的操作过程。
最后需要在代码里面进行发布的操作。使用一个sprintf函数,把所有的代码转换到字符串中,然后发送出去。
            sprintf(s_temp,"{\"id\":1,\"params\":{\"CurrentTemperature\":%d,\"CurrentHumidity\":%d,\"warning\":%d},\"version\":\"1.0\",\"method\":\"thing.event.property.post\"}",
                    temperature,humidity,cnt>0?1:0);
            MQTT_PublishData(P_TOPIC_NAME, s_temp, 0);// 发送数据到服务器



最终的显示效果如图所示。


最后附上源代码

游客,如果您要查看本帖隐藏内容请回复


使用特权

评论回复

相关帖子

沙发
xdqfc| | 2021-8-23 11:01 | 只看该作者
请问阿里云平台是免费接入,还是需要每年每个终端都要付费啊?、

使用特权

评论回复
板凳
gaochy1126|  楼主 | 2021-8-23 14:39 | 只看该作者
xdqfc 发表于 2021-8-23 11:01
请问阿里云平台是免费接入,还是需要每年每个终端都要付费啊?、

现在来看是一定数量是免费的,一般没有问题。把发送时间间隔调的长一点。   

使用特权

评论回复
地板
wangcf20006| | 2021-8-24 10:30 | 只看该作者
讲的不错,比较详细!!!!!!!!!!!!!

使用特权

评论回复
5
uiint| | 2021-9-2 20:28 | 只看该作者
有onenet的驱动代码吗?         

使用特权

评论回复
6
hellosdc| | 2021-9-2 20:30 | 只看该作者
ESP8266怎么下载固件?   

使用特权

评论回复
7
mituzu| | 2021-9-2 20:30 | 只看该作者
这个比较牛,物联网通信。   

使用特权

评论回复
8
suzhanhua| | 2021-9-2 20:31 | 只看该作者
esp8266如何怎样连接公网外网设置

使用特权

评论回复
9
xietingfeng| | 2021-9-2 20:31 | 只看该作者
可以不通过云服务器连接互联网吗?

使用特权

评论回复
10
isseed| | 2021-9-2 20:32 | 只看该作者
怎么接入物联网云服务平台

使用特权

评论回复
11
wangdezhi| | 2021-9-2 20:32 | 只看该作者

如何单片机通过wifi模块ESP8266连接外网web网页

使用特权

评论回复
12
biechedan| | 2021-9-2 20:33 | 只看该作者
esp8266怎么连接到wifi  

使用特权

评论回复
13
chenci2013| | 2021-9-2 20:33 | 只看该作者
有阿里云的AT固件吗   

使用特权

评论回复
14
gygp| | 2021-9-2 20:33 | 只看该作者
esp8266怎么将数据传给云平台

使用特权

评论回复
15
xietingfeng| | 2021-9-2 20:34 | 只看该作者
esp8266 想要通过mqtt协议连接华为云

使用特权

评论回复
16
suzhanhua| | 2021-9-2 20:34 | 只看该作者
作为客户端去tcp连接一个服务器?   

使用特权

评论回复
17
uiint| | 2021-9-2 20:34 | 只看该作者
onenet的http的上传方式。        

使用特权

评论回复
18
isseed| | 2021-9-2 20:34 | 只看该作者
如何固定接收数据的端口  

使用特权

评论回复
19
mituzu| | 2021-9-2 20:34 | 只看该作者
传输数据的最大速度是多少呢   

使用特权

评论回复
20
chenci2013| | 2021-9-2 20:34 | 只看该作者
ESP8266如何实现与服务器的TCP通讯

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1051

主题

11300

帖子

26

粉丝