当前位置:   article > 正文

Arduno + ESP8266模组运用中移OneNet物联网平台实现远程监控_arduino与esp8266远程控制

arduino与esp8266远程控制

一、初识OneNet

OneNET定位为PaaS服务,即在物联网应用和真实设备之间搭建高效、稳定、安全的应用平台:面向设备,适配多种网络环境和常见传输协议,提供各类硬件终端的快速接入方案和设备管理服务;面向应用层,提供丰富的API和数据分发能力以满足各类行业应用系统的开发需求,使物联网企业可以更加专注于自身应用的开发,而不用将工作重心放在设备接入层的环境搭建上,从而缩短物联网系统的形成周期,降低企业研发、运营和运维成本。

1. 物联网与OneNet

物联网是把生活中各种物品通过各种元器件,传感器等连接在一起的网络。这个网络具备观察性和可控性,我们可以通过这个网络知道其中各个物品的状态,同时可以控制他们。

物联网可以分为三层,感知层、网络层、应用层。其中感知层可以通过传感器,执行器等元器件与环境进行互动。网络层指起到数据存储于管理功能的那一部分,其可以把各种数据按照特定标准进行存储,便于应用层调取。应用层是用户与网络层的接口,一方面把数据以特定形式展现给用户,一方面存储用户的指令,以备感知层调用。

OneNET平台具备网络层和应用层的功能,它可以把Arduino传感器采集的数据存储在自己的服务器上,同时可以在设计应用的时候调用这些数据。

OneNET平台是中国移动开发的物联网平台,稳定性非常好,上手容易。
使用方法:

1)进入OneNET官网(“https://open.iot.10086.cn/”)注册账号

2)注册完成后在首页右上角点击「开发者中心」进入产品开发界面

在这里插入图片描述
小提示:零基础入,建议先别去网络上找找乱七八糟的文章学习,直接参考官方文档一步一步走就没那么多问题了。遇到实际问题后首先根据官方文档以及网上资料去解决。官方文档:【首页】-【服务与支持】- 【开发文档】- 【快速入门】

2. OneNet快速入门

2.1 创建产品

进入产品开发界面后,选择左侧菜单栏中【全部产品】-【基础服务】。基础服务中有:

  • NB-IoT物联网套件
  • MQTT物联网套件(新版)
  • 多协议接入
  • 协议适配

在这里插入图片描述

【多协议接入】-【HTTP】-【添加产品】

在这里插入图片描述
添加产品时,填写产品相关信息
在这里插入图片描述

2.2 创建设备

创建产品后,点击左上角 【OneNet】 回到首页,单击进入产品 【HTTP

在这里插入图片描述

OneNet上在项目下还有设备的概念,一个设备就相当于一块Arduino板。单击【设备列表】-【添加备】,在弹出的设备信息里可以随便填,对后面没有影响,唯一需要注意的是数据保密性这里,建议选择私有,如果选择公开,那后面你把这个项目发布的时候别人就能看的你的数据了。填完后单击添加即可完成创建。

在这里插入图片描述

选择【设备列表】-【添加设备

在这里插入图片描述
添加新设备】 - 设置设备名称、设备编号后,点击确认即可。
在这里插入图片描述
2.3 新建数据流

Arduino发送给OneNET平台的数据可能有很多种,比如温度,湿度,光照强度等等。我们需要在OneNET上建立「变量」来存储这些数据,在OneNET上我们把这种变量叫做“ 数据流 ”。单击【数据流模板】-【添加数据流模板】,填入数据流名称即可得到一个存储数据的数据流。

在这里插入图片描述

2.4 创建应用

有了数据之后,我们需要把数据以一种特定形式呈现出来,比如用一个温度计显示实时温度,以一个折线图显示一段时间的温度趋势。肩负展示数据功能的是“应用”,就像我们平时在手机的“应用商店”里下载的那种应用一样,上面会有图标,图片等等。我们依次单击选择【应用管理】-【添加应用
在这里插入图片描述
设置应用相关信息:名称、logo等。
在这里插入图片描述

添加应用后,进入编辑应用界面如下:

在这里插入图片描述
设置应用界面组件以及组件的属性:

