几年前闲的蛋疼购买了一块esp8266开发板,还买了面包板和一块屏幕还有一堆led灯珠开关杜邦线啥的,但是很快就失去兴趣了,最近天天在b站刷到各种桌面小摆件,于是又来了兴趣。
在某宝逛了半天,发现一款紫色的esp32s3uno,我当时还寻思这种样式的开发板很不错,不需要面包板就能很不错的连接其它模块,刚好在下方推荐中发现一块可以直插r3uno的2.4寸ILI9341屏幕,然后我就想买这两个再把他们对插起来,这样刚好可以很方便的使用,一根线都不需要接了,还买了一个r3uno亚克力外壳,把他俩包起来。还看了不少这种样式的开发板扩展模块,甚至还有一分二的扩展板,于是全部收藏起来,以后可能需要。
还没到货的时候我就在提前准备,妈的我才开始考虑这个引脚的问题,屏幕是给r3 uno用的,引脚虽然长得一样但是io数都不一样,甚至买的亚克力外壳都是给官方r3uno的,我傻了,看了一晚上引脚相关的教程,凌晨三点睡觉。
第二天我怕买来都不能用,于是就考虑买个一分二扩展板,结果那个扩展版一分二只是接线方便,一个口还是只能用一次,于是立刻转头考虑买r3uno,刷到源地的unor4,搜了搜发现r4和r3接口很兼容,而且性能也高,看到他家的开发板都不错,又顺便买了块esp32s3开发板。
由于uno的开发板接了屏幕后剩余接口不多,于是我就买了面包板和许多跳线,ST7789屏幕,INMP441全向麦克风,SHT30温湿度传感器,MAX98357音频放大器和一个小喇叭,这样可以把那款esp32s3uno只用来接屏幕,这些模块用来做一个桌面摆件,可以显示时间当前温湿度,也可以对话。
果真如我所料,那款接口一样的esp32s3uno直接插上屏幕后无法正常使用,使用tft_espi库配置好引脚后也不能用,于是寻求各路大神帮助,经过各种短接rst,修改多次库文件等各种操作,仍然不可用,屏幕测试程序运行后屏幕白屏,但是程序已经正常运行了,持续好几天,由于这款开发板网上没有任何资料,只有店铺扔出的引脚图片,最后我怀疑是引脚就是错误的,但是写了个程序测试了每个引脚,发现gpio47和gpio48接反了,而且gpio48和gnd短接了,但是这两个问题与屏幕没任何关联,于是也放弃不管,垃圾某宝卖家买的什么垃圾玩意。在网上搜到esp32s3文档中表面有的io口有特殊作用。gpio3与gpio46均为Strapping管脚,于是怀疑是不是这两个引脚的问题,搜索许多也没作用。
9月16号今天没上班,上午又在看,直接开干,不对插直接改变接线,用杜邦线重新连接,把gpio3与gpio46换成了gpio8和gpio9,屏幕显示正常,我立刻把8改回3发现还是正常,于是怀疑是gpio46的原因,就在我回去修改tft_espi配置文件的时候,妈的突然发现引脚定义配置旁边注释写着一条只能用gpio0-gpio31妈的我直接傻了,看了半天也没看到注释,于是我尝试修改gpio46到gpio8,尝试短接这两个端口后仍能正常刷入和开机使用,于是立刻将两个引脚背面焊了起来,现在一切正常。
翻箱倒柜找出来之前买的esp8266,把温湿度传感器接上了,让8266连接wifi后发送温湿度信息到局域网,然后再用esp32来接收。
#include <WiFi.h>
#include <WiFiUdp.h>
#include <TFT_eSPI.h>
#include <NTPClient.h>
#include <TimeLib.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "SSID";
const char* password = "PASSWORD";
bool connectionSuccess;
const char* ntpServer = "NTPSERVER";
const int listenPort = PORT;
const long gmtOffset_sec = 28800;
const int daylightOffset_sec = 0;
unsigned long previousWeatherMillis = 0;
unsigned long lastReceiveTime = 0;
const unsigned long receiveInterval = 30000;
const unsigned long timeoutInterval = 300000;
unsigned long currentMillis = millis();
const long weatherInterval = 300000;
String url = "APIURL";
char timeStr[9];
char dateStr[11];
String temperature = "N/A";
String humidity = "N/A";
String textDay;
String high;
String low;
String humidity2;
String windy;
String precip;
String rainfall;
float precip_num = precip.toFloat();
int precip_percentage = static_cast<int>(precip_num * 100);
String precip_print = String(precip_percentage);
WiFiUDP udp;
WiFiUDP ntpUDP;
HTTPClient http;
NTPClient timeClient(ntpUDP, ntpServer, gmtOffset_sec, 60000);
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite sprite = TFT_eSprite(&tft);
void setup() {
Serial.begin(115200);
tft.init();
tft.setRotation(3);
sprite.createSprite(tft.width(), tft.height());
sprite.fillRect(0, 0, 320, 240, TFT_BLACK);
connectToWifi();
timeClient.begin();
getDateTime();
udp.begin(listenPort);
getUdpPacket();
getWeather();
}
void loop() {
sprite.fillRect(0, 0, 320, 240, TFT_BLACK);
getDateTime();
getUdpPacket();
if (currentMillis - previousWeatherMillis >= weatherInterval) {
previousWeatherMillis = currentMillis;
getWeather();
}
if (millis() - lastReceiveTime > timeoutInterval) {
temperature = "N/A";
humidity = "N/A";
}
sprite.setTextColor(TFT_WHITE);
sprite.setTextSize(3);
sprite.setCursor(10, 20);
sprite.print("Time:");
sprite.print(timeStr);
sprite.setTextSize(2);
sprite.setCursor(10, 60);
sprite.print("Date:");
sprite.print(dateStr);
sprite.setCursor(10, 90);
sprite.print("Temperature:" + temperature);
sprite.setCursor(10, 120);
sprite.print("Humidity:" + humidity);
sprite.setCursor(10, 150);
sprite.print("Weather:" + textDay);
sprite.setCursor(10, 180);
sprite.print(low + "C~" + high + "C," + humidity2 + "%RH," + windy + "km/h");
sprite.setCursor(10, 210);
sprite.print(rainfall + "mm,Chance:" + precip_print + "%");
sprite.pushSprite(0, 0);
delay(1000);
}
void connectToWifi() {
int attemptCount = 0;
while (true) {
sprite.fillRect(0, 0, 320, 240, TFT_BLACK);
sprite.setTextColor(TFT_WHITE);
sprite.setTextSize(3);
sprite.setCursor(10, 80);
sprite.print("Connecting...");
sprite.pushSprite(0, 0);
WiFi.begin(ssid, password);
int cursorPosition = 10;
attemptCount = 0;
while (attemptCount < 5) {
while (WiFi.status() != WL_CONNECTED) {
sprite.setCursor(cursorPosition, 120);
sprite.print(".");
sprite.pushSprite(0, 0);
cursorPosition += 20;
if (cursorPosition > 80) {
cursorPosition = 10;
}
delay(1000);
}
if (WiFi.status() == WL_CONNECTED) {
sprite.fillRect(0, 0, 320, 240, TFT_BLACK);
sprite.setTextColor(TFT_WHITE);
sprite.setTextSize(3);
sprite.setCursor(10, 80);
sprite.print("Connected!");
sprite.pushSprite(0, 0);
delay(3000);
return;
}
attemptCount++;
}
sprite.fillRect(0, 0, 320, 240, TFT_BLACK);
sprite.setTextColor(TFT_WHITE);
sprite.setTextSize(3);
sprite.setCursor(10, 80);
sprite.print("Connection Failed!");
sprite.setCursor(10, 120);
sprite.print("Waiting 5 mins...");
sprite.pushSprite(0, 0);
delay(300000);
}
}
void getDateTime() {
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
setTime(epochTime);
sprintf(dateStr, "%04d-%02d-%02d", year(), month(), day());
sprintf(timeStr, "%02d:%02d:%02d", hour(), minute(), second());
}
void getUdpPacket() {
int packetSize = udp.parsePacket();
if (packetSize) {
String receivedData = "";
while (udp.available()) {
receivedData += (char)udp.read();
}
int tempIndex = receivedData.indexOf("Temperature:");
int humidIndex = receivedData.indexOf("Humidity:");
if (tempIndex != -1 && humidIndex != -1) {
temperature = receivedData.substring(tempIndex + 12, receivedData.indexOf(",", tempIndex));
humidity = receivedData.substring(humidIndex + 9);
lastReceiveTime = millis();
}
}
}
void getWeather() {
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
DynamicJsonDocument doc(2048);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
String textDay = "N/A";
String high = "N/A";
String low = "N/A";
String windy = "N/A";
String precip_print = "N/A";
String rainfall = "N/A";
http.end();
return;
}
textDay = doc["results"][0]["daily"][1]["text_day"].as<String>();
high = doc["results"][0]["daily"][1]["high"].as<String>();
low = doc["results"][0]["daily"][1]["low"].as<String>();
humidity2 = doc["results"][0]["daily"][1]["humidity"].as<String>();
windy = doc["results"][0]["daily"][1]["wind_speed"].as<String>();
precip = doc["results"][0]["daily"][1]["precip"].as<String>();
rainfall = doc["results"][0]["daily"][1]["rainfall"].as<String>();
http.end();
}
}
改来改去不知道还能不能编译成功,闲置了,兴趣转瞬即逝了。