授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷

一、你如果想学基于Arduino的ESP8266开发技术

一、基础篇

  1. ESP8266开发之旅 基础篇① 走进ESP8266的世界
  2. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境
  3. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明
  4. ESP8266开发之旅 基础篇④ ESP8266与EEPROM
  5. ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
  6. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

二、网络篇

  1. ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
  2. ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
  3. ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
  4. ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
  5. ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
  6. ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
  7. ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
  8. ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
  9. ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
  10. ESP8266开发之旅 网络篇⑩ UDP服务
  11. ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
  12. ESP8266开发之旅 网络篇⑫ 域名服务——ESP8266mDNS库
  13. ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 Flash文件系统
  14. ESP8266开发之旅 网络篇⑭ web配网
  15. ESP8266开发之旅 网络篇⑮ 真正的域名服务——DNSServer
  16. ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新

三、应用篇

  1. ESP8266开发之旅 应用篇① 局域网应用 ——炫酷RGB彩灯
  2. ESP8266开发之旅 应用篇② OLED显示天气屏
  3. ESP8266开发之旅 应用篇③ 简易版WiFi小车

四、高级篇

  1. ESP8266开发之旅 进阶篇① 代码优化 —— ESP8266内存管理
  2. ESP8266开发之旅 进阶篇② 闲聊Arduino IDE For ESP8266配置
  3. ESP8266开发之旅 进阶篇③ 闲聊 ESP8266 Flash
  4. ESP8266开发之旅 进阶篇④ 常见问题 —— 解决困扰
  5. ESP8266开发之旅 进阶篇⑤ 代码规范 —— 像写文章一样优美
  6. ESP8266开发之旅 进阶篇⑥ ESP-specific APIs说明

1.理论基础

    参考博主线上博文:

  • 玩转OneNET物联网平台之简介
  • ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用

2.OneNet HTTP

    Http协议作为常用网络协议,其为短连接协议(这里不讲解HTTP协议,请读者自行查阅资料),在OneNet平台上也同样支持。

设备侧适用特点

  • 只上报传感器数据到平台
  • 无需下行控制质量到设备

平台侧提供功能

  • 存储设备上报的数据点;
  • 提供API接口实现设备管理;
  • 提供数据推送到应用;

典型适用场景

  • 简单数据上报场景,比如温湿度控制系统等传感器检测类项目;

3.模拟上传温度

3.1 实验材料

  • ESP8266 NodeMcu
  • OneNet平台

3.2 实验步骤

3.2.1 创建 温湿度系统-HTTP 产品(HTTP协议)

注意点

  • 务必选择HTTP协议

    创建完毕后,我们点击查看具体的产品信息:

注意点

  • 需要记录产品ID,其用来区分产品唯一标识符
  • Master-APIkey,网络请求鉴权信息,接口调用需要带入

3.2.2 API调试创建 deviceA

API接口定义

操作步骤

  • 通过API调试工具创建deviceA

http body

{
    "title": "http_device_A",
    "desc": "http_device_A",
    "tags": ["china", "mobile"],
    "location": {
        "lon": 109,
        "lat": 23.54
    },
    "auth_info": "http_device_A",
    "other": {
        "version": "1.0.0",
        "manufacturer": "china mobile"
    }
}
  • 查看设备列表

3.2.3 API调试模拟上传温度 —— deviceA

API接口定义

操作步骤

  • 通过API调试工具发送请求

  • 查看操作结果

3.2.4 NodeMcu烧录代码 —— deviceA

    为了明确区分代码功能,博哥命名工程名为P_OneNet_Exam02:

  • P_OneNet_Exam02.ino文件:
/**
 *  功能:ESP8266 HTTP 远程上传温度值 V1.0
 *  作者:单片机菜鸟
 *  时间:2019-06-27
 *  描述:
 *      1.OneNet平台端:创建Http协议的产品,创建DeviceA设备点
 *      2.每个20s上传一个随机值给到OneNet平台
*/

#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <stdlib.h>
#include <Ticker.h>
#include "H_project.h"