在这里插入图片描述
查看应用有两种方法:

  • 第一种单击【应用管理】-【应用名称】,即可在底部看到应用页面
  • 第二种是下载OneNET的移动端(下载地址:https://open.iot.10086.cn/doc/art656.html ),通过手机或平板查看。


参考资料


二、Arduino + ESP8266 接入 OneNet

1.准备工作

1.1 硬件

  • ESP8266-01S * 1
  • Arduno Uno * 1
  • DHT11 * 1

ESP8266-01SArduno Uno
VCC&EN3.3V
GNDGND
RXTX (D1)
TXRX(D0)

DHT11Arduno Uno
VCC3.3V /5V
GNDGND
OUTD3

在这里插入图片描述

1.2 软件

Arduino 通过 ESP8266-01S 发送数据给 OneNet 平台的数据。ESP8266-01S 属于 安信可公司的产品,我们需要下载官网的安信可串口调试助手 查看返回的数据。

  • 安信可串口调试助手
  • Arduino IDE

1.3 平台

OneNet服务器里有很多项目很多设备,具体把数据发到拿呢?
实际上OneNet平台对于发送过来的Json数据是有一定格式要求的,其中除了要传输的数据,还包含了设备ID密匙,这样就可以保证数据发送到正确的设备。

在正式开始前,我们需要记录设备的ID和密匙。设备ID可通过单击【设备列表】可在设备前面看到设备ID、密匙,在APIKey这一列的就是密匙。

  • 设备ID 597420765
  • 密匙 APIKey vutzlt=cl9B99vnsozQcKSRSkNs= (进入【设备列表】- 【设备详情】路径添加APIKey)

另外,还需要自家的WiFi账号与密码接入网络。

  • WiFi名称
  • WiFi密码

在这里插入图片描述
补充:按照前文的方法对 OneNet平台设置:创建产品(多协议接入 - edp)、创建设备、新建数据流(数据流的名称要与程序中的一致)、添加应用(注意开关控件的属性设置"switch:{V}")
在这里插入图片描述
在这里插入图片描述

2.程序设计

2.1 ESP8266-01S AT指令手动联网

  1. /***************************************************
  2. *
  3. * 名称:ESP8266 01S AT指令手动联网
  4. * 作者:Naiva
  5. * 日期:2020/05/17
  6. * 接线:
  7. * Arduino nano ESP8266 01S
  8. * D2(RX) ——— TX
  9. * D3(TX) ——— RX
  10. * VCC(3.3) ——— VCC(&EN)
  11. * GND ——— GND
  12. *
  13. ****************************************************/
  14. #include<SoftwareSerial.h>
  15. SoftwareSerial mySerial(2,3);//RX ,TX wifiSerial
  16. void setup() {
  17. // put your setup code here, to run once:
  18. Serial.begin(115200);
  19. while (!Serial)
  20. {
  21. ;
  22. }
  23. Serial.println("ok");
  24. mySerial.begin(115200);
  25. mySerial.println("ready");
  26. }
  27. void loop() {
  28. // put your main code here, to run repeatedly:
  29. if(mySerial.available())
  30. Serial.write(mySerial.read());
  31. if(Serial.available())
  32. mySerial.write(Serial.read());
  33. }

2.2 自动联网及接入设备

把AT指令写进程序让程序自动帮我们发送,并且链接到云平台,还要再实现设备和脚本的关联。

  1. while (!doCmdOk("AT+CWMODE=3", "OK")); //工作模式
  2. while (!doCmdOk("AT+CWJAP=\"CMCC-R6Qs\",\"qmt2fx3q\"", "OK"));//WiFi账号与WiFi密码
  3. while (!doCmdOk("AT+CIPSTART=\"TCP\",\"jjfaedp.hedevice.com\",876", "OK"));//链接到云平台,三个参数分别是接入协议,服务器地址和端口号
  4. while (!doCmdOk("AT+CIPMODE=1", "OK")); //透传模式
  5. while (!doCmdOk("AT+CIPSEND", ">")); //开始发送

程序讲解参考一下视频连接,代码见文末附录。
https://www.bilibili.com/video/BV1CE411h7hP?p=4

3.效果展示

安信可串口调试助手
在这里插入图片描述
实验过程中,一开始用的Arduino Nano 开发板,但后来可能因为开发板质量或接线的把板子烧坏了,电脑识别不了设备,于是我换了一块官网的Arduino Uno 正版开发板!
在这里插入图片描述

OneNet 移动终端「设备云」效果界面展示,实现温湿度显示、开关控件控制pin13 板载 LED 的亮灭。
在这里插入图片描述


参考资料


附代码

ESP8266_EDP.ino

  1. /***********************************************************
  2. File name: ESP8266_EDP.ino
  3. Description: ESP8266 realizes remote control via ONENet
  4. Author: Naiva
  5. Date: 2020/05/17
  6. ***********************************************************/
  7. #include "edp.c"
  8. #include "DHT11.h"
  9. DHT11 dht11;
  10. #define DHT11PIN 3 //pin3
  11. #define KEY "24eV33JUKr8dj=XGpckVygdFyJQ=" //APIkey
  12. #define ID "598229651" //设备ID
  13. //#define PUSH_ID "680788"
  14. #define PUSH_ID NULL
  15. String comdata = "";
  16. // 串口
  17. #define _baudrate 115200
  18. #define WIFI_UART Serial
  19. int DHT11 = 0;
  20. const int stbPin = 7; //the segment display module STB pin connected to digital pin 7
  21. const int clkPin = 9; //the segment display module CLK pin connected to digital pin 9
  22. const int dioPin = 8; //the segment display module DIO pin connected to digital pin 8
  23. uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };
  24. edp_pkt *pkt;
  25. /*
  26. * doCmdOk
  27. * 发送命令至模块,从回复中获取期待的关键字
  28. * keyword: 所期待的关键字
  29. * 成功找到关键字返回true,否则返回false
  30. */
  31. bool doCmdOk(String data, char *keyword)
  32. {
  33. bool result = false;
  34. if (data != "") //对于tcp连接命令,直接等待第二次回复
  35. {
  36. WIFI_UART.println(data); //发送AT指令
  37. }
  38. if (data == "AT") //检查模块存在
  39. delay(2000);
  40. else
  41. while (!WIFI_UART.available()); // 等待模块回复
  42. delay(200);
  43. if (WIFI_UART.find(keyword)) //返回值判断
  44. {
  45. result = true;
  46. }
  47. else
  48. {
  49. result = false;
  50. }
  51. while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
  52. delay(500); //指令时间间隔
  53. return result;
  54. }
  55. void sendCommand(uint8_t value)
  56. {
  57. digitalWrite(stbPin, LOW); //pin low. To begin receiving data
  58. shiftOut(dioPin, clkPin, LSBFIRST, value); //send data(value) to the segment display module
  59. digitalWrite(stbPin, HIGH); //pin high. Stop receiving data
  60. }
  61. void setup()
  62. {
  63. char buf[100] = {0};
  64. int tmp;
  65. pinMode(13, OUTPUT); //WIFI模块指示灯
  66. pinMode(8, OUTPUT); //用于连接EDP控制的发光二极管
  67. WIFI_UART.begin( _baudrate );
  68. pinMode(stbPin, OUTPUT); //initialize the stbPin as an output 数码管
  69. pinMode(clkPin, OUTPUT); //initialize the clkPin as an output
  70. pinMode(dioPin, OUTPUT); //initialize the dioPin as an output
  71. sendCommand(0x8f); //activate
  72. WIFI_UART.setTimeout(3000); //设置find超时时间
  73. delay(3000);
  74. Serial.setTimeout(100);
  75. delay(2000);
  76. while (!doCmdOk("AT", "OK"));
  77. digitalWrite(13, HIGH); // 使Led亮
  78. while (!doCmdOk("AT+CWMODE=3", "OK")); //工作模式
  79. while (!doCmdOk("AT+CWJAP=\"CMCC-R6Qs\",\"qmt2fx3q\"", "OK"));//WiFi账号与WiFi密码
  80. while (!doCmdOk("AT+CIPSTART=\"TCP\",\"jjfaedp.hedevice.com\",876", "OK"));
  81. while (!doCmdOk("AT+CIPMODE=1", "OK")); //透传模式
  82. while (!doCmdOk("AT+CIPSEND", ">")); //开始发送
  83. }
  84. int dht_flag = 1;
  85. void loop()
  86. {
  87. static int edp_connect = 0;
  88. bool trigger = false;
  89. edp_pkt rcv_pkt;
  90. unsigned char pkt_type;
  91. int i = 0, tmp;
  92. char num[10];
  93. int wd,sd;
  94. char wd1[20],sd1[20];
  95. /* EDP 连接 */
  96. if (!edp_connect)
  97. {
  98. while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
  99. packetSend(packetConnect(ID, KEY)); //发送EPD连接包
  100. while (!WIFI_UART.available()); //等待EDP连接应答
  101. if ((tmp = WIFI_UART.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0 )
  102. {
  103. rcvDebug(rcv_pkt.data, tmp);
  104. if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00)
  105. {
  106. edp_connect = 1;
  107. digitalWrite(13, LOW); // 使Led灭
  108. }
  109. else
  110. ;
  111. }
  112. packetClear(&rcv_pkt);
  113. }
  114. if(dht_flag == 1)
  115. {
  116. dht_flag = 0;
  117. dht11.read(DHT11PIN);//温湿度
  118. wd = dht11.temperature;
  119. sd = dht11.humidity;
  120. sprintf(wd1,"%d",wd); //int型转换char型
  121. sprintf(sd1,"%d",sd); //int型转换char型
  122. DHT11 = 0;
  123. delay(500);
  124. packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流 WD是上传的地方 wd1是上传的数据
  125. delay(500);
  126. packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流
  127. delay(500);
  128. }
  129. DHT11++;
  130. if(DHT11 > 150&&edp_connect)
  131. {
  132. dht11.read(DHT11PIN);
  133. wd = dht11.temperature;
  134. sd = dht11.humidity;
  135. sprintf(wd1,"%d",wd); //int型转换char型
  136. sprintf(sd1,"%d",sd); //int型转换char型
  137. DHT11 = 0;
  138. delay(500);
  139. packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流
  140. delay(500);
  141. packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流
  142. delay(500);
  143. }
  144. while (WIFI_UART.available())
  145. {
  146. readEdpPkt(&rcv_pkt);
  147. if (isEdpPkt(&rcv_pkt))
  148. {
  149. pkt_type = rcv_pkt.data[0];
  150. switch (pkt_type)
  151. {
  152. case CMDREQ:
  153. char edp_command[50];
  154. char edp_cmd_id[40];
  155. long id_len, cmd_len, rm_len;
  156. char datastr[20];
  157. char val[10];
  158. memset(edp_command, 0, sizeof(edp_command));
  159. memset(edp_cmd_id, 0, sizeof(edp_cmd_id));
  160. edpCommandReqParse(&rcv_pkt, edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len);
  161. //数据处理与应用中EDP命令内容对应
  162. //本例中格式为 datastream:[1/0]
  163. sscanf(edp_command, "%[^:]:%s", datastr, val);
  164. if (atoi(val) == 1)
  165. // 使Led亮
  166. digitalWrite(13, HIGH);
  167. //digitalWrite(8, HIGH);
  168. else
  169. digitalWrite(13, LOW); // 使Led灭
  170. //digitalWrite(8, HIGH);
  171. if(atoi(val) > 1)
  172. {
  173. sendCommand(0x40); //setting the Write Data Command,using automatic address genuine.
  174. digitalWrite(stbPin, LOW); //pin low. To begin receiving data
  175. shiftOut(dioPin, clkPin, LSBFIRST, 0xc0); //Set the start address 0C0H
  176. if(atoi(val) >= 100 && atoi(val) <=1000)
  177. {
  178. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  179. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  180. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/100%10]); //hundred data
  181. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  182. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data
  183. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  184. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  185. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  186. }
  187. else if(atoi(val) >= 10 && atoi(val) <=100)
  188. {
  189. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  190. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  191. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
  192. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  193. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data
  194. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  195. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  196. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  197. }
  198. else if(atoi(val) > 0 && atoi(val) <=10)
  199. {
  200. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  201. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  202. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
  203. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  204. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //ten data
  205. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  206. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  207. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  208. }
  209. digitalWrite(stbPin, HIGH);
  210. delay(500);
  211. }
  212. //pin high. Stop receiving data
  213. packetSend(packetDataSaveTrans(NULL, datastr, val)); //将新数据值上传至数据流
  214. break;
  215. default:
  216. ;
  217. break;
  218. }
  219. }
  220. //delay(4);
  221. }
  222. if (rcv_pkt.len > 0)
  223. packetClear(&rcv_pkt);
  224. delay(150);
  225. }
  226. /*
  227. * readEdpPkt
  228. * 从串口缓存中读数据到接收缓存
  229. */
  230. bool readEdpPkt(edp_pkt *p)
  231. {
  232. int tmp;
  233. if ((tmp = WIFI_UART.readBytes(p->data + p->len, sizeof(p->data))) > 0 )
  234. {
  235. rcvDebug(p->data + p->len, tmp);
  236. p->len += tmp;
  237. }
  238. return true;
  239. }
  240. /*
  241. * packetSend
  242. * 将待发数据发送至串口,并释放到动态分配的内存
  243. */
  244. void packetSend(edp_pkt* pkt)
  245. {
  246. if (pkt != NULL)
  247. {
  248. WIFI_UART.write(pkt->data, pkt->len); //串口发送
  249. WIFI_UART.flush();
  250. free(pkt); //回收内存
  251. }
  252. }
  253. void rcvDebug(unsigned char *rcv, int len)
  254. {
  255. int i;
  256. }

