ESP32 WiFiClient发送数据至腾讯云服务器并接收处理


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.com",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.com/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)如果需要发送多组采集数据的时候服务器端如何统一接收?或者说不丢包?

好的,这是一个关于Arduino Uno和ESP-01S模块的项目,主要用于接收DHT11温湿度传感器的数据并将其通过ESP-01S模块上传到阿里云服务器上。以下是具体的步骤: 1. 将DHT11温湿度传感器连接到Arduino Uno上,可以参考以下连接方式: DHT11 VCC - Arduino 5V DHT11 GND - Arduino GND DHT11 DATA - Arduino Digital Pin 2 2. 下载并安装ESP8266库,这里我们使用的是ESP8266WiFi库和ESP8266HTTPClient库。打开Arduino IDE,选择菜单栏:Sketch -> Include Library -> Manage Libraries,搜索并安装这两个库。 3. 连接ESP-01S模块到Arduino Uno上,可以参考以下连接方式: ESP-01S VCC - Arduino 3.3V ESP-01S GND - Arduino GND ESP-01S RX - Arduino Digital Pin 3 ESP-01S TX - Arduino Digital Pin 4 4. 在阿里云上创建一个IoT实例并添加一个设备,记录下设备的三元组(ProductKey、DeviceName、DeviceSecret)。 5. 在阿里云上创建一个Topic,用于接收设备上传的数据。 6. 编写Arduino代码,实现从DHT11传感器读取数据并将其上传到阿里云服务器上,可以参考以下代码: ``` #include <DHT.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <PubSubClient.h> #define DHTPIN 2 #define DHTTYPE DHT11 const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; const char* serverName = "your_SERVER_NAME"; const char* productKey = "your_PRODUCT_KEY"; const char* deviceName = "your_DEVICE_NAME"; const char* deviceSecret = "your_DEVICE_SECRET"; const char* mqttServer = productKey ".iot-as-mqtt.cn-shanghai.aliyuncs.com"; int mqttPort = 1883; const char* mqttClientId = "clientId"; const char* mqttUsername = deviceName "&" productKey; const char* mqttPassword = "your_MQTT_PASSWORD"; const char* mqttTopic = "/sys/" productKey "/" deviceName "/thing/event/property/post"; DHT dht(DHTPIN, DHTTYPE); WiFiClient wifiClient; PubSubClient mqttClient(wifiClient); void setup() { Serial.begin(9600); dht.begin(); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); mqttClient.setServer(mqttServer, mqttPort); } void loop() { float temp = dht.readTemperature(); float humidity = dht.readHumidity(); if (isnan(temp) || isnan(humidity)) { Serial.println("Failed to read from DHT sensor!"); return; } Serial.print("Temperature: "); Serial.print(temp); Serial.print("C, Humidity: "); Serial.print(humidity); Serial.println("%"); if (WiFi.status() == WL_CONNECTED) { HTTPClient http; String serverPath = serverName + "/temperature=" + String(temp) + "&humidity=" + String(humidity); http.begin(serverPath.c_str()); int httpCode = http.GET(); if (httpCode > 0) { String payload = http.getString(); Serial.println(payload); } else { Serial.println("Error on HTTP request"); } http.end(); } if (!mqttClient.connected()) { String clientId = mqttClientId; clientId += String(random(0xffff), HEX); Serial.print("Connecting to MQTT server "); Serial.print(mqttServer); Serial.println("..."); if (mqttClient.connect(clientId.c_str(), mqttUsername, mqttPassword)) { Serial.println("Connected to MQTT server"); } else { Serial.print("Failed to connect to MQTT server, rc="); Serial.println(mqttClient.state()); delay(2000); return; } } String payload = "{\"id\":\"1\",\"params\":{\"Temperature\":" + String(temp) + ",\"Humidity\":" + String(humidity) + "},\"method\":\"thing.event.property.post\"}"; mqttClient.publish(mqttTopic, payload.c_str()); Serial.println("Published message"); delay(5000); } ``` 在代码中,我们使用了MQTT协议将传感器数据上传到阿里云服务器上。需要注意的是,MQTT连接需要使用三元组中的DeviceName、ProductKey和DeviceSecret,以及阿里云IoT账号的AccessKey和SecretKey生成MQTT密码,可以在阿里云控制台中找到。 7. 将代码上传到Arduino Uno板子上。 到这里,你已经完成了将温湿度传感器数据发送到阿里云服务器的过程。如果你在阿里云IoT控制台中创建了一个Topic,则可以在控制台中查看设备上传的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值