ESP32项目实战:用OLED屏做个带自定义Logo的温湿度计(附PCtoLCD取模全流程)
ESP32创意项目打造个性化OLED温湿度监测仪在创客圈里温湿度计可能是最基础却又最富创意的项目之一。当普通的数字显示遇上OLED屏幕当标准字体遇上自定义Logo一个简单的传感器项目就能变成展现个人风格的科技艺术品。本文将带您从零开始用ESP32开发板、DHT22传感器和0.96寸OLED屏幕打造一款既实用又能展示个性设计的温湿度监测仪。1. 硬件准备与环境搭建1.1 所需材料清单ESP32开发板推荐使用ESP32-WROOM-32OLED显示屏SSD1306驱动128x64分辨率DHT22温湿度传感器或兼容的DHT11杜邦线若干微型面包板可选USB数据线用于供电和编程1.2 开发环境配置安装Arduino IDE最新版本添加ESP32开发板支持# 在附加开发板管理器网址中添加 https://dl.espressif.com/dl/package_esp32_index.json安装必要库文件Adafruit_SSD1306Adafruit_GFXDHT sensor library注意安装库时务必选择与硬件匹配的版本错误的库版本可能导致显示异常。2. 基础电路连接与测试2.1 硬件接线示意图组件引脚ESP32对应引脚DHT22 VCC3.3VDHT22 GNDGNDDHT22 DATAGPIO4OLED VCC3.3VOLED GNDGNDOLED SCLGPIO22OLED SDAGPIO212.2 基础功能测试代码#include Wire.h #include Adafruit_GFX.h #include Adafruit_SSD1306.h #include DHT.h #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define DHTPIN 4 #define DHTTYPE DHT22 Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, Wire, -1); DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(115200); if(!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F(SSD1306分配失败)); for(;;); } dht.begin(); oled.display(); delay(2000); oled.clearDisplay(); } void loop() { float h dht.readHumidity(); float t dht.readTemperature(); if (isnan(h) || isnan(t)) { Serial.println(读取DHT传感器失败!); return; } oled.clearDisplay(); oled.setTextSize(1); oled.setTextColor(WHITE); oled.setCursor(0,0); oled.print(温度: ); oled.print(t); oled.println( C); oled.print(湿度: ); oled.print(h); oled.println( %); oled.display(); delay(2000); }3. 高级显示设计汉字与自定义图形3.1 使用PCtoLCD进行汉字取模下载并运行PCtoLCD工具建议版本2.2按以下参数设置字符模式点阵格式阴码取模方式逐行式取模走向顺向输出数制十六进制自定义大小16x16推荐输入需要显示的汉字如温度、湿度生成字模数据// 示例16x16的温字模数据 static const unsigned char wen[] { 0x00,0x00,0x00,0x80,0x00,0x40,0x00,0x30,0xFF,0x0F,0x00,0x04,0x00,0x04,0x00,0x04, 0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04};3.2 自定义Logo设计技巧设计原则保持简洁OLED分辨率有限复杂细节无法呈现高对比度避免使用渐变效果建议尺寸不超过64x64像素使用Img2Lcd处理图像将图像转换为单色BMP格式设置输出宽度不超过128像素选择正确的扫描方式通常为水平扫描生成图像数组示例const unsigned char myLogo[] PROGMEM { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...更多图像数据... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};4. 完整项目集成与优化4.1 界面布局设计方案区域内容尺寸左上自定义Logo48x48像素右上温度值带单位64x32像素左下湿度值带单位64x32像素右下状态图标/更新时间32x32像素4.2 优化后的完整代码框架#include Wire.h #include Adafruit_GFX.h #include Adafruit_SSD1306.h #include DHT.h // 硬件定义 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define DHTPIN 4 #define DHTTYPE DHT22 // 初始化对象 Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, Wire, -1); DHT dht(DHTPIN, DHTTYPE); // 自定义图形数据 #include custom_graphics.h void setup() { // 初始化代码... } void drawCustomUI(float temp, float humi) { oled.clearDisplay(); // 绘制Logo oled.drawBitmap(0, 0, myLogo, 48, 48, WHITE); // 绘制温度区域 oled.drawBitmap(50, 0, tempIcon, 16, 16, WHITE); oled.setCursor(70, 4); oled.print(temp, 1); oled.print( C); // 绘制湿度区域 oled.drawBitmap(50, 20, humiIcon, 16, 16, WHITE); oled.setCursor(70, 24); oled.print(humi, 1); oled.print( %); // 状态指示 if(millis() % 2000 1000) { oled.fillCircle(120, 60, 4, WHITE); // 闪烁状态点 } oled.display(); } void loop() { // 主循环代码... }4.3 性能优化技巧减少屏幕刷新仅在数据变化时更新数值部分固定元素如Logo不需要每次刷新数据平滑处理#define SAMPLE_SIZE 5 float tempSamples[SAMPLE_SIZE]; float humiSamples[SAMPLE_SIZE]; float getSmoothedTemp() { static int index 0; tempSamples[index] dht.readTemperature(); index (index 1) % SAMPLE_SIZE; float sum 0; for(int i0; iSAMPLE_SIZE; i) { sum tempSamples[i]; } return sum / SAMPLE_SIZE; }低功耗模式在电池供电场景下可配置ESP32进入深度睡眠示例代码void enterDeepSleep(uint64_t time_in_us) { esp_deep_sleep_enable_timer_wakeup(time_in_us); esp_deep_sleep_start(); }5. 项目扩展思路5.1 无线数据传输方案蓝牙低功耗BLE广播#include BLEDevice.h #include BLEUtils.h #include BLEServer.h void setupBLE() { BLEDevice::init(ESP32_EnvMonitor); BLEServer *pServer BLEDevice::createServer(); BLEService *pService pServer-createService(SERVICE_UUID); // ...更多BLE设置... }WiFi连接与MQTT#include WiFi.h #include PubSubClient.h void connectToMQTT() { WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); } mqttClient.setServer(mqtt_server, 1883); mqttClient.connect(ESP32Client); }5.2 多屏显示系统使用I2C多路复用器如TCA9548A驱动多个OLED#include Adafruit_TCA9548A.h Adafruit_TCA9548A i2cMux; void setup() { i2cMux.begin(); // 初始化第一个屏幕 i2cMux.selectChannel(0); oled1.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 初始化第二个屏幕 i2cMux.selectChannel(1); oled2.begin(SSD1306_SWITCHCAPVCC, 0x3C); }5.3 3D打印外壳设计建议尺寸考量为ESP32留出足够散热空间设计OLED窗口时考虑可视角度为传感器设计通风孔材料选择PLA适合室内使用PETG更好的耐温性ABS高强度和耐久性在实际项目中我发现将温湿度传感器与主电路板分离并通过延长线连接可以避免电路板发热对测量精度的影响。同时使用深色半透明的亚克力作为前面板既能保护OLED屏幕又能增强显示对比度。