DHT11.cpp

  1. /*
  2. File name: DHT11.cpp
  3. */
  4. #include "DHT11.h"
  5. // Return values:
  6. // DHTLIB_OK
  7. // DHTLIB_ERROR_CHECKSUM
  8. // DHTLIB_ERROR_TIMEOUT
  9. int DHT11::read(int pin)
  10. {
  11. // BUFFER TO RECEIVE
  12. uint8_t bits[5];
  13. uint8_t cnt = 7;
  14. uint8_t idx = 0;
  15. // EMPTY BUFFER
  16. for (int i=0; i< 5; i++) bits[i] = 0;
  17. // REQUEST SAMPLE
  18. pinMode(pin, OUTPUT);
  19. digitalWrite(pin, LOW);
  20. delay(18);
  21. digitalWrite(pin, HIGH);
  22. delayMicroseconds(40);
  23. pinMode(pin, INPUT);
  24. // ACKNOWLEDGE or TIMEOUT
  25. unsigned int loopCnt = 10000;
  26. while(digitalRead(pin) == LOW)
  27. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  28. loopCnt = 10000;
  29. while(digitalRead(pin) == HIGH)
  30. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  31. // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
  32. for (int i=0; i<40; i++)
  33. {
  34. loopCnt = 10000;
  35. while(digitalRead(pin) == LOW)
  36. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  37. unsigned long t = micros();
  38. loopCnt = 10000;
  39. while(digitalRead(pin) == HIGH)
  40. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  41. if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
  42. if (cnt == 0) // next byte?
  43. {
  44. cnt = 7; // restart at MSB
  45. idx++; // next byte!
  46. }
  47. else cnt--;
  48. }
  49. // WRITE TO RIGHT VARS
  50. // as bits[1] and bits[3] are allways zero they are omitted in formulas.
  51. humidity = bits[0];
  52. temperature = bits[2];
  53. uint8_t sum = bits[0] + bits[2];
  54. if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
  55. return DHTLIB_OK;
  56. }

DHT11.h

  1. /*
  2. /*
  3. File name: DHT11.h
  4. */
  5. */
  6. #ifndef DHT11_H
  7. #define DHT11_H
  8. #if defined(ARDUINO) && (ARDUINO >= 100)
  9. #include <Arduino.h>
  10. #else
  11. #include <WProgram.h>
  12. #endif
  13. #define DHT11LIB_VERSION "V1.0"
  14. #define DHTLIB_OK 0
  15. #define DHTLIB_ERROR_CHECKSUM -1
  16. #define DHTLIB_ERROR_TIMEOUT -2
  17. class DHT11
  18. {
  19. public:
  20. int read(int pin);
  21. int humidity;
  22. int temperature;
  23. };
  24. #endif

edp.c

  1. /*
  2. File name: edp.c
  3. */
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #define CONNREQ 0x10
  8. #define CONNRESP 0x20
  9. #define PUSHDATA 0x30
  10. #define SAVEDATA 0x80
  11. #define SAVEACK 0x90
  12. #define CMDREQ 0xA0
  13. #define CMDRESP 0xB0
  14. #define PINGREQ 0xC0
  15. #define PINGRESP 0xD0
  16. #define ENCRYPTREQ 0xE0
  17. #define ENCRYPTRESP 0xF0
  18. #define MAX_LEN 200
  19. #define PROTOCOL_NAME "EDP"
  20. #define PROTOCOL_VERSION 1
  21. typedef unsigned char uint8;
  22. typedef char int8;
  23. typedef unsigned int uint16;
  24. typedef int int16;
  25. typedef unsigned long uint32;
  26. typedef long int32;
  27. typedef struct
  28. {
  29. uint8 data[MAX_LEN];
  30. int16 len;
  31. int16 read_p;
  32. } edp_pkt;
  33. /*
  34. * packetCreate
  35. * 创建一个EDP包缓存空间
  36. */
  37. edp_pkt *packetCreate(void)
  38. {
  39. edp_pkt *p;
  40. if((p = (edp_pkt *)malloc(sizeof(edp_pkt))) != NULL)
  41. memset(p, 0, sizeof(edp_pkt));
  42. return p;
  43. }
  44. /*
  45. * writeRemainlen
  46. * 向EDP包中写入剩余长度字段
  47. * len_val: 剩余长度的值
  48. */
  49. int8 writeRemainlen(edp_pkt* pkt, int16 len_val)
  50. {
  51. int8 remaining_count = 0;
  52. int8 tmp = 0;
  53. do {
  54. tmp = len_val % 128;
  55. len_val = len_val / 128;
  56. /* If there are more digits to encode, set the top bit of this digit */
  57. if (len_val > 0) {
  58. tmp = tmp | 0x80;
  59. }
  60. pkt->data[pkt->len++] = tmp;
  61. remaining_count++;
  62. } while (len_val > 0 && remaining_count < 5);
  63. return remaining_count;
  64. }
  65. /*
  66. * writeByte
  67. * 向EDP包中写入一个字节
  68. */
  69. int16 writeByte(edp_pkt* pkt, int8 byte)
  70. {
  71. pkt->data[pkt->len++] = byte;
  72. return 0;
  73. }
  74. /*
  75. * writeBytes
  76. * 向EDP包中写入多个字节
  77. */
  78. int16 writeBytes(edp_pkt* pkt, const void* bytes, int16 count)
  79. {
  80. memcpy(pkt->data + pkt->len, bytes, count);
  81. pkt->len += count;
  82. return 0;
  83. }
  84. /*
  85. * writeStr
  86. * 向EDP包中写入字符串字段
  87. * 首先写入两个字节的长度,随后紧跟字符串内容
  88. */
  89. int16 writeStr(edp_pkt* pkt, const int8* str)
  90. {
  91. short len = strlen(str);
  92. writeByte(pkt, len >> 8);
  93. writeByte(pkt, len & 0x00ff);
  94. memcpy(pkt->data + pkt->len, str, len);
  95. pkt->len += len;
  96. return 0;
  97. }
  98. /*---------------------------------------------------------------------------*/
  99. /*
  100. * readUint8
  101. * 从EDP包中读出一个字节
  102. */
  103. uint8 readUint8(edp_pkt* pkt)
  104. {
  105. return pkt->data[pkt->read_p++];
  106. }
  107. /*
  108. * readUint16
  109. * 从EDP包中读出16bit的字段
  110. */
  111. uint16 readUint16(edp_pkt* pkt)
  112. {
  113. uint16 tmp;
  114. uint8 msb, lsb;
  115. msb = readUint8(pkt);
  116. lsb = readUint8(pkt);
  117. tmp = (msb<<8) | lsb;
  118. return tmp;
  119. }
  120. /*
  121. * readUint32
  122. * 从EDP包中读出4个字节的字段
  123. */
  124. uint32 readUint32(edp_pkt* pkt)
  125. {
  126. uint32 tmp = 0;
  127. int i = 4;
  128. while (--i >= 0)
  129. {
  130. tmp <<= 8;
  131. tmp |= readUint8(pkt);
  132. }
  133. return tmp;
  134. }
  135. /*
  136. * readStr
  137. * 根据长度,从EDP包中读出字符串数据
  138. * len : 字符串的长度
  139. */
  140. void readStr(edp_pkt* pkt, char* str, uint16 len)
  141. {
  142. memcpy(str, pkt->data + pkt->read_p, len);
  143. pkt->read_p += len;
  144. }
  145. /*
  146. * readRemainlen
  147. * 从EDP包中读出剩余长度
  148. */
  149. int32 readRemainlen(edp_pkt* pkt)
  150. {
  151. uint32 multiplier = 1;
  152. uint32 len_len = 0;
  153. uint8 onebyte = 0;
  154. int32 len_val = 0;
  155. do
  156. {
  157. onebyte = readUint8(pkt);
  158. len_val += (onebyte & 0x7f) * multiplier;
  159. multiplier *= 0x80;
  160. len_len++;
  161. if (len_len > 4)
  162. {
  163. return -1; /*len of len more than 4;*/
  164. }
  165. } while((onebyte & 0x80) != 0);
  166. return len_val;
  167. }
  168. /*
  169. * packetConnect:组EDP连接包
  170. * 首先创建EDP缓存空间,按照EDP协议组EDP连接包
  171. * 分配的内存需要在发送之后free掉
  172. * devid: 设备id
  173. * key:APIKey
  174. */
  175. edp_pkt *packetConnect(const int8* devid, const int8* key)
  176. {
  177. int32 remainlen;
  178. edp_pkt* pkt;
  179. if((pkt = packetCreate()) == NULL)
  180. return NULL;
  181. /* msg type */
  182. writeByte(pkt, CONNREQ);
  183. /* remain len */
  184. remainlen = (2 + 3) + 1 + 1 + 2 + (2 + strlen(devid)) + (2 + strlen(key));
  185. writeRemainlen(pkt, remainlen);
  186. /* protocol desc */
  187. writeStr(pkt, PROTOCOL_NAME);
  188. /* protocol version */
  189. writeByte(pkt, PROTOCOL_VERSION);
  190. /* connect flag */
  191. writeByte(pkt, 0x40);
  192. /* keep time */
  193. writeByte(pkt, 0);
  194. writeByte(pkt, 0x80);
  195. /* DEVID */
  196. writeStr(pkt, devid);
  197. /* auth key */
  198. writeStr(pkt, key);
  199. return pkt;
  200. }
  201. /*
  202. * packetDataSaveTrans:组EDP数据存储转发包
  203. * 首先创建EDP缓存空间,按照EDP协议组EDP数据存储转发包
  204. * 分配的内存需要在发送之后free掉
  205. * devid: 设备id
  206. * streamId:数据流ID,即数据流名
  207. * val: 字符串形式的数据值
  208. */
  209. edp_pkt *packetDataSaveTrans(const int8* destId, const int8* streamId, const int8 *val)
  210. {
  211. int32 remainlen;
  212. int8 tmp[200];
  213. int16 str_len;
  214. edp_pkt *pkt;
  215. if((pkt = packetCreate()) == NULL)
  216. return pkt;
  217. /* 生成数据类型格式5的数据类型 */
  218. sprintf(tmp, ",;%s,%s", streamId, val);
  219. str_len = strlen(tmp);
  220. /* msg type */
  221. writeByte(pkt, SAVEDATA);
  222. if (destId != NULL)
  223. {
  224. /* remain len */
  225. remainlen = 1 + (2 + strlen(destId)) + 1 + (2 + str_len);
  226. writeRemainlen(pkt, remainlen);
  227. /* translate address flag */
  228. writeByte(pkt, 0x80);
  229. /* dst devid */
  230. writeStr(pkt, destId);
  231. }
  232. else
  233. {
  234. /* remain len */
  235. remainlen = 1 + 1 + (2 + str_len);
  236. writeRemainlen(pkt, remainlen);
  237. /* translate address flag */
  238. writeByte(pkt, 0x00);
  239. }
  240. /* json flag */
  241. writeByte(pkt, 5);
  242. /* json */
  243. writeStr(pkt, tmp);
  244. return pkt;
  245. }
  246. void packetClear(edp_pkt* pkt)
  247. {
  248. memset(pkt, 0, sizeof(edp_pkt));
  249. }
  250. /*
  251. * isEdpPkt
  252. * 按照EDP数据格式,判断是否是完整数据包
  253. */
  254. int16 isEdpPkt(edp_pkt* pkt)
  255. {
  256. uint32 data_len = 0;
  257. uint32 multiplier = 1;
  258. uint32 len_val = 0;
  259. uint32 len_len = 1;
  260. uint32 pkt_total_len = 0;
  261. uint8* pdigit;
  262. pdigit = pkt->data;
  263. data_len = pkt->len;
  264. if (data_len <= 1)
  265. {
  266. return 0; /* continue receive */
  267. }
  268. do {
  269. if (len_len > 4)
  270. {
  271. return -1; /* protocol error; */
  272. }
  273. if (len_len > data_len - 1)
  274. {
  275. return 0; /* continue receive */
  276. }
  277. len_len++;
  278. pdigit++;
  279. len_val += ((*pdigit) & 0x7f) * multiplier;
  280. multiplier *= 0x80;
  281. } while (((*pdigit) & 0x80) != 0);
  282. pkt_total_len = len_len + len_val;
  283. /* receive payload */
  284. if (pkt_total_len == data_len)
  285. {
  286. return 1; /* all data for this pkt is read */
  287. }
  288. else
  289. {
  290. return 0; /* continue receive */
  291. }
  292. }
  293. /*
  294. * edpCommandReqParse
  295. * 按照EDP命令请求协议,解析数据
  296. */
  297. int edpCommandReqParse(edp_pkt* pkt, char *id, char *cmd, int32 *rmlen, int32 *id_len, int32 *cmd_len)
  298. {
  299. readUint8(pkt); /* 包类型 */
  300. *rmlen = readRemainlen(pkt); /* 剩余长度 */
  301. *id_len = readUint16(pkt); /* ID长度 */
  302. readStr(pkt, id, *id_len); /* 命令ID */
  303. *cmd_len = readUint32(pkt); /* 命令长度 */
  304. readStr(pkt, cmd, *cmd_len); /* 命令内容 */
  305. }
  306. /*
  307. * edpPushDataParse
  308. * 按照EDP透传数据格式,解析数据
  309. */
  310. int edpPushDataParse(edp_pkt* pkt, char *srcId, char *data)
  311. {
  312. uint32 remain_len;
  313. uint16 id_len;
  314. readUint8(pkt); /* 包类型 */
  315. remain_len = readRemainlen(pkt); /* 剩余长度 */
  316. id_len = readUint16(pkt); /* 源ID长度 */
  317. readStr(pkt, srcId, id_len); /* 源ID */
  318. readStr(pkt, data, remain_len - 2 - id_len); /* 数据内容 */
  319. }


