admin 管理员组

文章数量: 887021


2023.03.27
添加ESP8266获取DHT11的代码,增加日期时间信息内容

/*
    本程序实现的功能:
    1)从NTP服务器获取日期时间;
    2)获取DHT11传感器的温湿度数值
    3)通过WiFi客户端每隔一定时间将日期时间、温湿度数据发送至远端服务器
    4)通过SSD1306 OLED显示温湿度数值
*/
#include <NTPClient.h>  //安装NTP库
#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include "DHTesp.h"     // 安装ESP DHT库
// 安装ESP8266 and ESP32 OLED driver for SSD1306 displays库
#include <Wire.h>               // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h"        // legacy: #include "SSD1306.h"

#ifdef ESP32
#pragma message(THIS EXAMPLE IS FOR ESP8266 ONLY!)
#error Select ESP8266 board.
#endif

#ifndef STASSID
#define STASSID "WiFi名称"
#define STAPSK "密码"
#endif
// 初始化SSD1306 OLED
SSD1306Wire display(0x3c, 2, 14);   // ADDRESS, SDA, SCL

DHTesp dht;
const char* ssid = STASSID;
const char* password = STAPSK;
uint8 count = 0;
char temp[8];  // 存储温度值字符串
char hum[8];   // 存储湿度值字符串
const char* host = "106.52.100.218"; //服务器IP
const uint16_t port = 30003;        // 端口
// NTP时间
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP,"ntp1.aliyun",60*60*8); //北京时区UTC+8
// 转换时间
String formattedDate(unsigned long epochTime) {
    time_t t = epochTime;
    char str[50] = {0};
    strftime(str, sizeof(str), "%Y-%m-%d %T", localtime(&t));
    return str;
}

void setup() {
  // 串口初始化
  Serial.begin(115200);

  // OLED初始化
  display.init();

  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  
  // 启动ntp
  timeClient.begin();
  
  // DHT11 初始化
  dht.setup(5, DHTesp::DHT11); // Connect DHT11 sensor to GPIO 5
  
  // 连接WiFi网络
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
     would try to act as both a client and an access-point and could cause
     network-issues with your other WiFi-devices on your WiFi-network. */
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

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

void loop() {

  // 从DHT11传感器获取温湿度
  delay(dht.getMinimumSamplingPeriod());
  float humidity = dht.getHumidity();
  dtostrf(humidity,2,2,hum);
  
  float temperature = dht.getTemperature();
  // This will send a string to the server
  dtostrf(temperature,2,2,temp);

  // 更新NTP
  timeClient.update();
  String datetime = formattedDate(timeClient.getEpochTime());
//  Serial.println(datetime);
  // SSD1306展示
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 0, datetime); // 显示日期时间
  display.setFont(ArialMT_Plain_16);
  display.drawString(0, 15, "Temp:");
  display.drawString(56, 15, temp);
  display.drawCircle(101, 17, 2);
  display.drawString(103, 15, "C");
  display.setFont(ArialMT_Plain_16);
  display.drawString(0, 41, "Humi:");
  display.drawString(56, 41, hum);
  display.drawString(100, 41, "%");
  display.display();
  count += 1;
  if (count==10)  // 间隔20s发送一次
  {
    count = 0;
    // 使用WiFiClient创建TCP连接
    Serial.print("connecting to ");
    Serial.print(host);
    Serial.print(':');
    Serial.println(port);
    WiFiClient client;
    if (!client.connect(host, port)) {
      Serial.println("connection failed");
      delay(5000);
      return;
    }
    Serial.println(" -> Sending data to server");
    // 向远端服务器发送传感器数据
    String msg = String(datetime) + ", " + "Temperature: " + String(temp)+ String("°C, ") + "Humidity: " + String(hum) + "%";
    if (client.connected()) { client.println(msg); }
    Serial.println(msg);
  }
  // 延时
  delay(1000);
}

2021-06-18
将程序简单用freertos封装了一下,代码地址:

https://gist.github/ouening/17102d05fe5957292bf550bb18610f6a


