Esp8266开发物联网小工具(一)

目标

我们将通过ESP8266连接Thinkphp开发的接收API,将DHT11温度传感器获取到的环境温度、湿度等数据实时发送至服务器,用户可通过设备和OLED触摸屏的实时数据界面查看实时环境温度。

硬件准备:

1)ESP8266-13 WIFI电路板

2)DHT11温湿度传感器

3)0.96”OLED(我使用的版本主控芯片是SSD1306、四线制SPI)

4)USB插座和5v至3.3V稳压器

5)USB-TTL串口下载模块

开发软件

arduino IDE

接下来我来介绍一下我们本次项目使用的控制器ESP8266

简介(来自官方)

  • 乐鑫智能互联平台ESP8266EX拥有高性能无线SOC,给移动平台
    设计师带来福音,它以最低成本提供最大实用性,为WiFi功能嵌入
    其他系统提供无限可能。

  • ·ESP8266EX是一个完整且自成体系的WiFi网络解决方案,能够
    立运行,也可以作为从机搭载于其他主机MCU运行。ESP8266EX
    在搭载应用并作为设备中唯一的应用处理器时,能够直接从外接闪存
    中启动。内置的高速缓冲存储器有利于提高系统性能,并减少内存需
    求。

  • 另外一种情况是,ESP8266EX负责无线上网接入承担WiFi适配器(网卡使用)
    的任务时,可以将其添加到任何基于微控制器的设计中,连接简单易
    行,身需通过SPI/SDIO接口或|2C/UART口即可。

    性能

    • 802.11b/g/n
    • 内置低功耗32位CPU:可以兼作应用处理器
    • 内置10bit,高精度ADC
    • 内置TCP/管协议栈
    • 内置TR开关、balun、LNA、功率放大器和匹配网络
    • 内置PLL、稳压器和电源管理组件
    • 支持天线分集
    • STBC、1×1MIMO、2×1 MIMO
    • A-MPDU、A-MSDU的聚合和0.4s的保护间隔
    • [email protected],支持WPAWPA2安全模式
    • 支持STA/AP/STA+AP工作模式
    • 支持 Smart Config 功能(包括Android和iOS设备)
    • SDIO 2.0、(H)SPI、UART、I2C、12S、IR Remote Control、PWM、GPIO
    • 深度睡眠保持电流为10uA,关断电流小于5uA
    • 2ms 之内唤醒、连接并传递数据包
    • 802.11b模式下+20dBm的输出功率
    • 待机状态消耗功率小于1.0mW(DTIM3)
    • 工作温度范围:-40℃-125℃
    • 模细通过CC,CE,TELEC,WiFi Alliance及 SRRC认证

在这里插入图片描述

简要介绍一下这个ESP8266,它一共有三种工作模式,AP模式,STA模式,AP+STA模式,每种模式的使用情况介绍如下图:

img