(2021.04.15更新)
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

数据转换

sprintf()函数的使用总结 ,其作用是将一个格式化的 字符串 输出到一个目的 字符串 中;sprintf 最常见的应用之一是把整数打印到字符串中 int型转换成 char型。

sprintf(字符串,"%d",整数);

 sprintf(wd1,"%d",wd); //int型转换char型,sprintf 把整数打印到字符串中 

dtostrf()函数的使用,将 float型 数据转换为 char型

格式如下:

char* dtostrf (double _val, signed char _width, unsigned char prec, char* _s)

参数说明:

  • _val:要转换的float或者double值。

  • _width:转换后整数部分长度。

  • _prec:转换后小数部分长度。

  • _s:保存到该char数组中。

 dtostrf(xl,3,0,xl1);//dtostrf() 函数的用法    dtostrf(源数字,位数,小数点位数,转换的字符串);

sscanf函数用法详解 sscanf() 从一个字符串中,读入指定格式的数据。

关键代码

  sscanf(edp_command, "%[^:]:%s", datastr, val);

ESP8266_EDP.ino

  1. /***********************************************************
  2. File name: ESP8266_EDP.ino
  3. Description: ESP8266 realizes remote control via ONENet
  4. Author: Naiva
  5. Date: 2021/04/15
  6. ***********************************************************/
  7. #include "edp.c"
  8. #include "DHT11.h"
  9. DHT11 dht11;
  10. #define DHT11PIN 3 //pin3
  11. #define KEY "24eV33JUKr8dj=XGpckVygdFyJQ=" //APIkey
  12. #define ID "598229651" //设备ID
  13. //#define PUSH_ID "680788"
  14. #define PUSH_ID NULL
  15. String comdata = "";
  16. // 串口
  17. #define _baudrate 115200
  18. #define WIFI_UART Serial
  19. int DHT11 = 0;
  20. const int stbPin = 7; //the segment display module STB pin connected to digital pin 7
  21. const int clkPin = 9; //the segment display module CLK pin connected to digital pin 9
  22. const int dioPin = 8; //the segment display module DIO pin connected to digital pin 8
  23. uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };
  24. edp_pkt *pkt;
  25. /*
  26. * doCmdOk
  27. * 发送命令至模块,从回复中获取期待的关键字
  28. * keyword: 所期待的关键字
  29. * 成功找到关键字返回true,否则返回false
  30. */
  31. bool doCmdOk(String data, char *keyword)
  32. {
  33. bool result = false;
  34. if (data != "") //对于tcp连接命令,直接等待第二次回复
  35. {
  36. WIFI_UART.println(data); //发送AT指令
  37. }
  38. if (data == "AT") //检查模块存在
  39. delay(2000);
  40. else
  41. while (!WIFI_UART.available()); // 等待模块回复
  42. delay(200);
  43. if (WIFI_UART.find(keyword)) //返回值判断
  44. {
  45. result = true;
  46. }
  47. else
  48. {
  49. result = false;
  50. }
  51. while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
  52. delay(500); //指令时间间隔
  53. return result;
  54. }
  55. void sendCommand(uint8_t value)
  56. {
  57. digitalWrite(stbPin, LOW); //pin low. To begin receiving data
  58. shiftOut(dioPin, clkPin, LSBFIRST, value); //send data(value) to the segment display module
  59. digitalWrite(stbPin, HIGH); //pin high. Stop receiving data
  60. }
  61. void setup()
  62. {
  63. char buf[100] = {0};
  64. int tmp;
  65. pinMode(13, OUTPUT); //WIFI模块指示灯
  66. pinMode(8, OUTPUT); //用于连接EDP控制的发光二极管
  67. WIFI_UART.begin( _baudrate );
  68. pinMode(stbPin, OUTPUT); //initialize the stbPin as an output 数码管
  69. pinMode(clkPin, OUTPUT); //initialize the clkPin as an output
  70. pinMode(dioPin, OUTPUT); //initialize the dioPin as an output
  71. sendCommand(0x8f); //activate
  72. WIFI_UART.setTimeout(3000); //设置find超时时间
  73. delay(3000);
  74. Serial.setTimeout(100);
  75. delay(2000);
  76. while (!doCmdOk("AT", "OK"));
  77. digitalWrite(13, HIGH); // 使Led亮
  78. while (!doCmdOk("AT+CWMODE=3", "OK")); //工作模式
  79. while (!doCmdOk("AT+CWJAP=\"CatHome\",\"12345678\"", "OK"));//WiFi账号与WiFi密码
  80. while (!doCmdOk("AT+CIPSTART=\"TCP\",\"jjfaedp.hedevice.com\",876", "OK"));
  81. while (!doCmdOk("AT+CIPMODE=1", "OK")); //透传模式
  82. while (!doCmdOk("AT+CIPSEND", ">")); //开始发送
  83. }
  84. int dht_flag = 1;
  85. void loop()
  86. {
  87. static int edp_connect = 0;
  88. bool trigger = false;
  89. edp_pkt rcv_pkt;
  90. unsigned char pkt_type;
  91. int i = 0, tmp;
  92. char num[10];
  93. int wd, sd;
  94. int xl = random(110,140);
  95. double tz = random(2300,2900);
  96. char wd1[20],sd1[20];
  97. char xl1[20];
  98. char tz1[20];
  99. dtostrf(tz,6,2,tz1);//dtostrf() 函数的用法
  100. dtostrf(xl,3,0,xl1);//dtostrf() 函数的用法 dtostrf(源数字,位数,小数点位数,转换的字符串);
  101. /* EDP 连接 */
  102. if (!edp_connect)
  103. {
  104. while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
  105. packetSend(packetConnect(ID, KEY)); //发送EPD连接包
  106. while (!WIFI_UART.available()); //等待EDP连接应答
  107. if ((tmp = WIFI_UART.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0 )
  108. {
  109. rcvDebug(rcv_pkt.data, tmp);
  110. if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00)
  111. {
  112. edp_connect = 1;
  113. digitalWrite(13, LOW); // 使Led灭
  114. }
  115. else
  116. ;
  117. }
  118. packetClear(&rcv_pkt);
  119. }
  120. if(dht_flag == 1)
  121. {
  122. dht_flag = 0;
  123. dht11.read(DHT11PIN);//温湿度
  124. wd = dht11.temperature;
  125. sd = dht11.humidity;
  126. sprintf(wd1,"%d",wd); //int型转换char型,sprintf 把整数打印到字符串中
  127. sprintf(sd1,"%d",sd); //int型转换char型
  128. DHT11 = 0;
  129. delay(500);
  130. packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流 WD是上传的地方 wd1是上传的数据
  131. delay(500);
  132. packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流
  133. delay(500);
  134. packetSend(packetDataSaveTrans(NULL, "XL", xl1)); //将新数据值上传至数据流
  135. delay(500);
  136. packetSend(packetDataSaveTrans(NULL, "TZ", tz1)); //将新数据值上传至数据流
  137. delay(500);
  138. }
  139. DHT11++;
  140. if(DHT11 > 150&&edp_connect)
  141. {
  142. dht11.read(DHT11PIN);
  143. wd = dht11.temperature;
  144. sd = dht11.humidity;
  145. sprintf(wd1,"%d",wd); //int型转换char型
  146. sprintf(sd1,"%d",sd); //int型转换char型
  147. DHT11 = 0;
  148. delay(500);
  149. packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流
  150. delay(500);
  151. packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流
  152. delay(500);
  153. packetSend(packetDataSaveTrans(NULL, "XL", xl1)); //将新数据值上传至数据流
  154. delay(500);
  155. packetSend(packetDataSaveTrans(NULL, "TZ", tz1)); //将新数据值上传至数据流
  156. delay(500);
  157. }
  158. while (WIFI_UART.available())
  159. {
  160. readEdpPkt(&rcv_pkt);
  161. if (isEdpPkt(&rcv_pkt))
  162. {
  163. pkt_type = rcv_pkt.data[0];
  164. switch (pkt_type)
  165. {
  166. case CMDREQ:
  167. char edp_command[50];
  168. char edp_cmd_id[40];
  169. long id_len, cmd_len, rm_len;
  170. char datastr[20];
  171. char val[10];
  172. memset(edp_command, 0, sizeof(edp_command));
  173. memset(edp_cmd_id, 0, sizeof(edp_cmd_id));
  174. edpCommandReqParse(&rcv_pkt, edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len);
  175. //数据处理与应用中EDP命令内容对应
  176. //本例中格式为 datastream:[1/0]
  177. sscanf(edp_command, "%[^:]:%s", datastr, val);
  178. if (atoi(val) == 1)
  179. { // 使Led亮
  180. digitalWrite(13, HIGH);
  181. digitalWrite(8, HIGH);}
  182. else
  183. { digitalWrite(13, LOW); // 使Led灭
  184. digitalWrite(8, LOW);}
  185. if(atoi(val) > 1)
  186. {
  187. sendCommand(0x40); //setting the Write Data Command,using automatic address genuine.
  188. digitalWrite(stbPin, LOW); //pin low. To begin receiving data
  189. shiftOut(dioPin, clkPin, LSBFIRST, 0xc0); //Set the start address 0C0H
  190. if(atoi(val) >= 100 && atoi(val) <=1000)
  191. {
  192. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  193. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  194. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/100%10]); //hundred data
  195. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  196. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data
  197. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  198. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  199. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  200. }
  201. else if(atoi(val) >= 10 && atoi(val) <=100)
  202. {
  203. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  204. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  205. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
  206. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  207. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data
  208. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  209. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  210. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  211. }
  212. else if(atoi(val) > 0 && atoi(val) <=10)
  213. {
  214. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  215. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  216. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
  217. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  218. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //ten data
  219. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  220. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  221. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  222. }
  223. digitalWrite(stbPin, HIGH);
  224. delay(500);
  225. }
  226. //pin high. Stop receiving data
  227. packetSend(packetDataSaveTrans(NULL, datastr, val)); //将新数据值上传至数据流
  228. break;
  229. default:
  230. ;
  231. break;
  232. }
  233. }
  234. //delay(4);
  235. }
  236. if (rcv_pkt.len > 0)
  237. packetClear(&rcv_pkt);
  238. delay(150);
  239. }
  240. /*
  241. * readEdpPkt
  242. * 从串口缓存中读数据到接收缓存
  243. */
  244. bool readEdpPkt(edp_pkt *p)
  245. {
  246. int tmp;
  247. if ((tmp = WIFI_UART.readBytes(p->data + p->len, sizeof(p->data))) > 0 )
  248. {
  249. rcvDebug(p->data + p->len, tmp);
  250. p->len += tmp;
  251. }
  252. return true;
  253. }
  254. /*
  255. * packetSend
  256. * 将待发数据发送至串口,并释放到动态分配的内存
  257. */
  258. void packetSend(edp_pkt* pkt)
  259. {
  260. if (pkt != NULL)
  261. {
  262. WIFI_UART.write(pkt->data, pkt->len); //串口发送
  263. WIFI_UART.flush();
  264. free(pkt); //回收内存
  265. }
  266. }
  267. void rcvDebug(unsigned char *rcv, int len)
  268. {
  269. int i;
  270. }

