赞
踩
OneNET定位为PaaS服务,即在物联网应用和真实设备之间搭建高效、稳定、安全的应用平台:面向设备,适配多种网络环境和常见传输协议,提供各类硬件终端的快速接入方案和设备管理服务;面向应用层,提供丰富的API和数据分发能力以满足各类行业应用系统的开发需求,使物联网企业可以更加专注于自身应用的开发,而不用将工作重心放在设备接入层的环境搭建上,从而缩短物联网系统的形成周期,降低企业研发、运营和运维成本。
物联网是把生活中各种物品通过各种元器件,传感器等连接在一起的网络。这个网络具备观察性和可控性,我们可以通过这个网络知道其中各个物品的状态,同时可以控制他们。
物联网可以分为三层,感知层、网络层、应用层。其中感知层可以通过传感器,执行器等元器件与环境进行互动。网络层指起到数据存储于管理功能的那一部分,其可以把各种数据按照特定标准进行存储,便于应用层调取。应用层是用户与网络层的接口,一方面把数据以特定形式展现给用户,一方面存储用户的指令,以备感知层调用。
OneNET平台具备网络层和应用层的功能,它可以把Arduino传感器采集的数据存储在自己的服务器上,同时可以在设计应用的时候调用这些数据。
OneNET平台是中国移动开发的物联网平台,稳定性非常好,上手容易。
使用方法:
1)进入OneNET官网(“https://open.iot.10086.cn/”)注册账号
2)注册完成后在首页右上角点击「开发者中心」进入产品开发界面
小提示:零基础入,建议先别去网络上找找乱七八糟的文章学习,直接参考官方文档一步一步走就没那么多问题了。遇到实际问题后首先根据官方文档以及网上资料去解决。官方文档:【首页】-【服务与支持】- 【开发文档】- 【快速入门】
2.1 创建产品
进入产品开发界面后,选择左侧菜单栏中【全部产品】-【基础服务】。基础服务中有:
【多协议接入】-【HTTP】-【添加产品】
添加产品时,填写产品相关信息
2.2 创建设备
创建产品后,点击左上角 【OneNet】 回到首页,单击进入产品 【HTTP】
OneNet上在项目下还有设备的概念,一个设备就相当于一块Arduino板。单击【设备列表】-【添加备】,在弹出的设备信息里可以随便填,对后面没有影响,唯一需要注意的是数据保密性这里,建议选择私有,如果选择公开,那后面你把这个项目发布的时候别人就能看的你的数据了。填完后单击添加即可完成创建。
选择【设备列表】-【添加设备】
【添加新设备】 - 设置设备名称、设备编号后,点击确认即可。
2.3 新建数据流
Arduino发送给OneNET平台的数据可能有很多种,比如温度,湿度,光照强度等等。我们需要在OneNET上建立「变量」来存储这些数据,在OneNET上我们把这种变量叫做“ 数据流 ”。单击【数据流模板】-【添加数据流模板】,填入数据流名称即可得到一个存储数据的数据流。
2.4 创建应用
有了数据之后,我们需要把数据以一种特定形式呈现出来,比如用一个温度计显示实时温度,以一个折线图显示一段时间的温度趋势。肩负展示数据功能的是“应用”,就像我们平时在手机的“应用商店”里下载的那种应用一样,上面会有图标,图片等等。我们依次单击选择【应用管理】-【添加应用】
设置应用相关信息:名称、logo等。
添加应用后,进入编辑应用界面如下:
设置应用界面组件以及组件的属性:
查看应用有两种方法:
参考资料
1.1 硬件
ESP8266-01S | Arduno Uno |
---|---|
VCC&EN | 3.3V |
GND | GND |
RX | TX (D1) |
TX | RX(D0) |
DHT11 | Arduno Uno |
---|---|
VCC | 3.3V /5V |
GND | GND |
OUT | D3 |
1.2 软件
Arduino 通过 ESP8266-01S 发送数据给 OneNet 平台的数据。ESP8266-01S 属于 安信可公司的产品,我们需要下载官网的安信可串口调试助手 查看返回的数据。
1.3 平台
OneNet服务器里有很多项目很多设备,具体把数据发到拿呢?
实际上OneNet平台对于发送过来的Json数据是有一定格式要求的,其中除了要传输的数据,还包含了设备ID、密匙,这样就可以保证数据发送到正确的设备。
在正式开始前,我们需要记录设备的ID和密匙。设备ID可通过单击【设备列表】可在设备前面看到设备ID、密匙,在APIKey这一列的就是密匙。
597420765
vutzlt=cl9B99vnsozQcKSRSkNs=
(进入【设备列表】- 【设备详情】路径添加APIKey)另外,还需要自家的WiFi账号与密码接入网络。
补充:按照前文的方法对 OneNet平台设置:创建产品(多协议接入 - edp)、创建设备、新建数据流(数据流的名称要与程序中的一致)、添加应用(注意开关控件的属性设置"switch:{V}")
2.1 ESP8266-01S AT指令手动联网
- /***************************************************
- *
- * 名称: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指令写进程序让程序自动帮我们发送,并且链接到云平台,还要再实现设备和脚本的关联。
- 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
安信可串口调试助手
实验过程中,一开始用的Arduino Nano 开发板,但后来可能因为开发板质量或接线的把板子烧坏了,电脑识别不了设备,于是我换了一块官网的Arduino Uno 正版开发板!
OneNet 移动终端「设备云」效果界面展示,实现温湿度显示、开关控件控制pin13 板载 LED 的亮灭。
参考资料
附代码
ESP8266_EDP.ino
- /***********************************************************
- 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
- /*
- 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
- /*
- /*
- 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
-
- /*
- 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",整数);
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
- /***********************************************************
- 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
等于
灯 | 状态 | EDP命令 |
---|---|---|
除菌 | 开 | switch:1 |
除菌 | 关 | switch:0 |
照明 | 开 | switch:2 |
照明 | 关 | switch:3 |
关键代码一:sscanf () 函数 数据转换的运用
sscanf(edp_command, "%[^:]:%s", datastr, val); //"%[^:]:%s" = switch:1
关键代码二:设置控制灯引脚
- pinMode(13, OUTPUT); // WIFI模块指示灯
- pinMode(12, OUTPUT); // 用于连接EDP控制的发光二极管
关键代码三:判断edp命令 控制对应的灯
- //本例中格式为 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
文件
- /***********************************************************
- 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
文件
-
- /*
- 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
文件
- /*
- 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
文件
-
- /*
- 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
文件
- #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
文件
- #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博客文章一键转载插件
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。