接下来我来介绍一下我们本次项目使用的传感器DHT11温湿度传感器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E0qeg5MX-1593946859904)(https://techtutorialsx.files.wordpress.com/2016/04/dht11.png?w=197&h=153)]

DHT11可以测量温度和湿度,是简单环境监测项目的理想选择。它的温度分辨率为1ºC,相对湿度为1%。它的温度范围在0ºC到50ºC之间,湿度的测量范围取决于温度(您可以查看数据表中的详细信息)。

OLED

OLED,即有机发光二极管(OrganicLight-Emitting Diode),又称为有机电激光显示(OrganicElectroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从2003 年开始,这种显示设备在MP3播放器上得到了广泛应用,而对于同属数码类产品的DC 与手机,此前只是在一些展会上展示过采用OLED 屏幕的工程样品。自2007 年后,寿命得到很大提高,具备了许多LCD 不可比拟的优势。

Esp8266开发物联网小工具(一)_第1张图片

接线

ESP8266 DHT11 OLED
GPIO_05 信号引脚
GPIO_14 SCL
GPIO_02 SDA

下面我们开始配置Arduino IDE使其支持ESP8266的开发

如前所述,我们假设使用Arduino IDE对ESP8266进行编程。如果您尚未将其配置为支持ESP8266板。Arduino有一些库可以简化我们与DHT11还有OLED的交互的任务。一个非常简单易用且与ESP8266配合使用的是Simple DHT传感器库OLED则是u8g2。可以通过Arduino IDE Library Manager轻松安装这两个库。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tg3qy3tw-1593946859916)(https://techtutorialsx.files.wordpress.com/2016/04/dht11-esp8266-library1.png?w=640)]

温湿度获取编程:

要导入新安装的库,请在代码顶部添加以下include:

#include 

同时使用GPIO引脚的编号声明一个全局变量,以便于更改。在这种情况下,我们将使用GPIO5:

int DHTpin = 5;

要允许将数据发送到计算机,请在设置功能中启动串行连接:

Serial.begin(115200);

声明两个字节变量,一个用于温度,另一个用于湿度:

byte temperature;

byte humidity;

我们使用字节变量,因为DHT11在温度和湿度方面只有8位分辨率。

最后,在主循环函数中,读取值并通过串口发送它们:

if (simple_dht11_read(DHTpin, &temperature, &humidity, NULL)) {

   Serial.print("Failed.");

}else {

   Serial.print("温度: "); Serial.print(temperature); Serial.println("ºC");

   Serial.print("湿度: "); Serial.print(humidity); Serial.println("%");

}

delay(500);

打开Arduino IDE的串行监视器,应该会看到类似于图4的内容。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FPQdcSUe-1593946859922)(https://techtutorialsx.files.wordpress.com/2016/04/esp8266-dht11-readings.png?w=640)]

到这里我们就完成了ESP8266对温湿度的获取程序,下一步我们来点亮我们的OLED屏幕

#include 
#include 

#ifdef U8X8_HAVE_HW_SPI
#include 
#endif
#ifdef U8X8_HAVE_HW_I2C
#include 
#endif

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ D2, /* data=*/ D1, /* reset=*/ U8X8_PIN_NONE);   // 此处 D1 D2是对应焊接的脚针

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.clearBuffer();                    // clear the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr);    // choose a suitable font
  u8g2.drawStr(0,10,"Hello World!");    // write something to the internal memory
  u8g2.sendBuffer();                    // transfer internal memory to the display
  delay(1000);  
}

下载程序后是不是屏幕上出现了Hello World!呢?好奇心严重的小宝宝可能发现了这代码没法显示中文啊!!!!

下面我们来修改代码让他显示中文

/*
esp8266+oled显示屏
显示汉字项目
论坛地址:bbskali.cn
博客:blog.bbskali.cn
*/

#include 
#include 

#ifdef U8X8_HAVE_HW_SPI
#include 
#endif
#ifdef U8X8_HAVE_HW_I2C
#include 
#endif



U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ D2, /* data=*/ D1, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display


void setup(void) {
  u8g2.begin();
  u8g2.enableUTF8Print();        // enable UTF8 support for the Arduino print() function
}

void loop(void) {
  u8g2.setFont(u8g2_font_unifont_t_chinese2);  // use chinese2 for all the glyphs of "你好世界"
  u8g2.setFontDirection(0);
  u8g2.clearBuffer();
  u8g2.setCursor(0, 15);
  u8g2.print("你好世界");
  u8g2.setCursor(0, 30);
  u8g2.print("你好世界");        // Chinese "Hello World" 

  u8g2.sendBuffer();

  delay(1000);
}

到这里我们的OLED得编码工作也到了最后一步了,发送HTTP-post请求到我们的API。

#include 
#include 

const char* ssid = "##设置能上网的wifi的名称##";      // wifi名
const char* password = "##wifi密码##";  // wifi密码

