ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ESP8266驱动2.13寸墨水屏教程:从接线到低功耗天气站实战

ESP8266驱动2.13寸墨水屏教程:从接线到低功耗天气站实战 2.13寸电子墨水屏HINK-E0213加一片esp8266能干什么我的答案是一个扔在桌上三个月不用充电的信息屏。这块组合我用了小半年从最初的hello world到现在稳定跑每天的天气和日程中间踩了不少坑这篇文章就把整套东西从头到尾讲清楚包括选型、接线、驱动、联网刷新和排查方法。如果你也想做一个墨水屏天气站、待办牌、智能家居状态面板直接照这个路子走能省好几个晚上的折腾工夫。1. 这套组合能做什么从场景倒推选型逻辑1.1 什么场景适合用“墨水屏ESP8266”先说结论墨水屏不是用来替代普通屏幕的它解决的是“显示内容要长期保留、但刷新频率不能太高”的需求。最常见的几个落地场景一个是桌面天气站每天早上自动刷新当天温度和降雨概率一个是待办事项牌配合手机或者后端服务把任务推送到屏幕再一个就是智能家居的状态面板比如显示门锁状态、空气净化器的PM2.5数值、鱼缸水温这一类低频变化的数据。为什么要用墨水屏而不是一块小LCD原因很直接LCD必须持续供电才能维持显示哪怕你只是显示一个静态数字背光、驱动电路、刷新电路都在悄悄耗电。墨水屏不一样它是双稳态显示断电之后屏幕上的画面对比度几乎不变化。我实测过如果用普通ST7789 LCD做一个小信息牌哪怕做了休眠几天不充电电池就见底换成HINK-E0213墨水屏在每天刷新几次的前提下一颗18500锂电池能跑一个多月如果只刷新一次续航轻松按季度计算。另外墨水屏在阳光下非常清晰没有背光眩光晚上看不刺眼。放在窗边、客厅茶几上都有不错效果。当然缺点也明显刷新慢、不能播放动画、全刷时有闪烁这些后面会详细讲。所以结论就是凡是“长时间显示、偶尔变化”的信息终端都是墨水屏的主场。1.2 为什么偏偏是HINK-E0213一块“够用”的屏市面上的电子墨水屏从1.54寸到7.5寸、13.3寸都有我选HINK-E0213有几点很实际的考量。首先是尺寸2.13英寸可视面积大概跟一张名片的一角差不多放天气、日期、三行文字刚刚好做成桌面摆件不占地方分辨率是常见的250×122做简单图形和文字排版完全够用放大字号也不会有明显颗粒感。其次是接口HINK-E0213走SPI总线标准四线SPICLK、DIN、CS、DC外加RST复位和BUSY忙信号。SPI的好处是几乎任何单片机都能驱动引脚占用少esp8266的GPIO数量本身就不富裕一个屏幕吃掉六个引脚正好卡在可接受范围。如果换7.5寸那种大屏虽然显示内容多但驱动时序更复杂刷一帧要好几秒对battery供电和代码调试来说都是额外的坑。再一个原因就是厂商资料和社区支持。HINK这个系列的屏资料相对全驱动芯片SKU大多用的是SSD1680或者同架构芯片Arduino生态里的GxEPD2、U8g2库直接支持。我自己这片HINK-E0213就是SSD1680驱动库里面套上模板类就能跑不需要自己抠寄存器级命令这对新手来说非常友好。顺便强调一下2.13寸实际上有250×122和212×104两种常见分辨率买之前一定要让卖家确认好驱动IC和分辨率不然接上代码后显示缺行缺列排查起来很费劲。1.3 ESP8266三块钱的联网核心esp8266这颗芯片已经火了很多年核心原因就是便宜、有WiFi、生态成熟。模块价格几块钱到十几块钱不等常见的NodeMCU开发板带USB转串口、带稳压电路、带LDO插上数据线就能在Arduino IDE里写程序对新手特别友好。对比几种方案如果用Arduino Uno你得额外挂ESP-01模块才能联网两套系统之间通信还要折腾串口或者AT指令结构复杂而且AT固件占用串口上报调试信息都费劲如果直接用ESP32性能是更强但价格翻倍、功耗也相对高对这个“显示固定信息”的项目来说性能严重溢出。esp8266跑在80MHz或160MHzFlash至少1MBRAM足够容纳JSON解析和字体缓冲驱动墨水屏绰绰有余。另外esp8266的GPIO虽然不多但SPI接口是完整支持的硬件SPI可以挂HINK-E0213这种SPI设备这正是很多人问的“esp8266模块能不能连SPI接口芯片”——答案当然是能只要把引脚对应好、电平匹配好完全可以稳定通信。后面接线部分我会给出具体的GPIO映射。2. 接线与硬件准备把屏和板子先握上手2.1 引脚对应关系与接线表HINK-E0213墨水屏模组一般引出8个引脚VCC、GND、DIN、CLK、CS、DC、RST、BUSY。我这里以最常用的NodeMCU / WeMos D1 Mini为例给出接线方案。注意D1 Mini引脚上的D1、D2这些编号是板子丝印不是ESP8266的GPIO号两者不能搞混写代码时用的是GPIO编号。我用的接线如下表墨水屏引脚功能D1 Mini引脚丝印ESP8266 GPIOVCC电源正3.3V3V33.3VGND电源地GGNDDINSPI数据输入MOSID7GPIO13CLKSPI时钟SCLKD5GPIO14CS片选低有效D8GPIO15DC数据/命令选择D1GPIO5RST复位低有效D2GPIO4BUSY忙信号高电平忙D6GPIO12有两点需要特别提醒。第一DC和RST尽量不要复用其他通信接口的引脚尤其不要和串口TX/RX冲突否则你在调试时打印串口日志屏幕会跟着乱跳。第二CS脚一定要接不能直接拉低省事因为ESP8266的硬件SPI可能同时挂在闪存上片选混乱会导致命令发不进去或者显示花屏。2.2 供电、电平匹配与上电时序墨水屏虽然静态功耗极低但刷新瞬间电流一点不小。我实测过HINK-E0213驱动SSD1680刷新一帧的峰值电流大约在30mA到50mA如果同时WiFi发送数据esp8266的射频峰值电流能到300mA级别。所以最好不要用一个AMS1117之类的线性稳压芯片硬扛建议3.3V侧放一个100uF电解电容和0.1uF陶瓷电容并联确保瞬间掉压下不会导致esp8266复位重启。上电时序也要注意。ESP8266的GPIO在上电瞬间可能是浮空或不定态可能通过DC、RST这些引脚把墨水屏误触发。稳妥的做法是程序里先把这些引脚全部设置为OUTPUT并拉高再执行屏幕初始化。很多花屏事故不是代码逻辑问题是上电瞬间GPIO乱跳导致的。还有一个很多人忽略的点墨水屏模组的VCC别直接接5V。虽然有些屏带电平转换但HINK-E0213标准是3.3V逻辑和供电。esp8266的GPIO本身就是3.3V电平所以不需要额外加电平转换芯片直连即可。如果你是拿一个5V单片机去驱动中间必须加电平转换模块否则长期运行不仅信号不稳还可能烧屏。2.3 制作时的排线、焊接与固定技巧墨水屏模组一般有两种连接方式一种是焊死的排针或邮票孔另一种是FPC软排线加转接板。如果你买的是FPC版本插转接板时注意金手指朝向通常是金属面朝下插入锁扣插好后翻盖压紧。千万不要用蛮力拉扯软排线FPC很薄很容易撕裂内部走线一旦撕裂就是整条屏报废。我用D1 Mini做信息牌时外壳用的是普通的3D打印小盒子屏幕用双面胶固定在壳子前面板。这里有一个经验墨水屏表面是玻璃基板很脆固定时压力要分散双面胶贴在四角或边缘背板不要贴中间。接线我建议用杜邦线先验证确定没问题后再换成短直连或焊在洞洞板上。杜邦线接触不良是初学时最难排查的问题之一刷代码时屏幕偶尔花屏大概率就是某根杜邦线虚接。如果你打算长期用在户外或湿度大的环境可以在PCB和排线接口刷一层三防漆但注意不要覆盖屏幕表面也不要堵住FPC卡扣。3. 驱动原理与代码实现从初始化到显示第一帧3.1 电子墨水屏到底是怎么“画字”的简单来说墨水屏的显示屏内部是大量微胶囊颗粒每一个胶囊里同时含有带正电荷的黑色粒子和带负电荷的白色粒子。当我们在上下电极之间施加电场黑色粒子和白色粒子就会向相反方向移动从而让某个像素呈现黑色或白色。电场撤销之后粒子因为静电力和粘滞阻力停在原位画面不会消失这就是双稳态显示的原理。这也是墨水屏两个核心特征的来源一是静态显示几乎不耗电维持画面只需要保持浮空或零电位二是刷新慢因为粒子物理移动需要时间一般全刷需要1到2秒局部刷新能快一些但仍有延迟。SSD1680这个驱动IC内部带LUT查找表其实就是一组精心设计的电压时序驱动IC会按照LUT自动控制电极电压MCU只需要把像素数据写入RAM再发命令触发更新即可不需要CPU一直去翻转电平。理解这个概念很重要因为后面排查问题时很多现象都要回到“粒子需要时间移动”这个物理本质上来解释比如局部刷新次数多了残影为什么越来越重。3.2 用GxEPD2库把屏幕点亮我推荐直接用GxEPD2库它在Arduino生态里维护很活跃对SSD1680驱动支持很成熟。先打开Arduino IDE的库管理器搜索GxEPD2安装即可同时建议一起安装Adafruit GFX库因为GxEPD2的绘图接口基于GFX画线、画圆、画矩形、设置字体都会用到。安装完成后代码结构大概是这样的#include GxEPD2_BW.h #include Fonts/FreeMonoBold12pt7b.h // 根据你手里的屏体选模板类250x122、SSD1680 常见配置如下 // 如果你的屏是 212x104、IL3897或SSD1680请到GxEPD2头文件里找对应类 #define EPD_CS 15 #define EPD_DC 5 #define EPD_RST 4 #define EPD_BUSY 12 GxEPD2_BWGxEPD2_213_B74, GxEPD2_213_B74::HEIGHT epd( GxEPD2_213_B74(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY) ); void setup() { Serial.begin(115200); epd.init(); epd.setRotation(1); epd.setFullWindow(); epd.fillScreen(GxEPD_WHITE); epd.setFont(FreeMonoBold12pt7b); epd.setCursor(30, 40); epd.print(Hello E-Ink); epd.setCursor(30, 80); epd.print(HINK-E0213); epd.display(); } void loop() { // 保持空白或者安排定时刷新 }这里有个容易踩的坑GxEPD2的工作模式有两种。一种是firstPage()/nextPage()分页模式适合复杂的页面缓冲另一种是setFullWindow()fillScreen()直接绘图再display()适合我这种内容简单的场景。新手别把两种模式混着用否则画面会闪烁两次甚至出现“只显示半帧”的奇怪现象。初始化时先调用epd.init()它会复位屏幕、读取一些状态并加载内置波形。随后setRotation(1)把屏幕方向从横变竖这是为了让2.13寸这种偏正方形的屏更适合显示竖向信息。如果你发现文字方向不对把参数改成0、1、2、3逐个试一遍即可这是最笨但也最有效的办法。3.3 显示中文、图形与图片绕不开的字库和取模Arduino自带的GFX字体默认是拉丁字符直接显示中文会变成豆腐块。解决中文显示有三个路子第一用全字库芯片或者SD卡里的字库文件第二把要用的汉字预先取模做成数组放进代码第三用U8g2库挂载中文字库。在esp8266这种Flash不太大的板子上我建议用“预取模”方案。比如你要显示“温度”“湿度”“天气”这几个词每个字抠出一个16×16点阵的字节数组大概需要32字节一个字几十个汉字也不过几百字节完全无压力。取模工具我用过PCtoLCD2002也有在线版本注意设置为“纵向取模、字节正序”字模顺序和驱动库的矩形填充方式要对上否则字是“反”的。显示图片的原理类似先把图片在电脑上缩小到250×122像素以内转成1位BMP或者1字节像素数据再用取模软件转成数组最后调用drawBitmap()方法。实际操作时一个小技巧是先在PC上把图片转成C语言数组然后在Arduino里用const uint8_t image[] PROGMEM保存这样可以大大减少RAM占用因为esp8266的RAM很宝贵大数组放内存里很容易崩溃。3.4 驱动IC的初始化流程SSD1680如果你不想用GxEPD2想自己写驱动那么理解SSD1680的寄存器级初始化流程也很有必要。常见序列大概是发送0x12软件复位命令等待至少10ms配置驱动输出控制寄存器0x01设置扫描方向、源极/栅极数量配置数据入口模式0x11确定地址自动递增方向设置RAM的X/Y起始和结束地址0x44和0x45配置边框波形0x3C、显示更新控制0x21通过0x22选择更新模式再发0x20触发驱动动作等待BUSY引脚拉低表示更新完成。这些寄存器值不是随便填的要和屏体的物理行列数严格对应。比如250×122的屏X方向是250个点Y方向是122个像素RAM地址范围写错了屏幕很可能会出现“只剩一半画面”或者显示内容错位。很多非正规厂家给的初始化代码彼此有细微差别最可靠的做法是直接找屏体厂商FAE要SDK或者下载同型号的官方例程对照。4. 实战做一个每天自动更新的天气信息屏4.1 整体流程与代码结构我手头的天气站需求很简单每天早上8点和晚上8点各刷新一次显示日期、城市、当前温度、天气现象、最高最低温。整套程序的流程可以拆成四步开机、联网请求天气数据、解析JSON、刷新墨水屏、进入休眠。流程图不用记心里有个顺序就行setup()里先初始化串口和墨水屏然后连接WiFi请求天气API拿到数据后解析绘制到屏幕最后display()并休眠loop()里可以什么都不做或者用定时器安排每隔几小时重新走一遍流程。我建议第一次跑通时先把网络和屏幕分开调试。先用一个最简单的程序单独测试屏幕能不能显示“Hello”再用另一个程序单独测试能不能从API拿到数据并串口打印出来最后再把两者合并。这样一旦有问题你能很快定位是网络问题还是屏幕问题。4.2 联网获取天气数据esp8266联网本身不复杂核心是WiFi.begin(ssid, password)然后等待WiFi.status() WL_CONNECTED。天气API我用的是和风天气的免费接口直接通过HTTPS或者HTTP请求一个JSON地址里面包含当前温度、天气代码、湿度等信息。如果你不想注册账户也可以用OpenWeatherMap的免费key效果类似。请求和解析的关键代码如下#include ESP8266WiFi.h #include ESP8266HTTPClient.h #include ArduinoJson.h const char* ssid 你的WiFi; const char* password 你的密码; const char* weatherUrl https://你的天气API地址location101010100; void fetchWeather() { WiFiClient client; HTTPClient http; http.begin(client, weatherUrl); int httpCode http.GET(); if (httpCode ! HTTP_CODE_OK) { Serial.println(HTTP请求失败); http.end(); return; } String payload http.getString(); http.end(); StaticJsonDocument1024 doc; DeserializationError err deserializeJson(doc, payload); if (err) { Serial.println(JSON解析失败); return; } // 具体字段按API返回结构调整 const char* text doc[now][text]; float temp doc[now][temp]; Serial.printf(天气: %s, 温度: %.1f\n, text, temp); }这里有几个常见问题一是WiFi连接失败esp8266默认会一直重试如果路由器不可达程序会卡在WiFi.begin里建议加一个超时逻辑比如20秒没连上就进入休眠下次再试二是HTTP响应体可能很大StaticJsonDocument开小了会导致解析失败按API返回的实际大小调整三是不要在loop()里每秒钟发一次HTTP请求会被服务商限流也会导致模块过热。4.3 界面布局与刷新策略2.13寸屏分辨率不高排版一定要克制。我的首选布局是顶部一行大字显示当前温度中间一行显示天气文字下面一行小字显示日期和最高/最低温。用GxEPD2画个简单表格线或者圆角矩形框也可以提升质感但不要贪多内容一旦拥挤墨水屏刷新慢、残影重的问题会被放大。刷新策略里最重要的是“能不能不刷就不刷”。比如我设置每天8点和20点刷新但如果晚8点请求失败我不会立刻重试而是直接等下一个刷新周期。原因是墨水屏每次刷新都是寿命磨损虽然几千次上百万次不至于但也没必要浪费而且WiFi请求失败、重试、再刷屏功耗会直线上升。另一个策略是全刷和局刷混合。日常更新温度数字时用局部刷新减少闪烁和等待每满10次局部刷新强制做一次全刷把累积的残影清洗干净。这个策略在长时间运行后尤为重要。4.4 低功耗优化从一夜掉电到十天不动如果你只是插着USB供电低功耗优化可以跳过但如果你像我一样用锂电池供电这里有几个关键动作。第一完成显示后调用epd.hibernate()或者epd.sleep()让驱动IC进入睡眠电流可以降到微安级第二显示完成后立即执行WiFi.disconnect()和WiFi.mode(WIFI_OFF)把射频完全关掉否则WiFi保持连接会一直耗电第三如果不介意每次重启做一次完整初始化可以直接用ESP.deepSleep(延时微秒)把整个esp8266睡死配合GPIO16D0接RST引脚实现定时唤醒。我实测过每天晚上只刷新一次用一节18650锂电池供电系统功耗稳定在“白天待机uA级、刷新时几十mA持续几秒”这个水平电池撑两个月很轻松。要注意的是深度睡眠唤醒后程序是从头开始的所以setup()里要做好断网重连、API重试等逻辑而且墨水屏在断电重启后内容不会丢这一点比LCD体验好太多。5. 常见问题与排查我踩过的坑你直接绕开5.1 屏幕花屏、乱码花屏的原因非常多但排名第一的是驱动IC型号和分辨率不匹配。我一开始买的HINK-E0213有250×122和212×104两种版本我直接套用了网上的一个212×104例程画面整个错位看起来像乱码。解决方法是先用官方SDK自带的例程点亮确认屏体参数再换到GxEPD2里选择对应模板类。第二个常见原因是电源问题。刷新时瞬间电流大如果USB线过长或者供电不足SPI信号会被拉垮表现为屏幕刷新到一半出现杂点。解决办法是在3.3V和GND之间加电容同时检查USB线是否过细或者直接改用5V 1A以上的适配器供电。第三个原因就是接线虚接。杜邦线用久了氧化或者FPC排线没插到底都会导致时序信号丢包。这种情况的花屏往往是偶发的一阵一阵的非常难查。我现在的做法是屏、板子和排线之间全部使用焊接或压接端子杜绝杜邦线用于长期运行。5.2 卡死在刷新流程程序执行到display()之后就一直不返回或者串口没有后续输出通常是BUSY引脚问题。SSD1680在刷新时会把BUSY拉高刷新完成拉低MCU必须轮询这个引脚。如果BUSY没接、接错GPIO或者对端引脚没有启用上拉/下拉驱动库就会死等。排查技巧先用万用表量一下BUSY引脚的电平屏幕空闲时应该是低电平。如果在空闲状态下测到高电平要么是引脚接错了要么是驱动IC没有初始化成功。此外GxEPD2库内部对超时有处理但如果你自己写驱动一定要给等待BUSY加一个超时阈值比如3秒没拉低就强制复位重来否则程序会永久挂死。另一个卡死原因是SPI速率设置过高。esp8266的硬件SPI确实能跑到20MHz以上但墨水屏模组走线长、FPC软排线也长速率太高容易误码。GxEPD2库默认SPI速率一般没问题如果发现偶发卡死可以手动把SPI时钟降到2MHz再测试。5.3 电压跌落导致重启这个现象很典型屏幕刷新到一半esp8266突然重启WiFi重新连接屏幕闪一下又回白。原因是刷新瞬间和WiFi射频瞬间叠加电流尖峰导致D1 Mini板载稳压器输出瞬间跌到3.0V以下芯片触发欠压复位。解决办法分三层硬件上在大电容稳压软件上在刷新前先关WiFi让刷新那几秒不要有射频占用时序上尽量让WiFi请求和墨水屏刷新前后错开不要在请求完数据的那一瞬间立刻刷新。如果带传感器或者OLED等其他外设也要逐个排查它们是否在刷新瞬间产生额外电流。我用18650供电时还遇到过电池保护板触发过流保护的情况那种是电池放电能力不够换一颗放电倍率高的电池就好了。5.4 残影严重墨水屏用久了会有上一帧画面的淡影尤其局部刷新用得多、刷新间隔短的情况下更明显。这是物理层面的现象完全消除不了但可以缓解。我的做法是每次局部刷新之前先做一个局部的清屏动作而不是直接写新内容每5到10次局部刷新之后强制一次全刷。全刷的过程会把所有粒子重新驱动一次残影基本消除。如果你发现全刷后还是有比较深的残影可能是刷新间隔太短导致粒子还没完全稳定就又开始下一次移动建议两次刷新之间至少间隔30秒以上。另外显示内容的布局尽量固定只更新变化区域残影也会轻很多。下面整理成速查表方便对照排查现象常见原因解决方向花屏、乱码驱动IC/分辨率不匹配确认屏体规格换对应模板类花屏、杂点供电不足或USB线太细加电容换电源和线材花屏、偶发接线/杜邦线虚接焊接固定检查FPC插接卡死BUSY引脚接错或没接测量电平修正GPIO映射卡死SPI速率过高降到2MHz以下重启刷新瞬间电流拉垮电源关WiFi加大电容换电池残影局部刷新过多、间隔太短定期全刷固定显示布局5.5 一个容易被忽略的坑刷写AT固件的选择有些朋友会把esp8266当成一个纯粹的WiFi透传模块刷AT固件后由外部MCU通过串口控制。这个思路没问题但选固件时要注意Flash容量和波特率版本网上各种编译版本鱼龙混杂如果固件版本和模块Flash型号不匹配会出现AT指令无响应或WiFi连接不稳定。更稳妥的做法是用AT指令先查询模块信息再对照官方release选择对应固件。如果你用的是NodeMCU这类开发板强烈建议直接用Arduino写原生代码把主控、WiFi、屏幕驱动放在同一个程序里省掉串口协议这一层。顺便说一句esp8266刷固件本身不难按住FLASH键再上电就能进入下载模式用esptool或Arduino IDE都能写。失败时多半是USB-TTL芯片驱动没装好或者串口号选错优先排查这两点。这块内容跟墨水屏项目关系不那么直接但很多初学者第一次接触esp8266就是在刷AT固件这一步被卡住我还是提醒一下。最后分享一个我自己的使用习惯给这个天气信息屏做了一根很短的排线外壳留了Micro USB充电口屏幕画面固定在每天早晚各更新一次。之前我总想着让它“实时刷新”误以为这样才高级后来才明白墨水屏这种设备真正的高级感是“平时像个印刷品需要时才电子化”。HINK-E0213加esp8266这套组合本质就是低功耗、长续航、远程更新的能力组合把这三个字想明白了很多衍生玩法就顺理成章了。后续我想把这块屏接到家里的MQTT服务器上做成一块能显示门锁状态、快递取件码、日历日程的小终端代码和结构都在往这个方向重构。你要是也想做类似的从这篇里挑一个最需要的功能入手先把屏幕点亮再慢慢往上加东西一定比我当初少走很多弯路。
返回列表