ESP32-C3利用AsyncWebServer和HTTPClient实现双机通信

因为刚好做作业需要用到双机通信,顺便学习一下,我在网上找了很多方法,试过用蓝牙通信,但是只能实现发送字符串(个人能力只能到这步,等后面有时间再深入研究蓝牙通信)最后实现方式是 AsyncWebServer和HTTPClient实现双机通信。

​ 这里我把ESP32-C3接温湿度传感器、空气报警器的当做服务端,ESP32-C3接OLED显示屏的当做客户端,一个发送数据,一个接受数据。

文章目录

一、服务端

1、环境配置

需要下载ESPAsyncWebServer库,大家可以去官网下载,也可以用我存放在百度网盘的,一样的资源。下载完以后还是跟之前一样,添加下载库

链接:https://pan.baidu.com/s/1Yr8efIupvVDV9nMvxpvd2Q
提取码:xi0x
ESP32-C3利用AsyncWebServer和HTTPClient实现双机通信

2、代码撰写

2.1 调用头文件

#include "WiFi.h"
#include "FS.h"
#include "ESPAsyncWebServer.h"
#include "DHT.h"
#include <Wire.h>

2.2 定义引脚接口、服务器端口

#define DHTPIN 7     //DHT数据口
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);
const int airtwo =6;   //空气警报器模拟口

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

2.3读取数据

这里写的函数是为了先读取数据,方便数据封装,又因为温湿度的数据函数是库封装好的,那要是我们是要其他传感器数据呢?这里我写了一个空气警报器的,可以借鉴一下。

//温度
String readTemp() {
  return String(dht.readTemperature());
}

//湿度
String readHumi() {
  return String(dht.readHumidity());
}
//空气
String readAir() {
  return String(Air());
}


String Air(){

  int newStat1 = digitalRead(airtwo);
   if(newStat1==HIGH)
  {
    Serial.println("超过气体阈值\n");
    String a ="1";
    return a;
  }
  else{
    String a ="0";
    return a; 
  }
}

2.4 发送数据

关于“/temperature”这个可根据你自己来定义,这里是搞了三个页面,对应不同的数据。

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readHumi().c_str());
  });
 server.on("/Air", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readAir().c_str());
  });
  

2.5获取服务端ip地址,我们可以通过串口助手查看或者是打开电脑的移动认定查看

  Serial.print("IP Address:");
  Serial.println(WiFi.localIP());
3、遇见的问题

在烧录代码的时候,报出了库的问题,说是IPAddress的问题,用ESP32开发板是没问题的,但是用ESP32-C3开发板就报错。一开始我也是在网上找了很久,可是还是没找到相关解决办法,后面根据报错地址,一个一个找,在找到报错的那个点,我把0U删除了,就可以用了。
ESP32-C3利用AsyncWebServer和HTTPClient实现双机通信
ESP32-C3利用AsyncWebServer和HTTPClient实现双机通信

4、服务端完整代码
// Import required libraries
#include "WiFi.h"
#include "FS.h"
#include "ESPAsyncWebServer.h"
#include "DHT.h"
#include <Wire.h>

#define DHTPIN 7  
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

const char* ssid = "3671";
const char* password = "05210835";
const int airtwo =6;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

String readTemp() {
  return String(dht.readTemperature());
}

String readHumi() {
  return String(dht.readHumidity());
}
String readAir() {
  return String(Air());
}
String Air(){

  int newStat1 = digitalRead(airtwo);
   if(newStat1==HIGH)
  {
    Serial.println("超过气体阈值\n");
    String a ="1";
    return a;
  }
  else{
    String a ="0";
    return a;
   
  }
}
void setup(){
  pinMode(airtwo,INPUT);  //空气报警器  是输入
  // Serial port for debugging purposes
  Serial.begin(115200);
  dht.begin();
  WiFi.begin(ssid, password);
   while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print("正在连接中----\n");       
    }

    Serial.print("WIFI已连接\n");
    Serial.print("IP Address:");
    Serial.println(WiFi.localIP());
  
  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readHumi().c_str());
  });
 server.on("/Air", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readAir().c_str());
  });
  
  // Start server
  server.begin();
}

void setupWifi(){
  WiFi.begin(ssid, password);
   while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print("正在连接中----\n");
        
    }

    Serial.print("WIFI已连接\n");
    Serial.print(WiFi.localIP());
}
void loop(){
float h = dht.readHumidity(); 
float t = dht.readTemperature(); 
float f = dht.readTemperature(true);
String a =Air();
int newStat1 = digitalRead(airtwo);
  if(newStat1==HIGH)
  {
    Serial.println("超过气体阈值\n");

  }
  else{  
  }
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!\n"));
    return;
  }
  //可以让我们通过串口查看数据
  Serial.print(F("Air: "));   
  Serial.print(a);
  Serial.print(F("  Humidity: "));        
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("*C  \n "));
 
  if (!WiFi.isConnected()) //先看WIFI是否还在连接
  {
    setupWifi();
  }
}

二、客户端