const char* host = "api.heclouds.com";  // 连接的主机域名
const int httpsPort = 443;  // https端口
String url = "";  // 请求的页面地址(后面代码中进行拼接)

String API_KEY = "##填写自己OneNet平台里的OneNet的api key##";  // onenet的 api key
String deviceId = "##OneNet里设备的ID##";    // onenet的 设备ID
String dataId = "led";    // 任意设置的数据名

void connectWifi();
void postDataToOnenet(float data);

void setup() {
  Serial.begin(115200);
}

void loop() {
  float data = 314;
  postDataToOnenet(data);
  delay(3000);
}

/**
 * 连接wifi
 */
void connectWifi(){
    Serial.println();
    Serial.print("connecting to ");
    Serial.println(ssid);

  WiFi.mode(WIFI_STA);    // 设置wifi模式
  WiFi.begin(ssid, password);   // 连接wifi
  while (WiFi.status() != WL_CONNECTED) { //判断连接状态
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

  Serial.print("requesting URL: ");
  Serial.println(url);

  // 发送POST请求
  // 组拼url地址
  url = "/devices/" + deviceId + "/datapoints";
  // 组拼HTTPS请求的Header
  String jsonStr = String("") + "{'datastreams':[{" +
            "'id':'" + dataId + "'" +
            ",'datapoints':[{" +
            "'value':" + data +
            "}]}]}";
  String getStr = String("POST ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: arduino\r\n" +
               "api-key:" + API_KEY + "\r\n" +
               "Connection: close\r\n";
  client.print(getStr);   // 发送Headers头
  client.print(String("") + "Content-Length:" + jsonStr.length() + "\r\n\r\n"); // 发送Header头-数据内容长度(注意:\r\n\r\n是结尾)
  client.print(jsonStr);  // 发送json数据

  Serial.println("request sent");

  Serial.println("==========");
  Serial.println("send was:");
  Serial.println(jsonStr);   // 打印发送的请求数据
  String line = client.readStringUntil('\n');
  Serial.println("reply was:");
  Serial.println(line);   // 打印接受到的数据
  Serial.println("==========");
###### }

到这里我们基础的小功能就都开发完成了!!!

下面我们进行最后一步将我们之前的代码整合到一起完成我们的想dome。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

String url = "192.168.199.228:5000";  // 请求的页面地址(后面代码中进行拼接)
const char* host = "192.168.199.228";  // 连接的主机域名
const int httpsPort = 5000;  // https端口


String API_KEY = "123";  //  api key
String dataId = "07140401";    // 任意设置的数据名

#define USE_SERIAL Serial
#ifdef U8X8_HAVE_HW_SPI
#include 
#endif
#ifdef U8X8_HAVE_HW_I2C
#include 
#endif
#define SCL 14
#define SDA 2
#ifndef STASSID
#define STASSID "************"
#define STAPSK  "************"
#endif
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
ESP8266WiFiMulti WiFiMulti;
int pinDHT11 = 5;
SimpleDHT11 dht11(pinDHT11);
byte temperature;
byte humidity;
const char *ssid = STASSID;
const char *password = STAPSK;

ESP8266WebServer server(80);

const int led = 13;

void handleRoot() {
  digitalWrite(led, 1);
  char temp[400];
  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;

  snprintf(temp, 400,

           "\
  \
    \
    ESP8266 Demo\
    \
  \
  \
    

这里是ESP8266!

\

运行时间: %02d:%02d:%02d

\ \ \ "
, hr, min % 60, sec % 60 ); server.send(200, "text/html", temp); digitalWrite(led, 0); } void handleNotFound() { digitalWrite(led, 1); String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); digitalWrite(led, 0); } void setup(void) { u8g2.begin();//oled初始化 u8g2.enableUTF8Print(); //初始换OLED中文语言类库 u8g2.setFont(u8g2_font_wqy15_t_chinese2); //设置中文字体 u8g2.setFontDirection(0); u8g2.clearBuffer();// 清除内存 u8g2.setCursor(0, 15);//设置写入位置 u8g2.print("系统启动中"); u8g2.sendBuffer();// 将内存传输到显示器 delay(100); pinMode(led, OUTPUT); digitalWrite(led, 0); Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); u8g2.setFontDirection(0); u8g2.clearBuffer();// 清除内存 u8g2.setCursor(0, 15);//设置写入位置 u8g2.print("网络连接中"); u8g2.sendBuffer();// 将内存传输到显示器 Serial.print("网络连接失败"); } Serial.println(""); Serial.print("接入WiFi名称:"); Serial.println(ssid); Serial.print("获取IP地址"); u8g2.setFontDirection(0); u8g2.clearBuffer();// 清除内存 u8g2.setCursor(0, 15);//设置写入位置 u8g2.print("IP地址为:"); u8g2.setCursor(0, 40); u8g2.print(WiFi.localIP()); u8g2.sendBuffer();// 将内存传输到显示器 delay(500); Serial.println(WiFi.localIP()); if (MDNS.begin("esp8266")) { Serial.println("MDNS服务启动成功"); } server.on("/", handleRoot); server.on("/test.svg", drawGraph); server.on("/inline", []() { server.send(200, "text/plain", "this works as well"); }); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP服务启动成功"); } void loop(void) { server.handleClient(); MDNS.update(); ws(); } void ws() { int err = SimpleDHTErrSuccess; if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) { Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000); return; } u8g2.setFontDirection(0); u8g2.clearBuffer();// 清除内存 u8g2.setCursor(0, 15);//设置写入位置 u8g2.print("温度"); u8g2.print((int)temperature); postData(temperature,"温度"); u8g2.print(" *C, "); u8g2.setCursor(0, 40); u8g2.print("湿度"); u8g2.print((int)humidity); postData(humidity,"湿度"); u8g2.print(" H"); u8g2.sendBuffer();// 将内存传输到显示器 Serial.print("Sample OK: "); Serial.print((int)temperature); Serial.print(" *C, "); Serial.print((int)humidity); Serial.println(" H"); delay(1500); } void drawGraph() { String out = ""; char temp[100]; out += "\n"; out += "\n"; out += "\n"; int y = rand() % 130; for (int x = 10; x < 390; x += 10) { int y2 = rand() % 130; sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); out += temp; y = y2; } out += "\n\n"; server.send(200, "image/svg+xml", out); } void postData(float data,String type){ // Use WiFiClientSecure class to create TLS connection WiFiClient client; // HTTP //WiFiClientSecure client; // HTTPS Serial.print("connecting to "); Serial.println(host); if (!client.connect(host, httpsPort)) { // 判断连接情况 Serial.println("connection failed"); return; } Serial.print("requesting URL: "); Serial.println(url); // 发送POST请求 // 组拼url地址 //url = "/devices/" + deviceId + "/datapoints"; // 组拼HTTPS请求的Header String jsonStr = String("") + "{'"+type+"':[{" + "'id':'" + dataId + "'" + ",'data':[{" + "'value':" + data + "}]}]}"; String getStr = String("POST ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: arduino\r\n" + "api-key:" + API_KEY + "\r\n" + "Connection: close\r\n"; client.print(getStr); // 发送Headers头 client.print(String("") + "Content-Length:" + jsonStr.length() + "\r\n\r\n"); // 发送Header头-数据内容长度(注意:\r\n\r\n是结尾) client.print(jsonStr); // 发送json数据 Serial.println("request sent"); Serial.println("=========="); Serial.println("send was:"); Serial.println(jsonStr); // 打印发送的请求数据 String line = client.readStringUntil('\n'); Serial.println("reply was:"); Serial.println(line); // 打印接受到的数据 Serial.println("=========="); }

到这里我们的硬件全部工作都已经完成了,接下来我们使用Thinkphp写一个简单的api来接收ESP8266发送的信息吧!

你可能感兴趣的:(熊本猫,物联网,智能家居)