ESP32如何将Serial监控信息显示在ST77XX LCD显示屏上?
ESP32+ST77XX显示屏显示OBD数据及文本更新问题解决
问题说明
作为MCU新手,我使用ESP32搭配Adafruit ST77XX驱动显示屏,结合ELMduino库开发车载HUD,已实现欢迎界面。当前需要解决两个问题:
- 将Serial监视器输出的信息(如OBD扫描器连接失败提示、RPM数据)显示在LCD屏幕上
- 此前测试自定义
print_text函数时,文本无法实时更新:
int temperature=0; while (temperature<10){ temperature=temperature+0.1; }
实际仅显示0.1,未按0.1、0.2、0.3...递增更新。
问题分析
测试代码的核心错误
temperature被定义为int整数类型,赋值0.1时会自动截断为0,导致循环条件temperature<10永远成立,程序卡在循环内无法执行屏幕更新逻辑;即使强制显示,数值也不会真正递增。需将类型改为float才能存储小数并正常递增。
OBD信息显示的核心需求
需要将setup阶段的连接错误提示、loop阶段的实时RPM数据,通过print_text函数输出到屏幕,同时保证每次更新时覆盖旧内容。
代码修改方案
1. 整合文本显示函数到主代码
将之前的print_text函数添加到主代码中,并补充屏幕更新的逻辑。
2. 修复连接失败提示的屏幕显示
在setup的OBD连接失败分支中,添加屏幕显示错误信息的代码,替代仅打印Serial的逻辑。
3. 实现RPM数据的实时显示
在loop中获取到RPM数据后,将数值转为字符串,调用print_text显示到屏幕,同时通过填充矩形覆盖旧数据避免残留。
修改后的完整代码
#include "BluetoothSerial.h" #include "ELMduino.h" #include <SPI.h> #include <Adafruit_GFX.h> // 核心图形库 #include <Adafruit_ST7735.h> // 硬件驱动库 #include "bitmaps.h" #include "bitmapsLarge.h" BluetoothSerial SerialBT; #define ELM_PORT SerialBT #define DEBUG_PORT Serial #define TFT_CS 5 #define TFT_RST 4 // 设为-1可连接到Arduino复位引脚 #define TFT_DC 2 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); ELM327 myELM327; uint32_t rpm = 0; // 自定义文本显示函数 void print_text(byte x_pos, byte y_pos, char *text, byte text_size, uint16_t color) { tft.setCursor(x_pos, y_pos); tft.setTextSize(text_size); tft.setTextColor(color); tft.setTextWrap(true); tft.print(text); } void setup() { Serial.print(F("Hello! ST77xx TFT Test")); tft.initR(INITR_BLACKTAB); tft.setRotation(0); tft.fillScreen(ST7735_BLACK); // 显示欢迎界面 int h = 160,w = 128, row, col, buffidx=0; for (row=0; row<h; row++) { for (col=0; col<w; col++) { tft.drawPixel(col, row, pgm_read_word(evive_in_hand + buffidx)); buffidx++; } } delay(5000); tft.setRotation(1); #if LED_BUILTIN pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); #endif DEBUG_PORT.begin(115200); ELM_PORT.begin("ArduHUD", true); // 连接OBD扫描器 - 阶段1 if (!ELM_PORT.connect("OBDII")) { DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 1"); // 屏幕显示错误信息 tft.fillScreen(ST7735_BLACK); char error_msg[] = "OBD Connect Fail - P1"; print_text(10, 50, error_msg, 1, ST77XX_RED); while(1); } // 初始化ELM327 - 阶段2 if (!myELM327.begin(ELM_PORT, true, 2000)) { DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 2"); // 屏幕显示错误信息 tft.fillScreen(ST7735_BLACK); char error_msg[] = "OBD Connect Fail - P2"; print_text(10, 50, error_msg, 1, ST77XX_RED); while (1); } DEBUG_PORT.println("Connected to ELM327"); // 屏幕显示连接成功 tft.fillScreen(ST7735_BLACK); char success_msg[] = "OBD Connected!"; print_text(10, 50, success_msg, 1, ST77XX_GREEN); delay(2000); } void loop() { // 填充黑色矩形覆盖旧RPM数据,避免残留 tft.fillRect(50, 20, 80, 20, ST7735_BLACK); if (myELM327.nb_rx_state == ELM_SUCCESS) { rpm = (uint32_t)myELM327.rpm(); // 修正:直接调用myELM327.rpm()获取数据 DEBUG_PORT.print("RPM: "); DEBUG_PORT.println(rpm); // 将RPM转为字符串 char rpm_str[10]; itoa(rpm, rpm_str, 10); // 显示RPM标签和数值 print_text(10, 20, "RPM:", 2, ST77XX_WHITE); print_text(50, 20, rpm_str, 2, ST77XX_GREEN); } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) { myELM327.printError(); // 屏幕显示错误信息 char error_str[30]; snprintf(error_str, sizeof(error_str), "Error: %d", myELM327.nb_rx_state); print_text(10, 80, error_str, 1, ST77XX_RED); } delay(100); // 适当延长延迟,平衡刷新率和性能 }
关键修改点说明
- 测试代码修复:将
int temperature改为float temperature,并在循环内添加屏幕更新代码(如每次递增后调用print_text并刷新) - 错误提示显示:在OBD连接失败的分支中,清屏后显示红色错误信息
- RPM实时更新:每次loop中用黑色矩形覆盖旧RPM区域,再绘制新数值,避免文本重叠
- 数据获取修正:原代码中
tempRPM未定义,改为直接调用myELM327.rpm()获取RPM数据 - 延迟调整:将loop中的
delay(10)改为delay(100),减少屏幕刷新频率,避免ESP32资源占用过高
内容的提问来源于stack exchange,提问作者Learner4491
相关产品推荐
相关产品推荐

