一.准备工作
1.1硬件
Arduino Mega2560*1
ESP8266-01*1
ESP8266-01模块的工作模式,固件烧录等都太麻烦。我们直接使用默认的固件和配置,使用透传(透明传输)来发送数据。
ESP8266-01的CH-PD,GPIO0,VCC三个引脚连接Arduino的3.3V;GND引脚连接Arduino的GND;UTXD,URXD分别连接Arduino mega2560的RX3,TX3(也就是数字口15,14)。
1.2软件
Arduino从OneNET平台请求数据和发送数据给OneNET平台类似,都是发送特定json格式数据,所以同样需要使用上一篇中提到的三个库。接收数据与发送数据的不同点在于,接收数据需要对OneNET平台返回的数据进行解析,提取出我们需要的值。
1.3平台
我们的远程控制也就是通过WiFi控制执行类元器件,比如远程开灯关灯。如下图所示,用户通过应用发送控制指令到OneNET服务器,Arduino则是每隔一段时间询问一次服务器有没有新指令,如果有新指令,服务器会把指令发送给Arduino板,这个时候Arduino板根据指令控制执行元件执行对应操作。
因为用户会通过应用发送控制指令到OneNET服务器,所以我们要在OneNET中新建对应数据流存储指令。因为我们的应用也是通过OneNET平台制作的,所以我们只要先创建一个数据流,然后在创建应用时把这个数据流绑定到组件上即可,具体创建方法在三部曲的第一篇里有详细介绍,这里就不再赘述。
二.Arduino数据处理
这里提供的同样是一个母版,只要WiFi名称,密码,设备ID,密匙替换即可接收数据。另外需要注意的是这个函数唯一一个需要修改的参数就是数据流的名称,这个名称是指我们在OneNET平台上关联了应用中组件的数据流的名称。
下面是在上一节基础上新建了一个control_data1的数据流,并且绑定到一个按钮组件上。
数据获取函数中已经对数据进行了处理,返回的是一个整数,把这个整数赋值给变量后,就可以通过变量控制LED,舵机,继电器等物品了。
#include
#include
#include
#define ESP8266Serail Serial3
#define Success 1U
#define Failure 0U
double data_receive;
HttpPacketHead packet;
unsigned long Time_Cont = 0;
const unsigned int esp8266RxBufferLength = 600;
char esp8266RxBuffer[esp8266RxBufferLength];
unsigned int ii = 0;
char OneNetServer[] = "api.heclouds.com";
const char ssid[] = "Rico_IOT";//这个地方替换为自己的wifi名称
const char password[] = "Rico666";//这个地方替换为自己的wifi密码
char device_id[] = "511234953";//这个地方替换为自己的设备ID
char API_KEY[] = "A2ORAeLeP2P=dc=";//这个地方要替换为自己的密匙
void setup() {
ESP8266Serail.begin(115200);
Timer1.initialize(1000);
Timer1.attachInterrupt(Timer1_handler);
initEsp8266();
Serial.begin(115200);
}
void loop() {
/*
* 下面的getDataFromOneNet(API_KEY, device_id, "control_data1")函数中
* "control_data1"是我们应用中组件绑定的数据流名称
*/
data_receive = getDataFromOneNet(API_KEY, device_id, "control_data1");
Serial.println(data_receive);
}
//下面的都不用改
int getDataFromOneNet(char * API_VALUE_temp, char * device_id_temp, char * sensor_id_temp) {
packet.setHostAddress(OneNetServer);
packet.setDevId(device_id_temp);
packet.setAccessKey(API_VALUE_temp);
packet.setDataStreamId(sensor_id_temp);
packet.createCmdPacket(GET, TYPE_DATASTREAM);
int httpLength = strlen(packet.content);
char cmd[400];
memset(cmd, 0, 400);
strcpy(cmd, "AT+CIPSTART=\"TCP\",\"");
strcat(cmd, OneNetServer);
strcat(cmd, "\",80\r\n");
if (sendCommand(cmd, "CONNECT", 10000, 5) == Success);
else ESP8266_ERROR(1);
clrEsp8266RxBuffer();
memset(cmd, 0, 400);
sprintf(cmd, "AT+CIPSEND=%d\r\n", httpLength);
if (sendCommand(cmd, ">", 3000, 1) == Success);
else ESP8266_ERROR(2);
clrEsp8266RxBuffer();
memset(cmd, 0, 400);
strcpy(cmd, packet.content);
if (sendCommand(cmd, "succ", 10000, 1) == Success);
else ESP8266_ERROR(3);
char * index1;
char * index2;
char getDataBuffer[10];
int getintData;
memset(getDataBuffer, 0, 10);
index1 = strstr(esp8266RxBuffer, "value\":");
index2 = strstr(index1, "},\"");
memcpy(getDataBuffer, index1 + 7, index2 - (index1 + 7));
sscanf(getDataBuffer, "%d", & getintData);
if (strlen(getDataBuffer) > 0)
return getintData;
else
return -1;
clrEsp8266RxBuffer();
if (sendCommand("AT+CIPCLOSE\r\n", "CLOSED", 3000, 1) == Success);
else ESP8266_ERROR(4);
clrEsp8266RxBuffer();
return 0;
}
void initEsp8266() {
if (sendCommand("AT\r\n", "OK", 1000, 10) == Success);
else ESP8266_ERROR(5);
clrEsp8266RxBuffer();
if (sendCommand("AT+CWMODE=1\r\n", "OK", 3000, 10) == Success);
else ESP8266_ERROR(7);
clrEsp8266RxBuffer();
char cmd[50];
strcpy(cmd, "AT+CWJAP=\"");
strcat(cmd, ssid);
strcat(cmd, "\",\"");
strcat(cmd, password);
strcat(cmd, "\"\r\n");
if (sendCommand(cmd, "OK", 20000, 10) == Success);
else ESP8266_ERROR(8);
clrEsp8266RxBuffer();
if (sendCommand("AT+CIPMUX=0\r\n", "OK", 3000, 10) == Success);
else ESP8266_ERROR(9);
clrEsp8266RxBuffer();
if (sendCommand("AT+CIFSR\r\n", "OK", 20000, 10) == Success);
else ESP8266_ERROR(10);
clrEsp8266RxBuffer();
}
void( * resetFunc)(void) = 0;
void ESP8266_ERROR(int num) {
while (1) {
if (sendCommand("AT\r\n", "OK", 100, 10) == Success) {
resetFunc();
}
}
}
unsigned int sendCommand(char * Command, char * Response, unsigned long Timeout, unsigned char Retry) {
clrEsp8266RxBuffer();
for (unsigned char n = 0; n < Retry; n++) {
ESP8266Serail.write(Command);
Time_Cont = 0;
while (Time_Cont < Timeout) {
esp8266ReadBuffer();
if (strstr(esp8266RxBuffer, Response) != NULL) {
return Success;
}
}
Time_Cont = 0;
}
return Failure;
}
void Timer1_handler(void) {
Time_Cont++;
}
void esp8266ReadBuffer() {
while (ESP8266Serail.available()) {
esp8266RxBuffer[ii++] = ESP8266Serail.read();
if (ii == esp8266RxBufferLength) clrEsp8266RxBuffer();
}
}
void clrEsp8266RxBuffer(void) {
memset(esp8266RxBuffer, 0, esp8266RxBufferLength);
ii = 0;
}