ESP8266 连接 OneNET 平台控制舵机:温度、湿度采集及数据发送
ESP8266 连接 OneNET 平台控制舵机:温度、湿度采集及数据发送
本教程使用 ESP8266 连接 OneNET 平台,实现温度、湿度采集并发送到云端,同时从 OneNET 获取命令控制舵机。
硬件准备
- Arduino 开发板
- ESP8266 模块
- DHT11 温度湿度传感器
- 舵机
- 跳线
软件准备
- Arduino IDE
- OneNET 平台账号
代码
#include 'ESP8266.h'
#include 'dht11.h'
#include 'SoftwareSerial.h'
#include<Servo.h>
//配置 ESP8266 WIFI 设置
#define SSID 'HONOR Play4T' //填写 2.4GHz 的 WIFI 名称,不要使用校园网
#define PASSWORD '12345678'//填写自己的 WIFI 密码
#define HOST_NAME 'api.heclouds.com' //API 主机名称,连接到 OneNET 平台,无需修改
#define DEVICE_ID '1099655073' //填写自己的 OneNET 设备 ID
#define HOST_PORT (80) //API 端口,连接到 OneNET 平台,无需修改
String APIKey = 'IiJSs17atNND2C77wumz03w63hw='; //与设备绑定的 APIKey
#define INTERVAL_SENSOR 5000 //定义传感器采样及发送时间间隔
//创建 dht11 示例
dht11 DHT11;
//创建舵机
Servo myservo;
int servoPin=7;
int light=0;
int servoPos=0;
//定义 DHT11 接入 Arduino 的管脚
#define DHT11PIN 4
//定义 ESP8266 所连接的软串口
/*********************
* 该实验需要使用软串口
* Arduino 上的软串口 RX 定义为 D3,
* 接 ESP8266 上的 TX 口,
* Arduino 上的软串口 TX 定义为 D2,
* 接 ESP8266 上的 RX 口.
* D3 和 D2 可以自定义,
* 但接 ESP8266 时必须恰好相反
*********************/
SoftwareSerial mySerial(3, 2);
ESP8266 wifi(mySerial);
void setup()
{
mySerial.begin(115200); //初始化软串口
Serial.begin(9600); //初始化串口
Serial.print('setup begin\r\n');
myservo.attach(servoPin);
myservo.write(0);
//以下为 ESP8266 初始化的代码
Serial.print('FW Version: ');
Serial.println(wifi.getVersion().c_str());
if (wifi.setOprToStation()) {
Serial.print('to station ok\r\n');
} else {
Serial.print('to station err\r\n');
}
//ESP8266 接入 WIFI
if (wifi.joinAP(SSID, PASSWORD)) {
Serial.print('Join AP success\r\n');
Serial.print('IP: ');
Serial.println(wifi.getLocalIP().c_str());
} else {
Serial.print('Join AP failure\r\n');
}
Serial.println('');
Serial.print('DHT11 LIBRARY VERSION: ');
Serial.println(DHT11LIB_VERSION);
mySerial.println('AT+UART_CUR=9600,8,1,0,0');
mySerial.begin(9600);
Serial.println('setup end\r\n');
}
unsigned long net_time1 = millis(); //数据上传服务器时间
void loop(){
if (net_time1 > millis())
net_time1 = millis();
if (millis() - net_time1 > INTERVAL_SENSOR) //发送数据时间间隔
{
int chk = DHT11.read(DHT11PIN);
Serial.print('Read sensor: ');
switch (chk) {
case DHTLIB_OK:
Serial.println('OK');
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println('Checksum error');
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println('Time out error');
break;
default:
Serial.println('Unknown error');
break;
}
float sensor_hum = (float)DHT11.humidity;
float sensor_tem = (float)DHT11.temperature;
Serial.print('Humidity (%): ');
Serial.println(sensor_hum, 2);
Serial.print('Temperature (oC): ');
Serial.println(sensor_tem, 2);
Serial.println('');
if (wifi.createTCP(HOST_NAME, HOST_PORT)) { //建立TCP连接,如果失败,不能发送该数据
Serial.print('create tcp ok\r\n');
char buf[10];
//拼接发送data字段字符串
String jsonToSend = '{\'Temperature\':';
dtostrf(sensor_tem, 1, 2, buf);
jsonToSend += '\'' + String(buf) + '\'';
jsonToSend += ',\'Humidity\':';
dtostrf(sensor_hum, 1, 2, buf);
jsonToSend += '\'' + String(buf) + '\'';
jsonToSend += ',\'light\':';
jsonToSend+= '\'' + String(light) + '\'';
jsonToSend += '}';
//拼接POST请求字符串
String postString = 'POST /devices/';
postString += DEVICE_ID;
postString += '/datapoints?type=3 HTTP/1.1';
postString += '\r\n';
postString += 'api-key:';
postString += APIKey;
postString += '\r\n';
postString += 'Host:api.heclouds.com\r\n';
postString += 'Connection:close\r\n';
postString += 'Content-Length:';
postString += jsonToSend.length();
postString += '\r\n';
postString += '\r\n';
postString += jsonToSend;
postString += '\r\n';
postString += '\r\n';
postString += '\r\n';
const char *postArray = postString.c_str(); //将str转化为char数组
Serial.println(postArray);
wifi.send((const uint8_t *)postArray, strlen(postArray)); //send发送命令,参数必须是这两种格式,尤其是(const uint8_t*)
Serial.println('send success');
if (wifi.releaseTCP()) { //释放TCP连接
Serial.print('release tcp ok\r\n');
} else {
Serial.print('release tcp err\r\n');
}
postArray = NULL; }//清空数组,等待下次传输数据
else {
Serial.print('create tcp err\r\n');
}
//控制舵机转动
Serial.println('');
net_time1 = millis();
}
//从 OneNET 获取命令并控制舵机
if (wifi.createTCP(HOST_NAME, HOST_PORT)) { //建立TCP连接
Serial.print('create tcp ok\r\n');
String getRequest = 'GET /cmds?device_id=';
getRequest += DEVICE_ID;
getRequest += ' HTTP/1.1';
getRequest += '\r\n';
getRequest += 'api-key:';
getRequest += APIKey;
getRequest += '\r\n';
getRequest += 'Host:api.heclouds.com\r\n';
getRequest += 'Connection:close\r\n';
getRequest += '\r\n';
const char *getRequestArray = getRequest.c_str(); //将str转化为char数组
wifi.send((const uint8_t *)getRequestArray, strlen(getRequestArray)); //send发送命令,参数必须是这两种格式,尤其是(const uint8_t*)
Serial.println('get cmd from OneNet');
Serial.println(getRequestArray);
char c;
String cmd = '';
while (wifi.available()) {
c = wifi.read();
cmd += c;
}
Serial.println(cmd);
if (cmd.indexOf('servo') != -1) { //如果收到的命令中包含“servo”,则控制舵机
int servoPos = cmd.substring(cmd.indexOf('servo') + 6, cmd.indexOf('servo') + 9).toInt(); //从命令字符串中提取舵机角度
Serial.println(servoPos);
myservo.write(servoPos); //控制舵机转动到指定角度
}
wifi.releaseTCP(); //释放TCP连接
getRequestArray = NULL; //清空数组,等待下次传输数据
} else {
Serial.print('create tcp err\r\n');
}
}
代码解析
- 引入头文件
#include 'ESP8266.h'
#include 'dht11.h'
#include 'SoftwareSerial.h'
#include<Servo.h>
- 配置 ESP8266 WIFI 设置
#define SSID 'HONOR Play4T' //填写 2.4GHz 的 WIFI 名称,不要使用校园网
#define PASSWORD '12345678'//填写自己的 WIFI 密码
#define HOST_NAME 'api.heclouds.com' //API 主机名称,连接到 OneNET 平台,无需修改
#define DEVICE_ID '1099655073' //填写自己的 OneNET 设备 ID
#define HOST_PORT (80) //API 端口,连接到 OneNET 平台,无需修改
String APIKey = 'IiJSs17atNND2C77wumz03w63hw='; //与设备绑定的 APIKey
- 定义传感器采样及发送时间间隔
#define INTERVAL_SENSOR 5000 //定义传感器采样及发送时间间隔
- 创建 dht11 示例
dht11 DHT11;
- 创建舵机
Servo myservo;
int servoPin=7;
int light=0;
int servoPos=0;
- 定义 DHT11 接入 Arduino 的管脚
#define DHT11PIN 4
- 定义 ESP8266 所连接的软串口
SoftwareSerial mySerial(3, 2);
ESP8266 wifi(mySerial);
- 初始化软串口和串口
void setup()
{
mySerial.begin(115200); //初始化软串口
Serial.begin(9600); //初始化串口
Serial.print('setup begin\r\n');
myservo.attach(servoPin);
myservo.write(0);
//以下为 ESP8266 初始化的代码
Serial.print('FW Version: ');
Serial.println(wifi.getVersion().c_str());
if (wifi.setOprToStation()) {
Serial.print('to station ok\r\n');
} else {
Serial.print('to station err\r\n');
}
//ESP8266 接入 WIFI
if (wifi.joinAP(SSID, PASSWORD)) {
Serial.print('Join AP success\r\n');
Serial.print('IP: ');
Serial.println(wifi.getLocalIP().c_str());
} else {
Serial.print('Join AP failure\r\n');
}
Serial.println('');
Serial.print('DHT11 LIBRARY VERSION: ');
Serial.println(DHT11LIB_VERSION);
mySerial.println('AT+UART_CUR=9600,8,1,0,0');
mySerial.begin(9600);
Serial.println('setup end\r\n');
}
- 读取传感器数据并发送到 OneNET
unsigned long net_time1 = millis(); //数据上传服务器时间
void loop(){
if (net_time1 > millis())
net_time1 = millis();
if (millis() - net_time1 > INTERVAL_SENSOR) //发送数据时间间隔
{
int chk = DHT11.read(DHT11PIN);
Serial.print('Read sensor: ');
switch (chk) {
case DHTLIB_OK:
Serial.println('OK');
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println('Checksum error');
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println('Time out error');
break;
default:
Serial.println('Unknown error');
break;
}
float sensor_hum = (float)DHT11.humidity;
float sensor_tem = (float)DHT11.temperature;
Serial.print('Humidity (%): ');
Serial.println(sensor_hum, 2);
Serial.print('Temperature (oC): ');
Serial.println(sensor_tem, 2);
Serial.println('');
if (wifi.createTCP(HOST_NAME, HOST_PORT)) { //建立TCP连接,如果失败,不能发送该数据
Serial.print('create tcp ok\r\n');
char buf[10];
//拼接发送data字段字符串
String jsonToSend = '{\'Temperature\':';
dtostrf(sensor_tem, 1, 2, buf);
jsonToSend += '\'' + String(buf) + '\'';
jsonToSend += ',\'Humidity\':';
dtostrf(sensor_hum, 1, 2, buf);
jsonToSend += '\'' + String(buf) + '\'';
jsonToSend += ',\'light\':';
jsonToSend+= '\'' + String(light) + '\'';
jsonToSend += '}';
//拼接POST请求字符串
String postString = 'POST /devices/';
postString += DEVICE_ID;
postString += '/datapoints?type=3 HTTP/1.1';
postString += '\r\n';
postString += 'api-key:';
postString += APIKey;
postString += '\r\n';
postString += 'Host:api.heclouds.com\r\n';
postString += 'Connection:close\r\n';
postString += 'Content-Length:';
postString += jsonToSend.length();
postString += '\r\n';
postString += '\r\n';
postString += jsonToSend;
postString += '\r\n';
postString += '\r\n';
postString += '\r\n';
const char *postArray = postString.c_str(); //将str转化为char数组
Serial.println(postArray);
wifi.send((const uint8_t *)postArray, strlen(postArray)); //send发送命令,参数必须是这两种格式,尤其是(const uint8_t*)
Serial.println('send success');
if (wifi.releaseTCP()) { //释放TCP连接
Serial.print('release tcp ok\r\n');
} else {
Serial.print('release tcp err\r\n');
}
postArray = NULL; }//清空数组,等待下次传输数据
else {
Serial.print('create tcp err\r\n');
}
//控制舵机转动
Serial.println('');
net_time1 = millis();
}
//从 OneNET 获取命令并控制舵机
if (wifi.createTCP(HOST_NAME, HOST_PORT)) { //建立TCP连接
Serial.print('create tcp ok\r\n');
String getRequest = 'GET /cmds?device_id=';
getRequest += DEVICE_ID;
getRequest += ' HTTP/1.1';
getRequest += '\r\n';
getRequest += 'api-key:';
getRequest += APIKey;
getRequest += '\r\n';
getRequest += 'Host:api.heclouds.com\r\n';
getRequest += 'Connection:close\r\n';
getRequest += '\r\n';
const char *getRequestArray = getRequest.c_str(); //将str转化为char数组
wifi.send((const uint8_t *)getRequestArray, strlen(getRequestArray)); //send发送命令,参数必须是这两种格式,尤其是(const uint8_t*)
Serial.println('get cmd from OneNet');
Serial.println(getRequestArray);
char c;
String cmd = '';
while (wifi.available()) {
c = wifi.read();
cmd += c;
}
Serial.println(cmd);
if (cmd.indexOf('servo') != -1) { //如果收到的命令中包含“servo”,则控制舵机
int servoPos = cmd.substring(cmd.indexOf('servo') + 6, cmd.indexOf('servo') + 9).toInt(); //从命令字符串中提取舵机角度
Serial.println(servoPos);
myservo.write(servoPos); //控制舵机转动到指定角度
}
wifi.releaseTCP(); //释放TCP连接
getRequestArray = NULL; //清空数组,等待下次传输数据
} else {
Serial.print('create tcp err\r\n');
}
}
注意事项
- 将代码中的 SSID、PASSWORD、DEVICE_ID 和 APIKey 替换为自己的信息。
- 确保 ESP8266 和 Arduino 之间的连接正确。
- 确保 DHT11 传感器连接到正确的管脚。
- 确保舵机连接到正确的管脚。
- 将 Arduino 开发板上传代码后,运行程序,观察串口输出信息,确保程序正常运行。
- 在 OneNET 平台上创建设备,并配置设备的 APIKey。
- 在 OneNET 平台上创建数据流,并将数据流与设备绑定。
- 在 OneNET 平台上创建命令,并将命令与设备绑定。
总结
本教程介绍了如何使用 ESP8266 连接 OneNET 平台,实现温度、湿度采集并发送到云端,同时从 OneNET 获取命令控制舵机。您可以根据自己的需要对代码进行修改,实现更多功能。
原文地址: https://www.cveoy.top/t/topic/oJXF 著作权归作者所有。请勿转载和采集!