首先我们需要知道如何让ESP32联网,并且作为一个Server发送信息。
想要让ESP32联网,显然需要告诉ESP32网络的名称和密码。PC通过数据线把信息烧录进ESP32后,开发板具有了联网功能,通过串口获得开发板的IP,此时我们就可以通过PC作为Client接入ESP32的Server,从而成功地与ESP32进行通讯。
实验5:helloServer
需要修改的仅有第5行,第6行的ssid和password,填入无线网络名和密码。ESP32只能支持2.4Ghz频段的无线网。
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char *ssid = "yourWIFIssid";
const char *password = "yourWIFIpassword";
WebServer server(80);
const int led = 13;
void handleRoot()
{
digitalWrite(led, 1);
server.send(200, "text/plain", "hello from esp32!");
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)
{
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);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp32"))
Serial.println("MDNS responder started");
server.on("/", handleRoot);
server.on("/inline", []()
{ server.send(200, "text/plain", "this works as well"); });
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void)
{
server.handleClient();
delay(2); // allow the cpu to switch to other tasks
}
将串口监视器里的IP address复制到浏览器中,实现服务器的应答。
现在我们已经能使用ESP32作为Server来与PC进行交互了,下面我们来学习如何通过温度传感器获得周围环境的信息。DS18B20只有三个管脚:GND负责接地,VCC负责供电,DAT负责传输信号。这是最简单的管脚功能。
实验6:ds18b20温度传感器
需要下载U8G2,OneWire,DallasTemperature,SPI库。
#include <Arduino.h>
#include <U8x8lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/15, /* data=*/4, /* reset=*/U8X8_PIN_NONE);
#define ONE_WIRE_BUS 17
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
char str[6];
void setup(void)
{
u8x8.begin();
u8x8.setPowerSave(0);
Serial.begin(115200);
Serial.println("Dallas Temperature IC Control Library Demo");
sensors.begin();
}
void loop(void)
{
u8x8.setFont(u8x8_font_chroma48medium8_r);
Serial.print("正在请求传感器数据...");
sensors.requestTemperatures();
Serial.println("完成");
float tempC = sensors.getTempCByIndex(0);
if (tempC != DEVICE_DISCONNECTED_C)
{
Serial.print("温度:");
Serial.println(tempC);
}
else
Serial.println("Error: Could not read temperature data");
u8x8.clearDisplay();
dtostrf(tempC, 3, 2, str);
u8x8.drawString(0, 1, str);
delay(700);
}
128x64屏幕只有四个管脚,GND,VCC,SCL,SDA。管脚连接:GND-GND,VCC-3V3,SCL-G15,SDA-G4。
综合上面的两个实验,结合成一项比较有难度的项目:通过环境传感器将数据传入ESP32,再把环境信息由TCP协议传输给网络调试助手。当然,我们最好也把环境信息通过串口发送到Arduino的串口监视器和64x128的oled显示器上。
实验7:TCPServer
综合DHT11,EasySheild的实验,把ESP32当作server,使用串口和网络调试助手来接受ESP32发送的信息,并在显示屏上显示。
#include "DHT.h"
#include <WiFi.h>
#include <Arduino.h>
#include <U8g2lib.h>
#define MAX_SRV_CLIENTS 3 // Client同时连接数
#define FREQ 50 // count=FREQ,发送一次温湿度
#define len 20 //
#define SCL 15 // GPIO15连接SCL
#define SDA 4 // GPIO4连接SDA
#define SINLED 32 // GPIO32作指示灯
#define CONL0 33 // GPIO33控制灯0
#define CONL1 27 // GPIO27控制灯1
DHT dht11; // GPIO0作DHT11数据IO("AITA_DHT.h"中宏DHT_PIN)
uint8_t temperature, humidity;
unsigned int count = 0; //计数器,到2000时发送一次温湿度值
const char *ssid = "307"; // Wi-Fi ssid即热点名称
const char *password = "7bhckfh9"; // Wi-Fi密码
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);
WiFiServer server(4000); // Server端口号,范围0-65535的整数
WiFiClient serverClients[MAX_SRV_CLIENTS]; // Client数组
void setup()
{
// pinMode(14, OUTPUT_OPEN_DRAIN);
Serial.begin(115200);
delay(10);
pinMode(SINLED, OUTPUT); //设置一个指示灯,表示网络状态
pinMode(CONL0, OUTPUT);
pinMode(CONL1, OUTPUT);
digitalWrite(SINLED, 0);
digitalWrite(CONL0, 1);
digitalWrite(CONL1, 1);
u8g2.begin(); // u8g2对象初始化
/* 设置ESP为STA模式的TCPServer */
WiFi.mode(WIFI_STA); // STA模式
WiFi.begin(ssid, password); //连接AP
while (WiFi.status() != WL_CONNECTED) //等待连接成功
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
server.begin(); //开启TCPServer
server.setNoDelay(true); //关闭小包合并包功能,不会延时发送数据
Serial.println("Server started");
Serial.println(WiFi.localIP()); //串口打印IP地址
}
void loop()
{
blink(); //指示灯闪烁
delay(1);
uint8_t i;
if (server.hasClient()) //有客户端接入
{ //客户端加入数组serverClients
for (i = 0; i < MAX_SRV_CLIENTS; i++)
{
if (!serverClients[i] || !serverClients[i].connected())
{
if (serverClients[i])
serverClients[i].stop(); //未联接,就释放
serverClients[i] = server.available(); //分配新的
continue;
}
}
}
for (i = 0; i < MAX_SRV_CLIENTS; i++)
{
if (serverClients[i] && serverClients[i].connected())
{
digitalWrite(SINLED, 0); //有链接存在,就一直长亮(输出低)
if (serverClients[i].available())
{
String order = "";
//接收到客户端发送的信息,通过串口输出
while (serverClients[i].available())
{
char c = serverClients[i].read();
if (c != '\r')
order = order + c;
Serial.write(c);
}
if (order.length() > 1024)
order = "";
if (order.indexOf("#00") != -1)
{
digitalWrite(CONL0, 1);
order = "";
}
else if (order.indexOf("#01") != -1)
{
digitalWrite(CONL0, 0);
order = "";
}
else if (order.indexOf("#10") != -1)
{
digitalWrite(CONL1, 1);
order = "";
}
else if (order.indexOf("#11") != -1)
{
digitalWrite(CONL1, 0);
order = "";
}
}
}
}
if (count > FREQ)
{
count = 0;
if (!dht11.dht11Read(&temperature, &humidity))
{
sendDHT(); //串口发送温湿度
showDHT(); // OLED显示温湿度
for (i = 0; i < MAX_SRV_CLIENTS; i++)
{
if (serverClients[i] && serverClients[i].connected())
{
serverClients[i].printf("Humidity:%d, Temperature:%d, LED0:%d, LED1:%d",
humidity, temperature, !digitalRead(CONL0), !digitalRead(CONL1));
delay(1);
}
}
}
}
}
void blink()
{
static long previousMillis = 0;
static int currstate = 0;
if (millis() - previousMillis > 200) // 200ms
{
previousMillis = millis();
currstate = 1 - currstate;
digitalWrite(SINLED, currstate);
count++; //计数器加一
}
}
void sendDHT()
{
Serial.print("Read sensor: ");
Serial.print("Humidity (%): ");
Serial.println(humidity);
Serial.print("Temperature (oC): ");
Serial.println(temperature);
}
void showDHT()
{
char hbuf[6] = "";
char tbuf[6] = "";
/* 将数值转化为字符串 */
dtostrf((float)humidity, 2, 2, hbuf);
dtostrf((float)temperature, 2, 2, tbuf);
u8g2.clearBuffer(); //等于清屏
u8g2.setFont(u8g2_font_ncenB08_tr); //选择字体
u8g2.drawStr(10, 16, "Humidity:");
u8g2.drawStr(0, 32, hbuf);
u8g2.drawStr(10, 48, "Temperature:");
u8g2.drawStr(0, 64, tbuf);
u8g2.sendBuffer(); //屏幕显示——不执行此步骤不显示
}
DHT11:G0-D4,rgbLED:G27-D9,LED1:G33-D13,LED2:G27-D12,GND-GND,5V-3.3V