ESP32代码:

#include <WiFi.h>
#include <WiFiClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
/* change ssid and password according to yours WiFi*/
const char* ssid     = "网络名称";
const char* password = "密码";
/*
 * This is the IP address of your PC
 * [Wins: use ipconfig command, Linux: use ifconfig command]
*/
const char* host = "公网服务器地址";
const int port = 8088;

/* 设置DHT11 */
#define DHTPIN 4     // Digital pin connected to the DHT sensor 
#define DHTTYPE    DHT11     // DHT 11

DHT_Unified dht(DHTPIN, DHTTYPE);

void setup()
{

    Serial.begin(115200);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    /* connect to your WiFi */
    WiFi.begin(ssid, password);
    /* wait until ESP32 connect to WiFi*/while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected with IP address: ");
    Serial.println(WiFi.localIP());

    /* ====== 初始化DHT11 ========*/
    dht.begin();
    Serial.println(F("DHTxx Unified Sensor Example"));
    // Print temperature sensor details.
    sensor_t sensor;
    dht.temperature().getSensor(&sensor);
    Serial.println(F("------------------------------------"));
    Serial.println(F("Temperature Sensor"));
    Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
    Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
    Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
    Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
    Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
    Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
    Serial.println(F("------------------------------------"));
    // Print humidity sensor details.
    dht.humidity().getSensor(&sensor);
    Serial.println(F("Humidity Sensor"));
    Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
    Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
    Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
    Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
    Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
    Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
    Serial.println(F("------------------------------------"));
}



void loop()
{
    char temp[8];
    char hum[8];
    delay(1000);
    Serial.print("connecting to ");
    Serial.println(host);
    /* Use WiFiClient class to create TCP connections */
    WiFiClient client;
    
    if (!client.connect(host, port)) {
        Serial.println("connection failed");
        return;
    }

    // Get temperature event and print its value.
    sensors_event_t event;
    dht.temperature().getEvent(&event);
    if (isnan(event.temperature)) {
      Serial.println(F("Error reading temperature!"));
    }
    else {
      Serial.print(F("Temperature: "));
      Serial.print(event.temperature);
      Serial.println(F("°C"));
//      client.print(event.temperature);
      dtostrf((float)event.temperature,2,2,temp);
    }
    // Get humidity event and print its value.
//    delay(100);
    dht.humidity().getEvent(&event);
    if (isnan(event.relative_humidity)) {
      Serial.println(F("Error reading humidity!"));
    }
    else {
      Serial.print(F("Humidity: "));
      Serial.print(event.relative_humidity);
      Serial.println(F("%"));
      dtostrf((float)event.relative_humidity,2,2,hum);
    }
    /* This will send the data to the server */
    String msg = "Temperature: " + String(temp)+ "; " + "Humidity: " + String(hum);
    client.print(msg);
//    client.stop();
}

服务端代码(以腾讯云为例,服务器端监听的网址是内网ip):

import socket
import datetime
# 建立一个服务端
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 以下设置解决ctrl+c退出后端口号占用问题
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

server.bind(('xx.xx.xx.xx',8088)) #绑定要监听的地址(内网ip)和端口
server.listen(5) #开始监听 表示可以使用五个链接排队
while True:# conn就是客户端链接过来而在服务端为期生成的一个链接实例
    conn,addr = server.accept() #等待链接,多个链接的时候就会出现问题,其实返回了两个值
    print(conn, addr)
    try:
        data = conn.recv(1024)  #接收数据
        if data:
            print('Time:',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            print('recive:',data.decode()) #打印接收到的数据
            # conn.send(b'hello!') #然后再发送数据
    except ConnectionResetError as e:
        print('关闭了正在占线的链接!')
        break
    # conn.close()

效果如下:

笔者使用的是腾讯云服务器,公网和内网的ip可以在后台查看:

思考:
(1)这种直接发送数据的方式是否安全?
(2)如果需要发送多组采集数据的时候服务器端如何统一接收?或者说不丢包?

本文标签: 腾讯 服务器 数据 WiFiClient