打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Arduino ESP8266自动配网并上传温湿度、光照强度到OneNET
前言
    从接触ESP8266到现在有一段时间了,也感受到ESP8266的强大,其高性价比给极客者们带来了极大的福音。之前用ESP8266改装了一部遥控车,使其能用手机控制,手机app是用易安卓编制的,遥控车视频挂到b站了,视频地址:https://www.bilibili.com/video/av20141857?from=search&seid=10781143291446850224
    这次是打算用Arduino+ESP8266来实现智能配网以及通过EDP协议上传温度、湿度和光照强度等数据到OneNET平台,也可以用EDP下发命令来实现远程控制。
所需材料
    Arduino_pro_mini         1
    ESP8266-12F              1
     USB-TTL串口下载模块       1
    DHT11温湿度传感器        1
    面包板及杜板线           若干
    光敏电阻                 1
    电阻及发光二极管等       若干
智能配网(Smart Config
SmartConfig的过程:
    1wifi模块通电,没有可用的wifi, 进入混杂模式,开始监(和谐)听覆盖范围内所有WiFi数据帧
    2、手机APP或微信端发送包含WIFI用户名和WIFI密码的UDP广播包或者组播包;
    3、智能终端的WIFI芯片可以接收到该UDP包,只要知道UDP的组织形式,就可以通过接收到的UDP包解密出WIFI用户名和密码;
    4、然后智能硬件配置收到的WIFI用户名和密码到指定的WIFI AP(路由器)上。
    ESP8266可通过AT指令进入智能配网模式,我所用的AT固件是安信可推出的固件,可在安信可官网里http://wiki.ai-thinker.com/esp8266/sdk下载。配网的AT指令可参考安信可官网http://wiki.ai-thinker.com/esp8266/examples/at_demo里的步骤。通过将AT指令写在pro mini内,再通过外部按钮按下进入配网。
    pro mini通过软串口跟ESP8266通信,而ESP8266用的是3.3V电源,pro mini用的是5V电源,所以串口必须通过电平转换才行,由于身边暂时没有电平转换模块,所以只能通过分压来实现。经过实测,ESP8266跟pro mini软串口通信用115200波特率会出现乱码,所以只能用9600波特率。
    分压和配网按钮接线图如下所示:

 
程序如下:
  1. #include<SoftwareSerial.h> //使用软串口的库文件
  2. #define configkey 2 //配网按钮,按住时候配网
  3. #define configRED 7 //智能配网失败红灯亮起
  4. #define configGREEN 8 //智能配网成功绿灯亮起
  5. #define TcpLED 12 //OneNET的TCP连接灯
  6. #define EdpLED 6 //OneNET的EDP连接灯
  7. bool link; //判断智能配网是否成功
  8. bool keyOK=1; //判断配网按钮是否可用
  9. SoftwareSerial mySerial(10, 9); // RX, TX
  10. void setup() {
  11. mySerial.begin(9600);
  12. pinMode(configkey,INPUT); //设置按键引脚为输入
  13. pinMode(configRED,OUTPUT); //没连上无线网
  14. pinMode(configGREEN,OUTPUT); //连上无线网
  15. pinMode(TcpLED,OUTPUT); //连上OneNET的TCP
  16. pinMode(EdpLED,OUTPUT); //连上OneNET的EDP
  17. }
  18. void loop() {
  19. int buttonState = digitalRead(configkey);
  20. if(buttonState==0 && keyOK==1){ //按钮被按下时
  21.     mySerial.print('+++');
  22.     delay(100);
  23.     mySerial.print('+++');
  24.     delay(100);
  25.     digitalWrite(TcpLED, HIGH);
  26.     analogWrite(EdpLED,255);
  27.     digitalWrite(configGREEN, HIGH);
  28.      digitalWrite(configRED, HIGH);
  29.     while (!doCmdOk('AT+CWSTARTSMART=3', 'OK',5)); //启动智能配网
  30.     t1=0;
  31.     Serial.println('Smartconfig Start');
  32.     digitalWrite(testLED, HIGH);
  33.     while (!doConfigOK('smartconfig connected wifi'));
  34.     t1=0;
  35. if(link==1){
  36. Serial.println('do Config OK');
  37. digitalWrite(configGREEN, LOW);
  38. digitalWrite(testLED, LOW);
  39. while (!doCmdOk('AT+CIPSTART=\'TCP\',\'183.230.40.39\',876','CONNECT',5)); //OneNET的TCP透传
  40. t1=0;
  41. digitalWrite(TcpLED, LOW); //tcp连接指示灯亮
  42. Serial.println('TCP connect OK');
  43. while (!doCmdOk('AT+CIPMODE=1', 'OK',5)); //透传模式
  44. t1=0;
  45. while (!doCmdOk('AT+CIPSEND', '>',5)); //开始发送
  46. t1=0;
  47. link=1;
  48. edp_connect=0;
  49. keyOK=0;
  50. Serial.println('Start send');
  51. } else {
  52. Serial.println('do Config ERROR');
  53. digitalWrite(configRED, LOW);
  54. digitalWrite(testLED, LOW);
  55. }
  56. while (!doCmdOk('AT+CWSTOPSMART', 'OK',5)); //不管ESP8266有没有连上wifi,都要释放内存
  57. t1=0;
  58. }
等待串口命令结果函数
  1. booldoCmdOk(String data, char keyword[], int timeout){ //给ESP8266发送AT指令,在次数timeout范围内回应正确就返回TURE
  2. bool result = false;
  3. if (data != ''){
  4. mySerial.println(data); //发送AT指令
  5. Serial.print('SEND: ');
  6. Serial.println(data);
  7. }
  8. while (!mySerial.available()); // 等待模块回复
  9. delay(200);
  10. if (mySerial.find(keyword)){ //返回值判断
  11. Serial.println('do cmd OK');
  12. response=1;
  13. result = true;
  14. } else {
  15. Serial.println('do cmd ERROR');
  16. result = false;
  17. }
  18. while(mySerial.read()>= 0){} //清空串口接收缓存
  19. delay(800); //指令时间间隔
  20. t1++;
  21. if(t1>=timeout){ //超过设定时间,跳出循环,并返回回应判断response的值
  22. result = true;
  23. response=0;
  24. }
  25. return result;
  26. }
配网时等待串口回复函数
  1. booldoConfigOK(char keyword1[]){ //开启智能配网
  2. bool result1 = false;
  3. linktime=0;
  4. while (!mySerial.available()){ // 等待模块回复,10秒内要配网完成
  5. t1++;
  6. delay(1000);
  7. if(t1 >= 10){
  8. linktime=1;
  9. link=0;
  10. result1 = true;
  11. Serial.println('Config timeout');
  12. break; //超过时间串口没收到信号就跳出
  13. }
  14. }
  15. if(linktime==0){
  16. delay(200);
  17. if (mySerial.find(keyword1)){ //返回值判断
  18. link=1;
  19. result1 = true;
  20. } else {
  21. link=0;
  22. result1 = false;
  23. }
  24. while(mySerial.read()>= 0){} //清空串口接收缓存
  25. delay(500); //指令时间间隔
  26. }
  27. return result1;
  28. }
EDP连接
    通过OneNET官网的库文件edp.c,可以很简单的连接到OneNET平台。当成功连接到平台时,会收到0x20 0x02 0x00 0x00,可以用这个信号来判断是否连接上。
  1. if(link==1){ //当wifi连接上后,执行下面程序
  2. if (!edp_connect){
  3. while(mySerial.read()>= 0){} //清空串口接收缓存
  4. packetSend(packetConnect(ID, KEY)); //发送EPD连接包
  5. while (!mySerial.available()); //等待EDP连接应答
  6. delay(200);
  7. if ((tmp = mySerial.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0 ){
  8. rcvDebug(rcv_pkt.data, tmp);
  9. if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[1] == 0x02 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00)
  10. {
  11. edp_connect = 1;
  12. analogWrite(EdpLED,0);
  13. Serial.println('EDP connected.');
  14. }
  15. else
  16. Serial.println('EDP connect error.');
  17. }
  18. packetClear(&rcv_pkt);
  19. }
  20. }
光敏电阻
    光敏电阻通过分压,并通过模拟口A0输入到pro mini,接线电路图如下:
    通过分压后,读出的值在0~1024之间,数值越大,说明光线约弱,有点不太直观,于是我用个简单的函数将数值控制在0~100之间,并且数值越大,光线约强。
  1. #define lightread A0 //光敏电阻读取的数值
  2. ld_x=analogRead(lightread); //光敏电阻接收的信号,信号是模拟值
  3. ld=(4490-4*ld_x)/49;
温湿度传感器
    温湿度传感器DHT11接线如下图所示:
  1. #include <dht11.h> //使用DHT11的库文件
  2. #define DHT11PIN A1 //DHT11温湿度模块数值
  3. int wd;      //温度
  4. int sd;      //湿度
  5. int chk = DHT11.read(DHT11PIN); //读DHT11
  6. wd = (float)DHT11.temperature; //获取温度
  7. sd = (float)DHT11.humidity; //获取湿度
上传数据到OneNET平台
  1. if (edp_connect && trigger){
  2. Serial.print('temperature : '); Serial.println(wd); //串口打印温度
  3. Serial.print('humidity : '); Serial.println(sd); //串口打印湿度
  4. Serial.print('LigthRead_x : '); Serial.println(ld_x); //串口打印亮度(读值)
  5. Serial.print('LigthRead_y : '); Serial.println(ld); //串口打印亮度(计算值)
  6. Serial.println(' ');
  7. sprintf(wd1,'%d',wd); //int型转换char型
  8. sprintf(sd1,'%d',sd); //int型转换char型
  9. sprintf(ld1,'%d',ld); //int型转换char型
  10. packetSend(packetDataSaveTrans(NULL, 'tem', wd1)); //发送的数据必须为字符串
  11. delay(100);
  12. packetSend(packetDataSaveTrans(NULL, 'hum', sd1));
  13. delay(100);
  14. packetSend(packetDataSaveTrans(NULL, 'light', ld1));
  15. delay(2000);
  16. }
EDP下发控制命令
    在OneNET平台开发者中心创建应用,在元件库里拉出一个开关按钮。按钮的EDP命令内容填datastr:{V}
    接收EDP命令并解析的程序:
  1. while(mySerial.available()){
  2. readEdpPkt(&rcv_pkt);
  3. if (isEdpPkt(&rcv_pkt)){
  4. pkt_type = rcv_pkt.data[0];
  5. switch (pkt_type){
  6. case CMDREQ:
  7. char edp_command[50];
  8. char edp_cmd_id[40];
  9. long id_len, cmd_len, rm_len;
  10. char datastr[20];
  11. char val[10];
  12. memset(edp_command, 0,sizeof(edp_command)); //置0
  13. memset(edp_cmd_id, 0,sizeof(edp_cmd_id)); //置0
  14. edpCommandReqParse(&rcv_pkt,edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len); //按照EDP命令请求协议,解析数据
  15. Serial.print('rm_len: ');
  16. Serial.println(rm_len, DEC);
  17. delay(10);
  18. Serial.print('id_len: ');
  19. Serial.println(id_len, DEC);
  20. delay(10);
  21. Serial.print('cmd_len: ');
  22. Serial.println(cmd_len, DEC);
  23. delay(10);
  24. Serial.print('id: ');
  25. Serial.println(edp_cmd_id);
  26. delay(10);
  27. Serial.print('cmd: ');
  28. Serial.println(edp_command);
  29. sscanf(edp_command,'%[^:]:%s', datastr, val);
  30. if (atoi(val) == 1){ //atoi(),int转换为char,把一个整数转换为字符串。
  31. Serial.println('LEDon'); // 使Led亮
  32. digitalWrite(testLED, HIGH);
  33. }
  34. else if(atoi(val) == 0){
  35. Serial.println('LEDoff'); // 使Led灭
  36. digitalWrite(testLED, LOW);
  37. }
  38. packetSend(packetDataSaveTrans(NULL,datastr,val)); //将新数据值上传至数据流
  39. break;
  40. default:
  41. Serial.print('unknown type:');
  42. Serial.println(pkt_type, HEX);
  43. break;
  44. }
  45. }
  46. }
最后的接线图:
电脑端界面:
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
新手求救...arduino 的RX/TX串口收发端口只能有一对吗?
串口透传(SerialApp)的数据发送过程
如何实现智能家居系统的设计?
Arduino IDE for ESP8266教程(二)软AP以及一些网络相关的设置 | 风之工房
ESP8266/ESP32 SmartConfig一键配网+自动重连+微信扫码配网
ESP8266WiFi连接
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服