我是靠谱客的博主 善良火车,这篇文章主要介绍Arduno + ESP8266模组运用中移OneNet物联网平台实现远程监控,现在分享给大家,希望可以做个参考。

一、初识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 ),通过手机或平板查看。


参考资料

  • [1] 【电子发烧友】Arduino接入OneNET云服务
  • [2] 【CSDN】Arduino物联网三步曲—(1)OneNET初识
  • [3] Arduino+ESP8266上传至oneNet云(文章粗劣)
  • [4] 【CSDN】超详细Arduino uno接入onenet云平台教程(TCP透传)
  • [5] 【B站】Arduino 利用ESP8266模块通过ONENET平台来实现远程控制


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

2.2 自动联网及接入设备

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

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

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

3.效果展示

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

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


参考资料

  • [1] Arduino_OneNET物联网三部曲(2)远程数据监控
  • [2] 【B站】Arduino ESP8266模块通过ONENET平台来实现远程控制(系列视频如下)
    在这里插入图片描述


附代码

ESP8266_EDP.ino

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

DHT11.cpp

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

DHT11.h

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

edp.c

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


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

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

在这里插入图片描述

数据转换

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

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

复制代码
1
2
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数组中。

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

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

关键代码

复制代码
1
2
sscanf(edp_command, "%[^:]:%s", datastr, val);

ESP8266_EDP.ino

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

2021.04.21 总结:

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

edp_command 等于

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

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

在这里插入图片描述

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

复制代码
1
2
sscanf(edp_command, "%[^:]:%s", datastr, val); //"%[^:]:%s" = switch:1

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

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

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

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

附:项目完整代码

ESP8266_EDP.ino文件

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

edp.c文件

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


DHT11.cpp文件

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

DHT11.h文件

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

HX711.cpp文件

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

HX711.h文件

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


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

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

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


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

最后

以上就是善良火车最近收集整理的关于Arduno + ESP8266模组运用中移OneNet物联网平台实现远程监控的全部内容,更多相关Arduno内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部