void initSystem();
void wifiTick();
void postTempToOneNet();

/**
 * 初始化
 */
void setup() {
  initSystem();
}

void loop() {
  ESP.wdtFeed();
  wifiTick();
  doTCPClientTick();
  postTempToOneNet();
}

/**
 * 初始化系统
 */
void initSystem(){
    int cnt = 0;
    Serial.begin (115200);
    Serial.println("\r\n\r\nStart ESP8266 HTTP");
    Serial.print("Firmware Version:");
    Serial.println(VER);
    Serial.print("SDK Version:");
    Serial.println(ESP.getSdkVersion());
    wifi_station_set_auto_connect(0);//关闭自动连接
    ESP.wdtEnable(5000);
    WiFi.disconnect();
    delay(100);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          cnt++;
          Serial.print(".");
          if(cnt>=40){
            cnt = 0;
            //重启系统
            delayRestart(1);
          }
    }
    pinMode(LED_BUILTIN, OUTPUT);
}

/*
*  WiFiTick
*  检查是否需要初始化WiFi
*  检查WiFi是否连接上,若连接成功启动TCP Client
*  控制指示灯
*/
void wifiTick(){
  static bool taskStarted = false;
  static bool ledTurnon = false;
   if ( WiFi.status() != WL_CONNECTED ) {
       if (millis() - lastWiFiCheckTick > 1000) {
         lastWiFiCheckTick = millis();
         ledState = !ledState; digitalWrite(LED_BUILTIN, ledState);
         ledTurnon = false;
       }
    }else{
       if (ledTurnon == false) {
             ledTurnon = true;
             digitalWrite(LED_BUILTIN, 0);
        }

        if (taskStarted == false) {
             taskStarted = true;
             startTCPClient();
        }
    }
}

/**
 * 检查client连接
 */
void doTCPClientTick(){
   //检查是否断开,断开后重连
   if(WiFi.status() != WL_CONNECTED) return;
   if (!client.connected()) {//断开重连
      if(preTCPConnected == true){
            preTCPConnected = false;
            preTCPStartTick = millis();
            Serial.println();
            Serial.println("TCP Client disconnected.");
            client.stop();
       }else if(millis() - preTCPStartTick > 10*1000){
            startTCPClient();
       }
   }
}

/**
 * 启动Tcp client
 */
void startTCPClient(){
   Serial.println("\r\nstartTCPClient");
  if(client.connect(host, 80)){
      preTCPConnected = true;
      client.setNoDelay(true);
  }else{
      Serial.print("Failed connected to server:");
      Serial.println(host);
      client.stop();
      preTCPConnected = false;
  }
  preTCPStartTick = millis();
}

/**
 * 提交数据到OneNet
 */
void postTempToOneNet(){
   if(WiFi.status() != WL_CONNECTED || !client.connected()) return;
   if(millis() - lastOneNetPostTick > 15*1000){
       lastOneNetPostTick = millis();
       Serial.println("TCP Client postTempToOneNet.");

       StaticJsonBuffer<230> jsonBuffer;
       //创建根,也就是顶节点
       JsonObject& root = jsonBuffer.createObject();
       //在root对象中加入data数组
       JsonArray& datastreams = root.createNestedArray("datastreams");
       JsonObject& stream = datastreams.createNestedObject();
       stream["id"] = "temperature";
       JsonArray& datapoints = stream.createNestedArray("datapoints");
       JsonObject& value1 = datapoints.createNestedObject();
       value1["value"] =  random(20, 50);
       JsonObject& value2 = datapoints.createNestedObject();
       value2["value"] =  random(20, 50);

       int len = root.measureLength();
       char buffer[100];
       root.printTo(buffer, 100);
       String data;
       for(int index = 0;index<len;index++){
           data += buffer[index];
       }
       postToDeviceDataPoint(data);
   }
}
  • H_project.h 代码:
#ifndef _MAIN_H__
#define _MAIN_H__

extern "C" {
#include "user_interface.h"
#include "smartconfig.h"
}