2021.04.21 总结:

OneNet应用中,增设两个控制按钮,一个灯光(),一个除菌。

edp_command 等于

  • "switch:1 "
  • "switch:0 "
  • "switch:2 "
  • “switch:3”

状态EDP命令
除菌switch:1
除菌switch:0
照明switch:2
照明switch:3

在这里插入图片描述

关键代码一:sscanf () 函数 数据转换的运用

 sscanf(edp_command, "%[^:]:%s", datastr, val); //"%[^:]:%s"  = switch:1

关键代码二:设置控制灯引脚

  1. pinMode(13, OUTPUT); // WIFI模块指示灯
  2. pinMode(12, OUTPUT); // 用于连接EDP控制的发光二极管

关键代码三:判断edp命令 控制对应的灯

  1. //本例中格式为 datastream:[1/0]
  2. sscanf(edp_command, "%[^:]:%s", datastr, val);
  3. "%[^:]:%s" = switch:1
  4. if (atoi(val) == 1)//数据结尾是1
  5. { // 使Led亮
  6. digitalWrite(12, HIGH);
  7. }
  8. if(atoi(val) == 0)//数据结尾是0
  9. { digitalWrite(12, LOW); // 使Led灭
  10. }
  11. if(atoi(val) == 2)//数据结尾是0
  12. { digitalWrite(13, HIGH); // 使Led灭
  13. }
  14. if(atoi(val) == 3)//数据结尾是0
  15. { digitalWrite(13, LOW); // 使Led灭
  16. }

附:项目完整代码

