Arduino+ESP8266上传至oneNet云

26 篇文章 5 订阅
本文介绍了如何使用Arduino Mega 2560与ESP8266-12F模块的硬件连接,详细讲解了ESP8266的AT指令编程流程,并分享了实际操作中的关键代码。通过实例展示了物联网设备如何通过WiFi连接云端进行远程控制。
摘要由CSDN通过智能技术生成

一、硬件简介

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

  

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

二、硬件接线

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

  2. 接线如下表所示

  

ArduinoESP8266
3.3V VCC
GNDGND
RXDTXD
TXDRXD

三、硬件编程

  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. 程序代码

/**
 *
 */
#include <TimerOne.h>
#include <HttpPacket.h>
#include <ArduinoJson.h>
/**'
 * ESP8266 采用串口3通讯
 */
#define ESP8266Serial Serial3
#define mySerial Serial

#define RES_MAX_LENGTH 500

#define SEND_SUCCESS 1
#define SEND_FAIL 0

/**
* 链接的AP的账户密码
*/
char ssid[] = "zlei";
char pass[] = "18829237005";

/**
 * Onenet 互联网信息
 */
char oneNetServer[] = "api.heclouds.com";       //不需要修改
char deviceId[] = "10005241";
char API_KEY[] = "qB40IZOP6Rx58EZ7ow16mA=VkRQ=";
char sensorID1[] = "waterLevel";


// ESP8266于Arduino交互的数据缓存
char ESP8266Response[RES_MAX_LENGTH];

// 交互数据缓存的世纪存储长度
int resLength = 0;

// 请求时间计算的最小分度值
const unsigned long interval = 1000;

// 计时器,以毫秒为最小计数单位
unsigned long curTime = 0;

HttpPacketHead packet;
void setup() {
  ESP8266Serial.begin(115200);
  mySerial.begin(9600);

  Timer1.initialize(interval);
  Timer1.attachInterrupt(timeClock);
  intiESP8266();

}

void loop() {
  postDataToServer(API_KEY,deviceId,sensorID1,1.00); // 发送数据(数据为模拟数据)
  delay(10000);
}

/**
* 制造重启命令
*/
void(* resetFunc) (void) = 0;

/**
 * ESP8266 板子进行初始化
 * 1. 发送 AT 指令判断供电,TTL和WIFI模块是否正常 返回OK表示正常
 * 2. 发送 AT+CWMODE=? 指令 选择模式 1.Station模式,2. AP 模式
 * 3. 发送 AT+CWJAP="ssid","password" 来连接AP
 */
void intiESP8266(){

  // AT 指令, 返回OK表明供电,TTL和WIFI模块通讯正常
  if(sendATCommead("AT\r\n","OK", 1000, 2) == SEND_SUCCESS );
  else ESP8266_Error(1);
  delay(100);
  // AT+CWMODE=? 选择模式 1.Station模式,2. AP 模式
  if(sendATCommead("AT+CWMODE=1\r\n","OK",1000,3) == SEND_SUCCESS );
  else ESP8266_Error(2);

  // AT+CWJAP="sid","pass" 加入AP
  char cwjap[50];
  strcat(cwjap,"AT+CWJAP=\"");
  strcat(cwjap,ssid);
  strcat(cwjap,"\",\"");
  strcat(cwjap,pass);
  strcat(cwjap,"\"\r\n");
  if(sendATCommead(cwjap,"OK",2000,4) == SEND_SUCCESS );
  else ESP8266_Error(3);
}

/**
 * ESP8266 错误信息处理
 * @param type 错误信息类型
 */
void ESP8266_Error(int type){
  mySerial.println("ERROR");
  mySerial.println(type);
  while(1){
    if(sendATCommead("AT\r\n","OK", 1000, 2) == SEND_SUCCESS){
      mySerial.print("\r\nRESET!!!!!!\r\n");
      resetFunc();
    }
  }
}

/**
 * Arduino 向ESP8266中发送AT指令
 * @param commoned 需要发送的指令
 * @param response 发送之后接收到response之后表示成功
 * @param timeout 在发送命令之后 timeout 毫秒之后重新发送消息
 * @param reTry 重新发送的次数
 */
