zoukankan      html  css  js  c++  java
  • 【Arduino】、Arduino+ESP8266上传至oneNet云

    一、硬件简介

      1. Arudino 是一种开源的电子平台,该平台最初主要基于AVR单片机的微控制器和相应的开发软件,包含硬件(各种型号的Arduino板)和软件(Arduino IDE)。

      

      2. ESP8266 是深圳安信可科技有限公司开发的基于乐鑫ESP8266的超低功耗的UART-WIFI模块的模组,可以方便进行二次元开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。

    二、硬件接线

      1. 所用到的硬件有:Arudino Mega 2560, ESP8266-12F.

      2. 接线如下表所示

      

    Arduino ESP8266
    3.3V  VCC
    GND GND
    RXD TXD
    TXD RXD

    三、硬件编程

      1.  ESP8266 芯片接收的AT指令顺序

    • AT: 发送 AT 指令判断供电,TTL和WIFI模块是否正常 返回OK表示正常
    • AT+ CWMODE=?  : 发送 AT+CWMODE=? 指令 选择模式 1.Station模式,2. AP 模式, 返回字节中有OK表示连接成功
    • AT+CWJAP="ssid","password" : 发送 AT+CWJAP="ssid","password" 来连接AP 返回字节中有CONNECT表示连接成功
    • AT+CIPSTART="TCP","hostServer",hostPort : 链接服务器, 返回OK表示连接成功
    • AT+CIPSEND=dataLen :向服务器发送数据,dataLen表示HTTP的请求的长度,返回> 表示发送成功,继续发送数据
    • data : 向服务器发送数据
    • AT+CIPCLOSE: 关闭请求链接,返回CLOSED表示断开连接

      2. 程序代码

      

      1 /**
      2  *
      3  */
      4 #include <TimerOne.h>
      5 #include <HttpPacket.h>
      6 #include <ArduinoJson.h>
      7 /**'
      8  * ESP8266 采用串口3通讯
      9  */
     10 #define ESP8266Serial Serial3
     11 #define mySerial Serial
     12 
     13 #define RES_MAX_LENGTH 500
     14 
     15 #define SEND_SUCCESS 1
     16 #define SEND_FAIL 0
     17 
     18 /**
     19 * 链接的AP的账户密码
     20 */
     21 char ssid[] = "zlei";
     22 char pass[] = "18829237005";
     23 
     24 /**
     25  * Onenet 互联网信息
     26  */
     27 char oneNetServer[] = "api.heclouds.com";       //不需要修改
     28 char deviceId[] = "10005241";
     29 char API_KEY[] = "qB40IZOP6Rx58EZ7ow16mA=VkRQ=";
     30 char sensorID1[] = "waterLevel";
     31 
     32 
     33 // ESP8266于Arduino交互的数据缓存
     34 char ESP8266Response[RES_MAX_LENGTH];
     35 
     36 // 交互数据缓存的世纪存储长度
     37 int resLength = 0;
     38 
     39 // 请求时间计算的最小分度值
     40 const unsigned long interval = 1000;
     41 
     42 // 计时器,以毫秒为最小计数单位
     43 unsigned long curTime = 0;
     44 
     45 HttpPacketHead packet;
     46 void setup() {
     47   ESP8266Serial.begin(115200);
     48   mySerial.begin(9600);
     49 
     50   Timer1.initialize(interval);
     51   Timer1.attachInterrupt(timeClock);
     52   intiESP8266();
     53 
     54 }
     55 
     56 void loop() {
     57   postDataToServer(API_KEY,deviceId,sensorID1,1.00); // 发送数据(数据为模拟数据)
     58   delay(10000);
     59 }
     60 
     61 /**
     62 * 制造重启命令
     63 */
     64 void(* resetFunc) (void) = 0;
     65 
     66 /**
     67  * ESP8266 板子进行初始化
     68  * 1. 发送 AT 指令判断供电,TTL和WIFI模块是否正常 返回OK表示正常
     69  * 2. 发送 AT+CWMODE=? 指令 选择模式 1.Station模式,2. AP 模式
     70  * 3. 发送 AT+CWJAP="ssid","password" 来连接AP
     71  */
     72 void intiESP8266(){
     73   
     74   // AT 指令, 返回OK表明供电,TTL和WIFI模块通讯正常
     75   if(sendATCommead("AT
    ","OK", 1000, 2) == SEND_SUCCESS );
     76   else ESP8266_Error(1);
     77   delay(100);
     78   // AT+CWMODE=? 选择模式 1.Station模式,2. AP 模式
     79   if(sendATCommead("AT+CWMODE=1
    ","OK",1000,3) == SEND_SUCCESS );
     80   else ESP8266_Error(2);
     81 
     82   // AT+CWJAP="sid","pass" 加入AP
     83   char cwjap[50];
     84   strcat(cwjap,"AT+CWJAP="");
     85   strcat(cwjap,ssid);
     86   strcat(cwjap,"","");
     87   strcat(cwjap,pass);
     88   strcat(cwjap,""
    ");
     89   if(sendATCommead(cwjap,"OK",2000,4) == SEND_SUCCESS );
     90   else ESP8266_Error(3);
     91 }
     92 
     93 /**
     94  * ESP8266 错误信息处理
     95  * @param type 错误信息类型
     96  */
     97 void ESP8266_Error(int type){
     98   mySerial.println("ERROR");
     99   mySerial.println(type);
    100   while(1){
    101     if(sendATCommead("AT
    ","OK", 1000, 2) == SEND_SUCCESS){
    102       mySerial.print("
    RESET!!!!!!
    ");
    103       resetFunc();
    104     }
    105   }
    106 }
    107 
    108 /**
    109  * Arduino 向ESP8266中发送AT指令
    110  * @param commoned 需要发送的指令
    111  * @param response 发送之后接收到response之后表示成功
    112  * @param timeout 在发送命令之后 timeout 毫秒之后重新发送消息
    113  * @param reTry 重新发送的次数
    114  */
    115 unsigned int sendATCommead(char *commoned, char *response, int timeout, unsigned char reTry){
    116 
    117   // 多次重复发送消息,直到接收到消息。
    118   for(unsigned char tryTime = 0; tryTime < reTry; tryTime++){
    119     clearResponse(); // 清理接收缓存
    120     mySerial.print("send commoned ");
    121     mySerial.print(commoned);
    122     mySerial.print(" to ESP8266.
    ");
    123     ESP8266Serial.write(commoned); // 通过串口发送命令
    124     curTime = 0;
    125     
    126     // 在延时范围内查看回复消息,如果回复消息成功,返回成功
    127     while(curTime < timeout){
    128       readResponse();
    129       if(strstr(ESP8266Response, response) != NULL){
    130           mySerial.println("Response is ");
    131           mySerial.println("-------------- Response Start ----------------");
    132           mySerial.println(ESP8266Response);
    133           mySerial.println("-------------- Response end ------------------");
    134           return SEND_SUCCESS;
    135       }
    136     }
    137   }
    138   // 发送失败
    139   mySerial.print("response received, content is 
     >>>> ");
    140   mySerial.println(ESP8266Response);
    141   return SEND_FAIL;
    142 }
    143 
    144 /**
    145  * 向服务器发送数据请求
    146  * @param apiKey 访问网站的apiKey
    147  * @param deviceID 设备ID
    148  * @param sensorID 传感器ID
    149  * @param data 发送的数据
    150  */
    151 void postDataToServer(char *apiKey, char *deviceID, char *sensorID, double data){
    152   StaticJsonBuffer<400> jsonBuffer;
    153 
    154   JsonObject &value = jsonBuffer.createObject();
    155   value["value"] = data;
    156 
    157   JsonObject &idDataPoints = jsonBuffer.createObject();
    158   idDataPoints["id"] = sensorID;
    159   JsonArray &dataPoints = idDataPoints.createNestedArray("dataPoints");
    160   dataPoints.add(value);
    161 
    162   JsonObject &myJson = jsonBuffer.createObject();
    163   JsonArray &dataStreams = myJson.createNestedArray("dataStreams");
    164   dataStreams.add(idDataPoints);
    165 
    166   // 设置POST的请求表头
    167   char postData[400];
    168   int postLength = myJson.printTo(postData, sizeof(postData));
    169   
    170   packet.setHostAddress(oneNetServer);
    171   packet.setDevId(deviceId);
    172   packet.setAccessKey(API_KEY);
    173 
    174   packet.createCmdPacket(POST, TYPE_DATAPOINT, postData);
    175 
    176   int httpLength = strlen(packet.content) + postLength;
    177   
    178   char cmd[500];
    179   // 链接服务器
    180   memset(cmd, 0, 500);
    181   sprintf(cmd, "AT+CIPSTART="TCP","%s",80
    ",oneNetServer);
    182   if(sendATCommead(cmd,"CONNECT", 3000, 5) == SEND_SUCCESS);
    183   else ESP8266_Error(4);
    184 
    185   // 发送数据
    186   memset(cmd,0,500);
    187   sprintf(cmd, "AT+CIPSEND=%d
    ",httpLength);
    188   if(sendATCommead(cmd,">",3000,3) == SEND_SUCCESS);
    189   else ESP8266_Error(5);
    190 
    191   memset(cmd,0,500);
    192   strcpy(cmd,packet.content);
    193   strcat(cmd,postData);
    194   if(sendATCommead(cmd,"succ"}",5000,5) == SEND_SUCCESS);
    195   else ESP8266_Error(6);
    196 
    197   if(sendATCommead("AT+CIPCLOSE
    ","CLOSED",3000,3) == SEND_SUCCESS);
    198   else ESP8266_Error(7);
    199 }
    200 
    201 /**
    202  * @TODO 将ESP8266返回的数据返回到缓存数组中
    203  * 1. 清理缓存数据
    204  * 2. 将读取的数据存入全局数组中
    205  * 3. 超出数组长度之后
    206  */
    207 void readResponse(){
    208   clearResponse();
    209   while(ESP8266Serial.available()){
    210     ESP8266Response[resLength++] = ESP8266Serial.read();
    211     if(resLength == RES_MAX_LENGTH) clearResponse();
    212   }
    213 }
    214 
    215 /**
    216  * @todo 清理数据交互缓存区
    217  */
    218 void clearResponse(){
    219   memset(ESP8266Response,0,RES_MAX_LENGTH);
    220   resLength = 0;
    221 }
    222 
    223 /**
    224  * 计时器函数,单位为毫秒
    225  */
    226 void timeClock(){
    227   curTime++;
    228 }

      

  • 相关阅读:
    C基础之移位操作
    实现itoa()
    Python的time模块的clock方法在不同平台的效果不同
    __stdcall与__cdecl之区别浅析及相关知识
    Python 字典 dictionary changed size during iteration
    Windows下printf输出long long类型
    inotify也会爆棚
    一条对“失控的腾讯帝国:企鹅无法把控手机市场”的评论
    imfunny程序员的增量发展
    程序员第一定律:关于技能和收入
  • 原文地址:https://www.cnblogs.com/zleiblogs/p/7208566.html
Copyright © 2011-2022 走看看