ESP8266_EDP.ino文件

  1. /***********************************************************
  2. File name: ESP8266_EDP.ino
  3. Description: ESP8266 realizes remote control via ONENet
  4. Author: Naiva
  5. Date: 2021/04/21
  6. ***********************************************************/
  7. #include "edp.c"
  8. #include "DHT11.h"
  9. #include "HX711.h"//重量HX711
  10. int Weight = 0;//获取重量的变量
  11. DHT11 dht11;
  12. #define DHT11PIN 3 //pin3
  13. #define KEY "24eV33JUKr8dj=XGpckVygdFyJQ=" //APIkey
  14. #define ID "598229651" //设备ID
  15. //#define PUSH_ID "680788"
  16. #define PUSH_ID NULL
  17. String comdata = "";
  18. // 串口
  19. #define _baudrate 115200
  20. #define WIFI_UART Serial
  21. int DHT11 = 0;
  22. const int stbPin = 7; //the segment display module STB pin connected to digital pin 7
  23. const int clkPin = 9; //the segment display module CLK pin connected to digital pin 9
  24. const int dioPin = 8; //the segment display module DIO pin connected to digital pin 8
  25. uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };
  26. edp_pkt *pkt;
  27. /*
  28. * doCmdOk
  29. * 发送命令至模块,从回复中获取期待的关键字
  30. * keyword: 所期待的关键字
  31. * 成功找到关键字返回true,否则返回false
  32. */
  33. bool doCmdOk(String data, char *keyword)
  34. {
  35. bool result = false;
  36. if (data != "") //对于tcp连接命令,直接等待第二次回复
  37. {
  38. WIFI_UART.println(data); //发送AT指令
  39. }
  40. if (data == "AT") //检查模块存在
  41. delay(2000);
  42. else
  43. while (!WIFI_UART.available()); // 等待模块回复
  44. delay(200);
  45. if (WIFI_UART.find(keyword)) //返回值判断
  46. {
  47. result = true;
  48. }
  49. else
  50. {
  51. result = false;
  52. }
  53. while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
  54. delay(500); //指令时间间隔
  55. return result;
  56. }
  57. void sendCommand(uint8_t value)
  58. {
  59. digitalWrite(stbPin, LOW); //pin low. To begin receiving data
  60. shiftOut(dioPin, clkPin, LSBFIRST, value); //send data(value) to the segment display module
  61. digitalWrite(stbPin, HIGH); //pin high. Stop receiving data
  62. }
  63. void setup()
  64. {
  65. char buf[100] = {0};
  66. int tmp;
  67. pinMode(13, OUTPUT); // WIFI模块指示灯
  68. pinMode(12, OUTPUT); // 用于连接EDP控制的发光二极管
  69. Init_Hx711(); //初始化HX711模块连接的IO设置
  70. delay(3000);
  71. Get_Maopi(); //获取毛皮
  72. WIFI_UART.begin( _baudrate );
  73. pinMode(stbPin, OUTPUT); //initialize the stbPin as an output 数码管
  74. pinMode(clkPin, OUTPUT); //initialize the clkPin as an output
  75. pinMode(dioPin, OUTPUT); //initialize the dioPin as an output
  76. sendCommand(0x8f); //activate
  77. WIFI_UART.setTimeout(3000); //设置find超时时间
  78. delay(3000);
  79. Serial.setTimeout(100);
  80. delay(2000);
  81. while (!doCmdOk("AT", "OK"));
  82. digitalWrite(13, HIGH); // 使Led亮
  83. while (!doCmdOk("AT+CWMODE=3", "OK")); //工作模式
  84. while (!doCmdOk("AT+CWJAP=\"CatHome\",\"12345678\"", "OK"));//WiFi账号与WiFi密码
  85. while (!doCmdOk("AT+CIPSTART=\"TCP\",\"jjfaedp.hedevice.com\",876", "OK"));
  86. while (!doCmdOk("AT+CIPMODE=1", "OK")); //透传模式
  87. while (!doCmdOk("AT+CIPSEND", ">")); //开始发送
  88. }
  89. int dht_flag = 1;
  90. void loop()
  91. {
  92. static int edp_connect = 0;
  93. bool trigger = false;
  94. edp_pkt rcv_pkt;
  95. unsigned char pkt_type;
  96. int i = 0, tmp;
  97. char num[10];
  98. int wd, sd;
  99. int xl = random(110,140); //心率
  100. int tz = Get_Weight() - 170; //计算放在传感器上的重物重量
  101. if(tz >= 5000)
  102. {tz = 2980;}
  103. else if(tz <= 0)
  104. {tz = 0;}
  105. char wd1[20],sd1[20];
  106. char xl1[20];
  107. char tz1[20];
  108. dtostrf(xl,3,0,xl1);//dtostrf() 函数的用法 dtostrf(源数字,位数,小数点位数,转换的字符串);
  109. sprintf(tz1,"%d",tz); //int型转换char型
  110. /* EDP 连接 */
  111. if (!edp_connect)
  112. {
  113. while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
  114. packetSend(packetConnect(ID, KEY)); //发送EPD连接包
  115. while (!WIFI_UART.available()); //等待EDP连接应答
  116. if ((tmp = WIFI_UART.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0 )
  117. {
  118. rcvDebug(rcv_pkt.data, tmp);
  119. if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00)
  120. {
  121. edp_connect = 1;
  122. digitalWrite(13, LOW); // 使Led灭
  123. }
  124. else
  125. ;
  126. }
  127. packetClear(&rcv_pkt);
  128. }
  129. if(dht_flag == 1)
  130. {
  131. dht_flag = 0;
  132. dht11.read(DHT11PIN);//温湿度
  133. wd = dht11.temperature;
  134. sd = dht11.humidity;
  135. sprintf(wd1,"%d",wd); //int型转换char型,sprintf 把整数打印到字符串中
  136. sprintf(sd1,"%d",sd); //int型转换char型
  137. DHT11 = 0;
  138. delay(500);
  139. packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流 WD是上传的地方 wd1是上传的数据
  140. delay(500);
  141. packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流
  142. delay(500);
  143. packetSend(packetDataSaveTrans(NULL, "XL", xl1)); //将新数据值上传至数据流
  144. delay(500);
  145. packetSend(packetDataSaveTrans(NULL, "TZ", tz1)); //将新数据值上传至数据流
  146. delay(500);
  147. }
  148. DHT11++;
  149. if(DHT11 > 150&&edp_connect)
  150. {
  151. dht11.read(DHT11PIN);
  152. wd = dht11.temperature;
  153. sd = dht11.humidity;
  154. sprintf(wd1,"%d",wd); //int型转换char型
  155. sprintf(sd1,"%d",sd); //int型转换char型
  156. DHT11 = 0;
  157. delay(500);
  158. packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流
  159. delay(500);
  160. packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流
  161. delay(500);
  162. packetSend(packetDataSaveTrans(NULL, "XL", xl1)); //将新数据值上传至数据流
  163. delay(500);
  164. packetSend(packetDataSaveTrans(NULL, "TZ", tz1)); //将新数据值上传至数据流
  165. delay(500);
  166. }
  167. while (WIFI_UART.available())
  168. {
  169. readEdpPkt(&rcv_pkt);
  170. if (isEdpPkt(&rcv_pkt))
  171. {
  172. pkt_type = rcv_pkt.data[0];
  173. switch (pkt_type)
  174. {
  175. case CMDREQ:
  176. char edp_command[50];
  177. char edp_cmd_id[40];
  178. long id_len, cmd_len, rm_len;
  179. char datastr[20];
  180. char val[10];
  181. memset(edp_command, 0, sizeof(edp_command));
  182. memset(edp_cmd_id, 0, sizeof(edp_cmd_id));
  183. edpCommandReqParse(&rcv_pkt, edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len); //将onenet下发下来的命令转译
  184. //数据处理与应用中EDP命令内容对应
  185. //本例中格式为 datastream:[1/0]
  186. sscanf(edp_command, "%[^:]:%s", datastr, val);
  187. if (atoi(val) == 1)//数据结尾是1
  188. { // 使Led亮
  189. digitalWrite(12, HIGH);
  190. }
  191. if(atoi(val) == 0)//数据结尾是0
  192. { digitalWrite(12, LOW); // 使Led灭
  193. }
  194. if(atoi(val) == 2)//数据结尾是0
  195. { digitalWrite(13, HIGH); // 使Led灭
  196. }
  197. if(atoi(val) == 3)//数据结尾是0
  198. { digitalWrite(13, LOW); // 使Led灭
  199. }
  200. if(atoi(val) > 1)
  201. {
  202. sendCommand(0x40); //setting the Write Data Command,using automatic address genuine.
  203. digitalWrite(stbPin, LOW); //pin low. To begin receiving data
  204. shiftOut(dioPin, clkPin, LSBFIRST, 0xc0); //Set the start address 0C0H
  205. if(atoi(val) >= 100 && atoi(val) <=1000)
  206. {
  207. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  208. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  209. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/100%10]); //hundred data
  210. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  211. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data
  212. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  213. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  214. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  215. }
  216. else if(atoi(val) >= 10 && atoi(val) <=100)
  217. {
  218. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  219. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  220. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
  221. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  222. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data
  223. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  224. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  225. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  226. }
  227. else if(atoi(val) > 0 && atoi(val) <=10)
  228. {
  229. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
  230. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  231. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
  232. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  233. shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //ten data
  234. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  235. shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data
  236. shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
  237. }
  238. digitalWrite(stbPin, HIGH);
  239. delay(500);
  240. }
  241. //pin high. Stop receiving data
  242. packetSend(packetDataSaveTrans(NULL, datastr, val)); //将新数据值上传至数据流
  243. break;
  244. default:
  245. ;
  246. break;
  247. }
  248. }
  249. //delay(4);
  250. }
  251. if (rcv_pkt.len > 0)
  252. packetClear(&rcv_pkt);
  253. delay(150);
  254. }
  255. /*
  256. * readEdpPkt
  257. * 从串口缓存中读数据到接收缓存
  258. */
  259. bool readEdpPkt(edp_pkt *p)
  260. {
  261. int tmp;
  262. if ((tmp = WIFI_UART.readBytes(p->data + p->len, sizeof(p->data))) > 0 )
  263. {
  264. rcvDebug(p->data + p->len, tmp);
  265. p->len += tmp;
  266. }
  267. return true;
  268. }
  269. /*
  270. * packetSend
  271. * 将待发数据发送至串口,并释放到动态分配的内存
  272. */
  273. void packetSend(edp_pkt* pkt)
  274. {
  275. if (pkt != NULL)
  276. {
  277. WIFI_UART.write(pkt->data, pkt->len); //串口发送
  278. WIFI_UART.flush();
  279. free(pkt); //回收内存
  280. }
  281. }
  282. void rcvDebug(unsigned char *rcv, int len)
  283. {
  284. int i;
  285. }

