本帖最后由 MioChan 于 2024-5-20 17:16 编辑
首先,测试了一下ESP32的Deep-sleep模式,官方也有很多例程,例如下面的代码就可以实现RTC定时器唤醒功能
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0;
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
}
}
void setup(){
Serial.begin(115200);
delay(1000); //Take some time to open up the Serial Monitor
//Increment boot number and print it every reboot
++bootCount;
Serial.println("Boot number: " + String(bootCount));
//Print the wakeup reason for ESP32
print_wakeup_reason();
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
Serial.println("Going to sleep now");
Serial.flush();
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop(){
//This is not going to be called
}
后续还测量了一下整个开发版的电流,发现大概为30mA,大概只有十几mA的变化。应该是因为这种开发版的外围电路太多,锂电充放电管理、ldo这些都会影响功耗测量,真要测的准还是得自己画个板子移除这些影响来测。
下面再来实现一些网络相关的东西,因为最终是要实现驱动点阵屏做一个可以显示时间以及投送弹幕文字的时钟,所以我们先实现一个基本的API服务器,用于接受其他设备post的字符串,代码如下:
#include <WiFi.h>
#include <ArduinoJson.h>
const char* ssid = "XXXX";
const char* password = "XXXX";
int status = WL_IDLE_STATUS;
String receivedContent = "";
WiFiServer server(80);
const int led = 15;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
digitalWrite(led, 0);
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());
server.begin();
}
unsigned long startTime;
const unsigned long runDuration = 6000;
void loop() {
checkForNewClient(); // Check for new client connections
delay(2);
}
void checkForNewClient() {
WiFiClient client = server.available();
if (client) {
Serial.println("New client");
digitalWrite(led, 1);
// Read the first line of the request
String firstLine = client.readStringUntil('\n');
// Check if this is a POST request
if (firstLine.startsWith("POST")) {
// Read the headers and find the Content-Length
int contentLength = -1;
while (client.connected()) {
String line = client.readStringUntil('\n');
if (line.startsWith("Content-Length:")) {
contentLength = line.substring(15).toInt();
}
// Check if the end of headers is reached (empty line)
if (line == "\r") {
break;
}
}
// Read the request body
if (contentLength > 0) {
String requestBody = client.readStringUntil('\n');
// Parse JSON from the request body
DynamicJsonDocument doc(1024);
deserializeJson(doc, requestBody);
String content = doc["content"];
if (content != "") {
Serial.println("Received content: " + content);
receivedContent = " "+content+" "; // Update the received string
} else {
Serial.println("No content received");
}
}
}
digitalWrite(led,0);
// Send response to the client
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
client.println("Connection: close");
client.println();
client.println("Response sent");
client.stop();
Serial.println("Client disconnected");
}
}
直接用IOS快捷指令就能实现Post字符串的功能
运行
ESP32已经读取到了手机发来的字符串,并把它输出在了串口,这个功能实现完毕
顺便测试了一下,这个程序ESP32连接wifi后电流为40ma,在通过wifi交换报文时能达到270mA左右,如果使用电池供电的话加入休眠还是很有必要的。
因为要做时钟,所以NTP获取时间的功能也需要实现
#include <WiFi.h>
#include <NTPClient.h>
#include <ArduinoJson.h>
#include <NetworkUdp.h>
const char* ssid = "XXXX";
const char* password = "XXXX";
int status = WL_IDLE_STATUS;
String receivedContent = ""; // Variable to store the received string
const int led = 15;
const int timeZone = 8;
const char* ntpServer = "pool.ntp.org";
NetworkUDP udp;
NTPClient timeClient(udp,ntpServer, timeZone * 3600, 60000);
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
digitalWrite(led, 0);
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());
timeClient.begin();
timeClient.update();
}
void loop() {
Serial.println(timeClient.getFormattedTime());
delay(1000);
}
可以正常获取到北京时间,实现完毕
之后我们基于这两个代码实现的功能,使用MD_Parola 、MD_MAX72xx 这两个库就可以实现驱动点阵屏了,后续内容就放到下一帖啦~