​ 上一篇博客已经讲了OLED的使用,所以这里就一笔带过。讲客户端怎么获取服务端的数据。

1、调用头文件

#include <WiFi.h>
#include <HTTPClient.h>
/* 使用0.96寸的OLED屏幕需要使用包含这个头文件 */
#include "SSD1306Wire.h"

2、服务器的ip地址

对应服务端三个页面存放的数据

//服务端的ip地址
const char* serverNameTemp = "http://192.168.137.82/temperature";  
const char* serverNameHumi = "http://192.168.137.82/humidity";
const char* serverNameAir = "http://192.168.137.82/Air";

3、获取http网页函数

String httpGETRequest(const char* serverName) {
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "--"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

4、获取的数据显示到显示屏上

   String temperature = httpGETRequest(serverNameTemp);
   String Humidity = httpGETRequest(serverNameHumi);
   String Airpost  =httpGETRequest(serverNameAir);
   unsigned long currentMillis = millis();
  if(Airpost =="0"){
    oled.drawString(0,40, "Air:warning"); // 数值为0是 显示warning
    }
  else
  {
     oled.drawString(0,40, "Air:normal"); // 数值为1是 显示normal
  }
   /* 1. 显示字母 */
  oled.setFont(ArialMT_Plain_16);       // 设置字体
  oled.drawString(0,0, "Temp:" +temperature+"C"); // 将要显示的字母写入缓存
  oled.drawString(0,20, "Humidity:"+Humidity+"%"); // 将要显示的字母写入缓存
  oled.display();                       // 将缓存里的文字在屏幕上显示
  delay(10000);
  oled.clear(); 
  oled.display();         // 清除屏幕

5、客户端完整代码

#include <WiFi.h>
#include <HTTPClient.h>
/* 使用0.96寸的OLED屏幕需要使用包含这个头文件 */
#include "SSD1306Wire.h"
const char* ssid = "3671";
const char* password = "05210835";
//Your IP address or domain name with URL path
//服务端的ip地址
const char* serverNameTemp = "http://192.168.137.82/temperature";
const char* serverNameHumi = "http://192.168.137.82/humidity";
const char* serverNameAir = "http://192.168.137.82/Air";



/* 设置oled屏幕的相关信息 */
const int I2C_ADDR = 0x3c;              // oled屏幕的I2c地址
#define SDA_PIN 5                       // SDA引脚,默认gpio4(D2)
#define SCL_PIN 4                       // SCL引脚,默认gpio5(D1)

/* 新建一个oled屏幕对象,需要输入IIC地址,SDA和SCL引脚号 */
SSD1306Wire oled(I2C_ADDR, SDA_PIN, SCL_PIN);

unsigned long previousMillis = 0;
const long interval = 5000; 


void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
      
   /* 2. oled屏幕初始化 */
  oled.init();
  oled.flipScreenVertically();          // 设置屏幕翻转
  oled.setContrast(255);                // 设置屏幕亮度
  drawRect();                           // 测试屏幕显示
  oled.clear(); oled.display();         // 清除屏幕
}

void drawRect(void) {
  for (int16_t i=0; i<oled.getHeight()/2; i+=2) {
    oled.drawRect(i, i, oled.getWidth()-2*i, oled.getHeight()-2*i);
    oled.display();
    delay(50);
  }
}

void loop() {
   String temperature = httpGETRequest(serverNameTemp);
   String Humidity = httpGETRequest(serverNameHumi);
   String Airpost  =httpGETRequest(serverNameAir);
   unsigned long currentMillis = millis();
  if(Airpost =="0"){
    oled.drawString(0,40, "Air:warning"); // 将要显示的字母写入缓存
    }
  else
  {
     oled.drawString(0,40, "Air:normal"); // 将要显示的字母写入缓存
  }
   /* 1. 显示字母 */
  oled.setFont(ArialMT_Plain_16);       // 设置字体
  oled.drawString(0,0, "Temp:" +temperature+"C"); // 将要显示的字母写入缓存
  oled.drawString(0,20, "Humidity:"+Humidity+"%"); // 将要显示的字母写入缓存
  oled.display();                       // 将缓存里的文字在屏幕上显示
  delay(10000);
  oled.clear(); 
  oled.display();         // 清除屏幕

  if(currentMillis - previousMillis >= interval) {
     // Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED ){ 
      Serial.println("Temperature: " + temperature + " *C - Humidity: " + Humidity+ "%" );
     
      // save the last HTTP GET Request
      previousMillis = currentMillis;
    }
    else {
      Serial.println("WiFi Disconnected");
    }
  }
}

String httpGETRequest(const char* serverName) {
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "--"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

三、效果展示

ESP32-C3利用AsyncWebServer和HTTPClient实现双机通信
ESP32-C3利用AsyncWebServer和HTTPClient实现双机通信
写到这里,终于放假回家了,新的一年再继续加油努力吧!!!
凛冬散尽 星河长明 新的一年 万事顺遂

上一篇:基于arduino的dht11温湿度传感器的使用


下一篇:Arduino Serial.read()串口接收数据,输入open点灯,输入其他关闭