edp.c文件

  1. /*
  2. File name: edp.c
  3. */
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #define CONNREQ 0x10
  8. #define CONNRESP 0x20
  9. #define PUSHDATA 0x30
  10. #define SAVEDATA 0x80
  11. #define SAVEACK 0x90
  12. #define CMDREQ 0xA0
  13. #define CMDRESP 0xB0
  14. #define PINGREQ 0xC0
  15. #define PINGRESP 0xD0
  16. #define ENCRYPTREQ 0xE0
  17. #define ENCRYPTRESP 0xF0
  18. #define MAX_LEN 200
  19. #define PROTOCOL_NAME "EDP"
  20. #define PROTOCOL_VERSION 1
  21. typedef unsigned char uint8;
  22. typedef char int8;
  23. typedef unsigned int uint16;
  24. typedef int int16;
  25. typedef unsigned long uint32;
  26. typedef long int32;
  27. typedef struct
  28. {
  29. uint8 data[MAX_LEN];
  30. int16 len;
  31. int16 read_p;
  32. } edp_pkt;
  33. /*
  34. * packetCreate
  35. * 创建一个EDP包缓存空间
  36. */
  37. edp_pkt *packetCreate(void)
  38. {
  39. edp_pkt *p;
  40. if((p = (edp_pkt *)malloc(sizeof(edp_pkt))) != NULL)
  41. memset(p, 0, sizeof(edp_pkt));
  42. return p;
  43. }
  44. /*
  45. * writeRemainlen
  46. * 向EDP包中写入剩余长度字段
  47. * len_val: 剩余长度的值
  48. */
  49. int8 writeRemainlen(edp_pkt* pkt, int16 len_val)
  50. {
  51. int8 remaining_count = 0;
  52. int8 tmp = 0;
  53. do {
  54. tmp = len_val % 128;
  55. len_val = len_val / 128;
  56. /* If there are more digits to encode, set the top bit of this digit */
  57. if (len_val > 0) {
  58. tmp = tmp | 0x80;
  59. }
  60. pkt->data[pkt->len++] = tmp;
  61. remaining_count++;
  62. } while (len_val > 0 && remaining_count < 5);
  63. return remaining_count;
  64. }
  65. /*
  66. * writeByte
  67. * 向EDP包中写入一个字节
  68. */
  69. int16 writeByte(edp_pkt* pkt, int8 byte)
  70. {
  71. pkt->data[pkt->len++] = byte;
  72. return 0;
  73. }
  74. /*
  75. * writeBytes
  76. * 向EDP包中写入多个字节
  77. */
  78. int16 writeBytes(edp_pkt* pkt, const void* bytes, int16 count)
  79. {
  80. memcpy(pkt->data + pkt->len, bytes, count);
  81. pkt->len += count;
  82. return 0;
  83. }
  84. /*
  85. * writeStr
  86. * 向EDP包中写入字符串字段
  87. * 首先写入两个字节的长度,随后紧跟字符串内容
  88. */
  89. int16 writeStr(edp_pkt* pkt, const int8* str)
  90. {
  91. short len = strlen(str);
  92. writeByte(pkt, len >> 8);
  93. writeByte(pkt, len & 0x00ff);
  94. memcpy(pkt->data + pkt->len, str, len);
  95. pkt->len += len;
  96. return 0;
  97. }
  98. /*---------------------------------------------------------------------------*/
  99. /*
  100. * readUint8
  101. * 从EDP包中读出一个字节
  102. */
  103. uint8 readUint8(edp_pkt* pkt)
  104. {
  105. return pkt->data[pkt->read_p++];
  106. }
  107. /*
  108. * readUint16
  109. * 从EDP包中读出16bit的字段
  110. */
  111. uint16 readUint16(edp_pkt* pkt)
  112. {
  113. uint16 tmp;
  114. uint8 msb, lsb;
  115. msb = readUint8(pkt);
  116. lsb = readUint8(pkt);
  117. tmp = (msb<<8) | lsb;
  118. return tmp;
  119. }
  120. /*
  121. * readUint32
  122. * 从EDP包中读出4个字节的字段
  123. */
  124. uint32 readUint32(edp_pkt* pkt)
  125. {
  126. uint32 tmp = 0;
  127. int i = 4;
  128. while (--i >= 0)
  129. {
  130. tmp <<= 8;
  131. tmp |= readUint8(pkt);
  132. }
  133. return tmp;
  134. }
  135. /*
  136. * readStr
  137. * 根据长度,从EDP包中读出字符串数据
  138. * len : 字符串的长度
  139. */
  140. void readStr(edp_pkt* pkt, char* str, uint16 len)
  141. {
  142. memcpy(str, pkt->data + pkt->read_p, len);
  143. pkt->read_p += len;
  144. }
  145. /*
  146. * readRemainlen
  147. * 从EDP包中读出剩余长度
  148. */
  149. int32 readRemainlen(edp_pkt* pkt)
  150. {
  151. uint32 multiplier = 1;
  152. uint32 len_len = 0;
  153. uint8 onebyte = 0;
  154. int32 len_val = 0;
  155. do
  156. {
  157. onebyte = readUint8(pkt);
  158. len_val += (onebyte & 0x7f) * multiplier;
  159. multiplier *= 0x80;
  160. len_len++;
  161. if (len_len > 4)
  162. {
  163. return -1; /*len of len more than 4;*/
  164. }
  165. } while((onebyte & 0x80) != 0);
  166. return len_val;
  167. }
  168. /*
  169. * packetConnect:组EDP连接包
  170. * 首先创建EDP缓存空间,按照EDP协议组EDP连接包
  171. * 分配的内存需要在发送之后free掉
  172. * devid: 设备id
  173. * key:APIKey
  174. */
  175. edp_pkt *packetConnect(const int8* devid, const int8* key)
  176. {
  177. int32 remainlen;
  178. edp_pkt* pkt;
  179. if((pkt = packetCreate()) == NULL)
  180. return NULL;
  181. /* msg type */
  182. writeByte(pkt, CONNREQ);
  183. /* remain len */
  184. remainlen = (2 + 3) + 1 + 1 + 2 + (2 + strlen(devid)) + (2 + strlen(key));
  185. writeRemainlen(pkt, remainlen);
  186. /* protocol desc */
  187. writeStr(pkt, PROTOCOL_NAME);
  188. /* protocol version */
  189. writeByte(pkt, PROTOCOL_VERSION);
  190. /* connect flag */
  191. writeByte(pkt, 0x40);
  192. /* keep time */
  193. writeByte(pkt, 0);
  194. writeByte(pkt, 0x80);
  195. /* DEVID */
  196. writeStr(pkt, devid);
  197. /* auth key */
  198. writeStr(pkt, key);
  199. return pkt;
  200. }
  201. /*
  202. * packetDataSaveTrans:组EDP数据存储转发包
  203. * 首先创建EDP缓存空间,按照EDP协议组EDP数据存储转发包
  204. * 分配的内存需要在发送之后free掉
  205. * devid: 设备id
  206. * streamId:数据流ID,即数据流名
  207. * val: 字符串形式的数据值
  208. */
  209. edp_pkt *packetDataSaveTrans(const int8* destId, const int8* streamId, const int8 *val)
  210. {
  211. int32 remainlen;
  212. int8 tmp[200];
  213. int16 str_len;
  214. edp_pkt *pkt;
  215. if((pkt = packetCreate()) == NULL)
  216. return pkt;
  217. /* 生成数据类型格式5的数据类型 */
  218. sprintf(tmp, ",;%s,%s", streamId, val);
  219. str_len = strlen(tmp);
  220. /* msg type */
  221. writeByte(pkt, SAVEDATA);
  222. if (destId != NULL)
  223. {
  224. /* remain len */
  225. remainlen = 1 + (2 + strlen(destId)) + 1 + (2 + str_len);
  226. writeRemainlen(pkt, remainlen);
  227. /* translate address flag */
  228. writeByte(pkt, 0x80);
  229. /* dst devid */
  230. writeStr(pkt, destId);
  231. }
  232. else
  233. {
  234. /* remain len */
  235. remainlen = 1 + 1 + (2 + str_len);
  236. writeRemainlen(pkt, remainlen);
  237. /* translate address flag */
  238. writeByte(pkt, 0x00);
  239. }
  240. /* json flag */
  241. writeByte(pkt, 5);
  242. /* json */
  243. writeStr(pkt, tmp);
  244. return pkt;
  245. }
  246. void packetClear(edp_pkt* pkt)
  247. {
  248. memset(pkt, 0, sizeof(edp_pkt));
  249. }
  250. /*
  251. * isEdpPkt
  252. * 按照EDP数据格式,判断是否是完整数据包
  253. */
  254. int16 isEdpPkt(edp_pkt* pkt)
  255. {
  256. uint32 data_len = 0;
  257. uint32 multiplier = 1;
  258. uint32 len_val = 0;
  259. uint32 len_len = 1;
  260. uint32 pkt_total_len = 0;
  261. uint8* pdigit;
  262. pdigit = pkt->data;
  263. data_len = pkt->len;
  264. if (data_len <= 1)
  265. {
  266. return 0; /* continue receive */
  267. }
  268. do {
  269. if (len_len > 4)
  270. {
  271. return -1; /* protocol error; */
  272. }
  273. if (len_len > data_len - 1)
  274. {
  275. return 0; /* continue receive */
  276. }
  277. len_len++;
  278. pdigit++;
  279. len_val += ((*pdigit) & 0x7f) * multiplier;
  280. multiplier *= 0x80;
  281. } while (((*pdigit) & 0x80) != 0);
  282. pkt_total_len = len_len + len_val;
  283. /* receive payload */
  284. if (pkt_total_len == data_len)
  285. {
  286. return 1; /* all data for this pkt is read */
  287. }
  288. else
  289. {
  290. return 0; /* continue receive */
  291. }
  292. }
  293. /*
  294. * edpCommandReqParse
  295. * 按照EDP命令请求协议,解析数据
  296. */
  297. int edpCommandReqParse(edp_pkt* pkt, char *id, char *cmd, int32 *rmlen, int32 *id_len, int32 *cmd_len)
  298. {
  299. readUint8(pkt); /* 包类型 */
  300. *rmlen = readRemainlen(pkt); /* 剩余长度 */
  301. *id_len = readUint16(pkt); /* ID长度 */
  302. readStr(pkt, id, *id_len); /* 命令ID */
  303. *cmd_len = readUint32(pkt); /* 命令长度 */
  304. readStr(pkt, cmd, *cmd_len); /* 命令内容 */
  305. }
  306. /*
  307. * edpPushDataParse
  308. * 按照EDP透传数据格式,解析数据
  309. */
  310. int edpPushDataParse(edp_pkt* pkt, char *srcId, char *data)
  311. {
  312. uint32 remain_len;
  313. uint16 id_len;
  314. readUint8(pkt); /* 包类型 */
  315. remain_len = readRemainlen(pkt); /* 剩余长度 */
  316. id_len = readUint16(pkt); /* 源ID长度 */
  317. readStr(pkt, srcId, id_len); /* 源ID */
  318. readStr(pkt, data, remain_len - 2 - id_len); /* 数据内容 */
  319. }