/************** ESP8266相关操作 **************************/
void delayRestart(float t);
void delayNs(uint8_t m);
/*********************************************************/

/******************** Http 相关操作 **********************/
const unsigned long HTTP_TIMEOUT = 5000;// max respone time from server
const size_t MAX_CONTENT_SIZE = 500;// max size of the HTTP response

WiFiClient client;
char response[MAX_CONTENT_SIZE];
char endOfHeaders[] = "\r\n\r\n";

bool sendGetRequest(const char* host,String url,String header,char* response);
bool sendPostRequest(const char* host,String url,String header,String postData,char* response);
bool skipResponseHeaders();
void readReponseContent(char* content, size_t maxSize);
void clearResponseBuffer(char* response);
/*********************************************************/

/*************** OneNet HTTP相关操作 *********************/
const char* host = "api.heclouds.com";
bool postToDeviceDataPoint(String data);
/*********************************************************/

/*********************** 项目相关操作 ********************/
#define VER             "HTTP_TEMP_V1.0"
const char* ssid = "TP-LINK_5344";//wifi账号
const char* password = "xxxxxx";//wifi秘密
const unsigned long BAUD_RATE = 115200;// serial connection speed
unsigned long lastWiFiCheckTick = 0;
bool ledState = 0;
unsigned long lastOneNetPostTick=0;
unsigned long preTCPStartTick=0;
bool preTCPConnected=false;
/*********************************************************/

#endif

    全部工程代码,博哥放在个人QQ群里。

注意点

  • 这里用到了JSON,请参考博哥上线博文 玩转ArduinoJson库 V5版本
  • 我们这里使用到了ESP8266 WiFiClient来封装Http请求(也可以直接使用HttpClient库),为了加深理解,请读者参考博哥上线博文 ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client 关于client部分;

    把工程烧进NodeMcu,然后可以看到串口打印内容,如下:

    同时,也可以在OneNet平台看到数据流情况,如下:

4.总结

在理解HTTP协议的基础上,本篇是非常容易操作的。但是读者也需要关注几点:

  • 创建自己的OneNet产品,不要用博哥创建的(请在博哥源码基础上修改自己的产品信息);
  • 可以尝试加入优化代码,比如温度值不变,是否考虑不上传,或者加大上传间隔,也或者加入睡眠模式

下一篇,博哥将讲解 玩转OneNET物联网平台之HTTP服务② —— 模拟上传温度(HttpClient)。

最新文章

  1. Unity学习疑问记录之触屏
  2. 看懂UML类图
  3. 擦掉STM32F429芯片上的数据的一个方法
  4. grunt配置太复杂?使用Qbuild进行文件合并、压缩、格式化等处理
  5. .net如何实现时间相减得到天数
  6. iOS App 转移
  7. Qt学习之自定义窗口部件
  8. Entity Framework 并发处理
  9. Shuffle&#39;m Up
  10. UIView和CALayer有什么关系
  11. opencv之haar特征+AdaBoos分类器算法流程(二)
  12. Kafka单机版安装(CentOS 7环境下)
  13. github windows pycharm 设置
  14. Exp2 后门原理与实践-------20164325王晓蕊
  15. flask_mail发送163邮件,报553错误的原因
  16. python 将一个JSON 字典转换为一个Python 对象
  17. 更改MySQL数据库目录位置[zz]
  18. 服务器返回的json数据中含有null的处理方法
  19. rar ubuntu
  20. android解决AVD中文路径无法启动问题

热门文章

  1. 《Maven实战》读书笔记
  2. 1、Spark 2.1 源码编译支持CDH
  3. Loadrunner录制步骤及说明
  4. App的功能测试要点
  5. 暑期——第四周总结(Ubuntu系统安装新版eclipse双击无法打开问题 【已解决】)
  6. 网关鉴权后下游统一filter获取用户信息
  7. ASP.NET 服务端接收Multipart/form-data文件
  8. Spring 梳理-el表达式和jstl
  9. Spring 梳理-bean作用域
  10. CSS div仿table样式