因为刚好做作业需要用到双机通信,顺便学习一下,我在网上找了很多方法,试过用蓝牙通信,但是只能实现发送字符串(个人能力只能到这步,等后面有时间再深入研究蓝牙通信)最后实现方式是 AsyncWebServer和HTTPClient实现双机通信。
这里我把ESP32-C3接温湿度传感器、空气报警器的当做服务端,ESP32-C3接OLED显示屏的当做客户端,一个发送数据,一个接受数据。
文章目录
一、服务端
1、环境配置
需要下载ESPAsyncWebServer库,大家可以去官网下载,也可以用我存放在百度网盘的,一样的资源。下载完以后还是跟之前一样,添加下载库
链接:https://pan.baidu.com/s/1Yr8efIupvVDV9nMvxpvd2Q
提取码:xi0x
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删除了,就可以用了。
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;
}
三、效果展示
写到这里,终于放假回家了,新的一年再继续加油努力吧!!!
凛冬散尽 星河长明 新的一年 万事顺遂