DHT11.cpp文件

  1. /*
  2. File name: DHT11.cpp
  3. */
  4. #include "DHT11.h"
  5. // Return values:
  6. // DHTLIB_OK
  7. // DHTLIB_ERROR_CHECKSUM
  8. // DHTLIB_ERROR_TIMEOUT
  9. int DHT11::read(int pin)
  10. {
  11. // BUFFER TO RECEIVE
  12. uint8_t bits[5];
  13. uint8_t cnt = 7;
  14. uint8_t idx = 0;
  15. // EMPTY BUFFER
  16. for (int i=0; i< 5; i++) bits[i] = 0;
  17. // REQUEST SAMPLE
  18. pinMode(pin, OUTPUT);
  19. digitalWrite(pin, LOW);
  20. delay(18);
  21. digitalWrite(pin, HIGH);
  22. delayMicroseconds(40);
  23. pinMode(pin, INPUT);
  24. // ACKNOWLEDGE or TIMEOUT
  25. unsigned int loopCnt = 10000;
  26. while(digitalRead(pin) == LOW)
  27. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  28. loopCnt = 10000;
  29. while(digitalRead(pin) == HIGH)
  30. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  31. // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
  32. for (int i=0; i<40; i++)
  33. {
  34. loopCnt = 10000;
  35. while(digitalRead(pin) == LOW)
  36. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  37. unsigned long t = micros();
  38. loopCnt = 10000;
  39. while(digitalRead(pin) == HIGH)
  40. if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  41. if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
  42. if (cnt == 0) // next byte?
  43. {
  44. cnt = 7; // restart at MSB
  45. idx++; // next byte!
  46. }
  47. else cnt--;
  48. }
  49. // WRITE TO RIGHT VARS
  50. // as bits[1] and bits[3] are allways zero they are omitted in formulas.
  51. humidity = bits[0];
  52. temperature = bits[2];
  53. uint8_t sum = bits[0] + bits[2];
  54. if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
  55. return DHTLIB_OK;
  56. }

DHT11.h文件

  1. /*
  2. File name: DHT11.h
  3. */
  4. #ifndef DHT11_H
  5. #define DHT11_H
  6. #if defined(ARDUINO) && (ARDUINO >= 100)
  7. #include <Arduino.h>
  8. #else
  9. #include <WProgram.h>
  10. #endif
  11. #define DHT11LIB_VERSION "V1.0"
  12. #define DHTLIB_OK 0
  13. #define DHTLIB_ERROR_CHECKSUM -1
  14. #define DHTLIB_ERROR_TIMEOUT -2
  15. class DHT11
  16. {
  17. public:
  18. int read(int pin);
  19. int humidity;
  20. int temperature;
  21. };
  22. #endif

HX711.cpp文件

  1. #include "hx711.h"
  2. long HX711_Buffer = 0;
  3. long Weight_Maopi = 0,Weight_Shiwu = 0;
  4. #define GapValue 430
  5. //****************************************************
  6. //初始化HX711
  7. //****************************************************
  8. void Init_Hx711()
  9. {
  10. pinMode(HX711_SCK, OUTPUT);
  11. pinMode(HX711_DT, INPUT);
  12. }
  13. //****************************************************
  14. //获取毛皮重量
  15. //****************************************************
  16. void Get_Maopi()
  17. {
  18. Weight_Maopi = HX711_Read();
  19. }
  20. //****************************************************
  21. //称重
  22. //****************************************************
  23. long Get_Weight()
  24. {
  25. HX711_Buffer = HX711_Read();
  26. Weight_Shiwu = HX711_Buffer;
  27. Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
  28. Weight_Shiwu = (long)((float)Weight_Shiwu/GapValue);
  29. return Weight_Shiwu;
  30. }
  31. //****************************************************
  32. //读取HX711
  33. //****************************************************
  34. unsigned long HX711_Read(void) //增益128
  35. {
  36. unsigned long count;
  37. unsigned char i;
  38. bool Flag = 0;
  39. digitalWrite(HX711_DT, HIGH);
  40. delayMicroseconds(1);
  41. digitalWrite(HX711_SCK, LOW);
  42. delayMicroseconds(1);
  43. count=0;
  44. while(digitalRead(HX711_DT));
  45. for(i=0;i<24;i++)
  46. {
  47. digitalWrite(HX711_SCK, HIGH);
  48. delayMicroseconds(1);
  49. count=count<<1;
  50. digitalWrite(HX711_SCK, LOW);
  51. delayMicroseconds(1);
  52. if(digitalRead(HX711_DT))
  53. count++;
  54. }
  55. digitalWrite(HX711_SCK, HIGH);
  56. count ^= 0x800000;
  57. delayMicroseconds(1);
  58. digitalWrite(HX711_SCK, LOW);
  59. delayMicroseconds(1);
  60. return(count);
  61. }

HX711.h文件

  1. #ifndef __HX711__H__
  2. #define __HX711__H__
  3. #include <Arduino.h>
  4. #define HX711_SCK 5 //定义hx711传感器SCK 引脚
  5. #define HX711_DT 6
  6. extern void Init_Hx711();
  7. extern unsigned long HX711_Read(void);
  8. extern long Get_Weight();
  9. extern void Get_Maopi();
  10. #endif


划重点
本人在CSDN论坛写的所有文章,仅针对本人自身做学习记录,不全面,不详细,还请见谅!

如果有小伙伴真心需要我做详细解答,欢迎加入我的知识星球知识星球Naiva的知识问答社区

特别说明:回答问题/发帖分享经验都能赚钱啦!为了鼓励大家积极踊跃分享,互相交流答疑解惑,特组织答疑返佣金活动。


---------------------
作者:Naiva
来源:CSDN
原文:https://blog.csdn.net/Naiva/article/details/106113999
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/718220
推荐阅读
相关标签
  

闽ICP备14008679号