Arduino+ESP8266上传至oneNet云

2023-11-07

一、硬件简介

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

/**
 *
 */
#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++;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Arduino+ESP8266上传至oneNet云 的相关文章

  • 为什么存在 async 关键字

    浏览 msdn 9 频道视频时 我发现以下未答复的评论 希望有人能解释一下 我不明白 async 关键字的意义 为什么不直接允许 任何时候方法返回任务时都会使用await关键字 就像迭代器一样 可以在任何返回 IEnumerable 的方法
  • 如何使用 zlib 制作 .zip 文件

    我正在阅读zlib的文档 它相当详细 但我读到了这一行 输出数据将位于zlib格式 与 gzip 或zip formats http www zlib net zlib how html http www zlib net zlib how
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • 在 C# Winforms 应用程序中嵌入 Windows XP 主题

    我有一个旧版 C Windows 窗体应用程序 其布局是根据 Windows XP 默认主题设计的 由于需要将其作为 Citrix 应用程序进行分发 该应用程序现在看起来像经典主题应用程序 因为 Citrix 不鼓励使用主题系统服务 所以
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • 如何生成 appsettings..json 文件?

    我有一个 ASP NET Core 2 WebAPI 它将部署在以下环境中 INT QA STAGE 生产环境 基于上述 我需要有appsettings
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • 2D morton 码编码/解码 64 位

    如何将给定 x y 的莫顿代码 z 顺序 编码 解码为 32 位无符号整数 生成 64 位莫顿代码 反之亦然 我确实有 xy2d 和 d2xy 但仅适用于 16 位宽的坐标 产生 32 位莫顿数 在网上查了很多 但没有找到 请帮忙 如果您可
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • C# 中的常量和只读? [复制]

    这个问题在这里已经有答案了 可能的重复 const 和 readonly 之间有什么区别 https stackoverflow com questions 55984 what is the difference between cons
  • 从 R 到 C 处理列表并访问它

    我想使用从 R 获得的 C 列表 我意识到这个问题与此非常相似 使用 call 在 R 和 C 之间传递数据帧 https stackoverflow com questions 6658168 passing a data frame f
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

    我的应用程序中有一个网页 需要调用我设置的 Web 服务来返回对象列表 这个调用是这样设置的 document ready function var response ajax type POST contentType applicati
  • 使用 iTextSharp 5.3.3 和 USB 令牌签署 PDF

    我是 iTextSharp 和 StackOverFlow 的新手 我正在尝试使用外部 USB 令牌在 C 中签署 PDF 我尝试使用从互联网上挖掘的以下代码 Org BouncyCastle X509 X509CertificatePar
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题

随机推荐