与8266通讯,连接中国移动OneNet(程序移植)
OneNet开发板使用的是8266的wifi模块进行网络通讯的。而8266模块使用的是串口方式进行AT指令的设置与通讯的,所以这里只要移植好串口的低层通讯,其他的使用源有的通讯程序与协议就可以了。
转接板上连接的是串口5.
官方提供的是STM32的开发例程,这要移植起来也很方便。为了更快的移植,一些函数名与变量名保留为原名,没有再更改。也就是你看到的uart2并不是使用串口2进行的,还要看文件描述符fd。 其中EDP的协议文件基本上是不需要更改的,只要添加到Makefile中就可以了。
主要更改的是esp8266.c与esp8266.h两个文件。其中esp8266.h产要更改APIID与设备ID与wifi参数。如下图中。
DEVICEID与设备有关的,在上篇中已经提到。APIKEY是与产品有关的,在产品概要界面可以查到。CWJAP是wifi的名字与密码。CIPSTART是OneNet的服务器IP地址与端口号。只有前三项要更改,其他的可以不更改。 对于esp8266.c的修改就比较多了,与硬件有关。8266模块需要一个复位引脚与串口。复位引脚在转接板上连接的是通过修改设备树dts文件,将这个引脚设备为GPIO功能。 ESP8266初始化函数。
- void ESP8266_Init(int fd)
- {
- ESP8266_Rst();
-
- printf("%s\r\n","[ESP8266_Init]ENTER AT.");
- SendCmd(AT,"OK",1000,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT AT.");
-
- printf("%s\r\n","[ESP8266_Init]ENTER CWMODE.");
- SendCmd(CWMODE,"OK",1000,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT CWMODE.");
-
- printf("%s\r\n","[ESP8266_Init]ENTER RST.");
- SendCmd(RST,"OK",2000,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT RST.");
-
- printf("%s\r\n","[ESP8266_Init]ENTER CIFSR.");
- SendCmd(CIFSR,"OK",1000,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT CIFSR.");
-
- printf("%s\r\n","[ESP8266_Init]ENTER CWJAP.");
- SendCmd(CWJAP,"OK",2200,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT CWJAP.");
- printf("%s\r\n","[ESP8266_Init]ENTER CIPSTART.");
- SendCmd(CIPSTART,"OK",3000,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT CIPSART.");
-
- printf("%s\r\n","[ESP8266_Init]ENTER CIPMODE.");
- SendCmd(CIPMODE,"OK",1000,fd);
- printf("%s\r\n","[ESP8266_Init]EXIT CIPMODE.");
- }
其中SendCmd函数源码,也是通过串口发送数据,再检查出到的数据状态是否是“OK”
- void SendCmd(char* cmd, char* result, int timeOut,int fd)
- {
- while(1)
- {
- memset(usart2_rcv_buf,0,sizeof(usart2_rcv_buf));
- usart2_rcv_len=0;
- usart2_write((unsigned char *)cmd, strlen((const char *)cmd),fd);
- mdelay(timeOut);
- read(fd, usart2_rcv_buf, 0x02);
- if((NULL != strstr((const char *)usart2_rcv_buf, result))) //判断结果
- {
- break;
- }
- else
- {
- mdelay(100);
- }
- }
- }
usart2_write函数更改为linux下的串口发送函数,这里使用write函数进行发送。
- void usart2_write(char *Data,unsigned int len,int fd)
- {
- write(fd, Data, len);
- }
与OneNet建立连接函数。
- void ESP8266_DevLink(const char* devid, const char* auth_key, int timeOut,int fd)
- {
- int count=0;
-
- memset(usart2_rcv_buf,0,strlen((const char *)usart2_rcv_buf));
- usart2_rcv_len=0;
-
- printf("%s\r\n","[ESP8266_DevLink]ENTER device link...");
- usart2_write(CIPSEND,strlen(CIPSEND),fd); //向ESP8266发送数据透传指令
- for(count=0;count ")))
- {
- break;
- }
- }
- send_pkg = PacketConnect1(devid,auth_key);
- mdelay(200);
- usart2_write(send_pkg->_data,send_pkg->_write_pos,fd); //发送设备连接请求数据
- mdelay(500);
- DeleteBuffer(&send_pkg);
- mdelay(200);
- usart2_write("+++",3,fd); //向ESP8266发送+++结束透传,ESP8266返回指令模式
- mdelay(50);
- printf("%s\r\n","[ESP8266_DevLink]EXIT device link...");
- }
如下函数生成发送数据,可以看到其中的use_status与Electricity都是我们在OneNet中建的数据流的名称。
- void GetSendBuf(void)
- {
- char text[25] = {0};
-
- Check_Data();
- memset(send_buf,0,MAX_SEND_BUF_LEN);
-
- strcat(send_buf, ",;");
- strcat(send_buf, "use_status,");
- sprintf(text,"%d",use_status);
- strcat(send_buf, text);
- strcat(send_buf, ";");
-
- strcat(send_buf, "Electricity,");
- sprintf(text,"%d",electricity);
- strcat(send_buf, text);
- strcat(send_buf, ";");
-
- }
数据发送。
- void ESP8266_SendDat(int fd)
- {
- int count=0;
- memset(usart2_rcv_buf,0,sizeof(usart2_rcv_buf));
- usart2_rcv_len=0;
- printf("%s\r\n","[ESP8266_SendDat]ENTER Senddata...");
- usart2_write(CIPSEND,strlen(CIPSEND),fd); //向ESP8266发送数据透传指令
- for(count=0;count ")))
- {
- break;
- }
- }
-
- GetSendBuf();
- send_pkg = PacketSavedataSimpleString(DEVICEID,send_buf);
- usart2_write(send_pkg->_data,send_pkg->_write_pos,fd); //向平台上传数据点
- DeleteBuffer(&send_pkg);
- mdelay(500);
- usart2_write("+++",3,fd); //向ESP8266发送+++结束透传,使ESP8266返回指令模式
- mdelay(200);
- printf("%s\r\n","[ESP8266_SendDat]EXIT Senddata...");
- }
主要的功能函数就是上面的几个,其他的函数都是比较简单的,这里不再赘述,可以参考OneNet的例程进行更改。
基本功能已经可以实现了。
例如,下面是设备的使用状态在OneNet上的显示。刷卡后为使用中,再刷卡为未使用。使用中为1,未使用为0。
大神能教教我吗
我想通过esp8266把单片机的数据传到onenet上 该怎么弄啊