用一块串口屏点亮温湿度世界:从零搭建一个独立显示终端
你有没有过这样的经历?调试一个环境监测项目时,满脑子都在想:“要是能直接在设备上看到温度和湿度就好了。” 不用手持示波器抓波形,不用连电脑看串口助手,更不需要靠猜——数据就清清楚楚地摆在眼前。
今天,我们就来实现这个“小愿望”。不搞复杂的图形界面,也不上Linux系统跑Qt,只用最简单的硬件组合:一片DHT11传感器 + 一块串口字符型LCD + 一块Arduino(或任何MCU),打造一个完全脱离PC的本地显示终端。
整个过程就像写一段printf代码一样自然。但背后却藏着嵌入式开发中非常实用的设计哲学:如何用最少的资源,做最有效的事。
为什么选择“串口字符型LCD”?
先问一个问题:如果你要做一个带屏幕的小设备,第一反应是接个TFT彩屏吗?可能很多人会点头。但现实往往是——接线太多、驱动难调、内存吃紧、刷新卡顿……
而我们今天要聊的这位“配角”——串口字符型LCD,反其道而行之。
它长得像传统的1602/2004字符屏,但只需要三根线就能工作:VCC、GND、RX。没错,没有数据总线,没有RS/EN控制脚,甚至不需要读状态。你想显示什么,只要通过串口发一串字符串过去就行,比如:
Temp: 25.0 C Hum : 60.0 %模块内部已经集成了一个微控制器,负责把收到的ASCII字符转换成LCD指令,自动写入显示内存。你可以把它理解为“会说话的显示屏”——你说什么,它就显示什么。
它到底有多简单?
想象一下你在调试时常用的Serial.println("Hello World"),现在目标不是电脑串口监视器,而是这块小小的液晶屏。编程体验几乎零切换成本。
更重要的是:
- 接线?3根。
- 驱动?不用写。
- 初始化?上电即用。
- 测试?拿USB转TTL模块直连,敲命令就能出字。
这不就是理想中的“即插即用”外设吗?
DHT11:便宜又好用的入门级传感器
既然要显示温湿度,那数据从哪来?我们选了最常见的DHT11 数字温湿度传感器。
别看它精度一般(±2°C,±5%RH),响应慢(>2秒),但它胜在三个字:够简单。
- 单引脚通信,占用一个GPIO就够了;
- 输出的是已校准的数字信号,无需额外算法补偿;
- 成本低到几块钱一片,摔了也不心疼。
它的通信协议虽然对时序要求严格(典型的单总线半双工),但好在社区成熟,有现成库可用。比如 Adafruit 提供的DHT.h库,一句话就能读出温度:
float temp = dht.readTemperature();背后复杂的电平拉低、延时等待、位解析全被封装好了。你要做的,只是确保两次读取间隔大于2秒。
⚠️ 小贴士:DHT11电源端建议并联一个0.1μF陶瓷电容,抗干扰能力提升明显;长距离布线时,在数据线上加4.7kΩ上拉电阻也很关键。
硬件怎么连?越少越好
整个系统的物理连接极其清爽:
+--------------+ | | DHT11 ────────▶ GPIO4 | | | | Arduino | | (or MCU) | | | | UART TX ────▶ RX (LCD) +--------------+ │ GND │ 所有共地- DHT11 接任意数字引脚(这里用4号)
- LCD 模块的 RX 引脚接到 MCU 的 TX(可以是硬件串口或软串口)
- VCC 和 GND 全部共用同一电源(USB供电即可)
注意一点:有些串口LCD模块默认使用9600bps波特率,务必确认你的代码里.begin(9600)匹配一致。如果发现乱码,请优先排查波特率和共地问题。
软件逻辑:像打印日志一样更新屏幕
接下来是最轻松的部分——写代码。
我们不再需要操作RS、E、DB0~DB7这些寄存器级别的细节,也不用手动计算DDRAM地址。一切回归本质:输出文本。
下面是核心流程:
#include <SoftwareSerial.h> #include "DHT.h" // 定义引脚 #define DHT_PIN 4 #define DHT_TYPE DHT11 #define LCD_RX_PIN 2 // 连接到LCD的RX脚 DHT dht(DHT_PIN, DHT_TYPE); SoftwareSerial lcdSerial(0, LCD_RX_PIN); // 使用软串口发送 void setup() { Serial.begin(9600); // 调试用主串口 lcdSerial.begin(9600); // 给LCD发数据 dht.begin(); // 清屏 + 欢迎语 lcdClear(); lcdSerial.println("Starting..."); delay(1000); } void loop() { float t = dht.readTemperature(); float h = dht.readHumidity(); // 数据有效性检查 if (isnan(t) || isnan(h)) { updateDisplayWithError(); } else { updateDisplay(t, h); } delay(2000); // 每2秒刷新一次 }其中updateDisplay()函数就是纯粹的格式化输出:
void updateDisplay(float temp, float humi) { lcdClear(); lcdSerial.print("Temp: "); lcdSerial.print(temp, 1); lcdSerial.println(" C"); lcdSerial.print("Hum : "); lcdSerial.print(humi, 1); lcdSerial.println(" %"); }而清屏操作也很简单,发送一个特殊控制字符0x01即可:
void lcdClear() { lcdSerial.write(0x01); delay(2); // 给LCD留点处理时间 }是不是感觉像是在给另一个“串口终端”发消息?这就是串口LCD的魅力所在:把复杂的硬件交互,抽象成最熟悉的字符串输出。
实战避坑指南:那些手册不会告诉你的事
理论很美好,实际调试总有意外。以下是几个常见“坑”和应对策略:
❌ 问题1:LCD显示乱码或无反应
原因:波特率不匹配 或 未共地
✅ 解法:用万用表确认GND是否真正连通;尝试9600/115200等常用波特率逐一测试
❌ 问题2:偶尔出现“ERROR”提示
原因:DHT11通信失败导致返回NaN
✅ 解法:加入isnan()判断,并显示错误标识,避免屏幕上出现“Temp: nan C”
❌ 问题3:文字闪烁严重
原因:频繁清屏+重绘造成视觉闪动
✅ 解法:改用局部刷新策略,比如只更新数值部分(需支持光标定位命令)
✅ 高阶技巧:让显示更有“设计感”
很多串口LCD支持自定义命令,例如:
-\xFF\x01设置背光亮度
-\xFF\x02关闭光标
-\xFF\x03\x08移动光标到第2行第8列
利用这些命令,你可以实现:
- 动态图标(用自定义字符画个水滴💧)
- 对齐优化(右对齐数值,提升美观度)
- 节能模式(夜间自动调暗背光)
为什么这个方案值得推广?
回到最初的问题:我们为什么要花时间做一个“只能显示两行文字”的设备?
因为它代表了一种极简主义的工程思维。
在真实的嵌入式产品开发中,很多时候并不需要炫酷的UI。你需要的只是一个能告诉你“当前状态正常”的反馈机制。这时候,串口字符型LCD就成了性价比最高的解决方案。
它特别适合以下场景:
- 工业控制柜的状态指示
- 农业大棚的本地环境监控
- 教学实验平台的数据可视化
- 原型验证阶段的快速反馈
而且它的扩展性很强。今天接的是DHT11,明天可以换成光照传感器、CO₂模块,甚至是Modbus从机读回来的数据。只要MCU能拿到值,就能显示出来。
甚至你可以把这里的“串口LCD”换成“WiFi串口模块”,数据就能上传云端;换成蓝牙模块,就能手机查看——底层显示逻辑几乎不用变。
写在最后:小改动,大效益
在这个追求“智能化”、“物联网化”的时代,我们很容易陷入技术堆叠的陷阱:一定要上RTOS?一定要跑GUI?一定要联网?
但有时候,真正的高效来自于克制。
就像这次我们做的项目:
3根线 + 1个传感器 + 几十行代码 = 一个看得见的智能节点
它不会画画,不能触控,也没有动画特效。但它稳定、可靠、易维护,最关键的是——开发者一眼就能看懂它在干什么。
这才是嵌入式系统的初心:让机器说话,让人听得懂。
如果你正在寻找一个既能练手又能落地的小项目,不妨试试用串口LCD点亮你的第一个独立显示终端。也许下一次会议上,你拿出来演示的那个小盒子,就会让大家眼前一亮。
如果你动手实现了这个项目,欢迎在评论区晒图交流!遇到了其他问题?也可以留言一起讨论。