unsigned int sendATCommead(char *commoned, char *response, int timeout, unsigned char reTry){

  // 多次重复发送消息,直到接收到消息。
  for(unsigned char tryTime = 0; tryTime < reTry; tryTime++){
    clearResponse(); // 清理接收缓存
    mySerial.print("send commoned ");
    mySerial.print(commoned);
    mySerial.print(" to ESP8266.\n");
    ESP8266Serial.write(commoned); // 通过串口发送命令
    curTime = 0;

    // 在延时范围内查看回复消息,如果回复消息成功,返回成功
    while(curTime < timeout){
      readResponse();
      if(strstr(ESP8266Response, response) != NULL){
          mySerial.println("Response is ");
          mySerial.println("-------------- Response Start ----------------");
          mySerial.println(ESP8266Response);
          mySerial.println("-------------- Response end ------------------");
          return SEND_SUCCESS;
      }
    }
  }
  // 发送失败
  mySerial.print("response received, content is \n >>>> ");
  mySerial.println(ESP8266Response);
  return SEND_FAIL;
}

/**
 * 向服务器发送数据请求
 * @param apiKey 访问网站的apiKey
 * @param deviceID 设备ID
 * @param sensorID 传感器ID
 * @param data 发送的数据
 */
void postDataToServer(char *apiKey, char *deviceID, char *sensorID, double data){
  StaticJsonBuffer<400> jsonBuffer;

  JsonObject &value = jsonBuffer.createObject();
  value["value"] = data;

  JsonObject &idDataPoints = jsonBuffer.createObject();
  idDataPoints["id"] = sensorID;
  JsonArray &dataPoints = idDataPoints.createNestedArray("dataPoints");
  dataPoints.add(value);

  JsonObject &myJson = jsonBuffer.createObject();
  JsonArray &dataStreams = myJson.createNestedArray("dataStreams");
  dataStreams.add(idDataPoints);

  // 设置POST的请求表头
  char postData[400];
  int postLength = myJson.printTo(postData, sizeof(postData));

  packet.setHostAddress(oneNetServer);
  packet.setDevId(deviceId);
  packet.setAccessKey(API_KEY);

  packet.createCmdPacket(POST, TYPE_DATAPOINT, postData);

  int httpLength = strlen(packet.content) + postLength;

  char cmd[500];
  // 链接服务器
  memset(cmd, 0, 500);
  sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",80\r\n",oneNetServer);
  if(sendATCommead(cmd,"CONNECT", 3000, 5) == SEND_SUCCESS);
  else ESP8266_Error(4);

  // 发送数据
  memset(cmd,0,500);
  sprintf(cmd, "AT+CIPSEND=%d\r\n",httpLength);
  if(sendATCommead(cmd,">",3000,3) == SEND_SUCCESS);
  else ESP8266_Error(5);

  memset(cmd,0,500);
  strcpy(cmd,packet.content);
  strcat(cmd,postData);
  if(sendATCommead(cmd,"succ\"}",5000,5) == SEND_SUCCESS);
  else ESP8266_Error(6);

  if(sendATCommead("AT+CIPCLOSE\r\n","CLOSED",3000,3) == SEND_SUCCESS);
  else ESP8266_Error(7);
}

/**
 * @TODO 将ESP8266返回的数据返回到缓存数组中
 * 1. 清理缓存数据
 * 2. 将读取的数据存入全局数组中
 * 3. 超出数组长度之后
 */
void readResponse(){
  clearResponse();
  while(ESP8266Serial.available()){
    ESP8266Response[resLength++] = ESP8266Serial.read();
    if(resLength == RES_MAX_LENGTH) clearResponse();
  }
}

/**
 * @todo 清理数据交互缓存区
 */
void clearResponse(){
  memset(ESP8266Response,0,RES_MAX_LENGTH);
  resLength = 0;
}

/**
 * 计时器函数,单位为毫秒
 */
void timeClock(){
  curTime++;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值