
1. 项目概述一个能显示动态二维码的“智能工牌”几年前我在参加一个大型技术峰会时遇到了一个尴尬又普遍的问题名片带少了。当你想和一位新认识的同行交换联系方式时要么是对方没带名片要么是自己名片发完了最后往往只能掏出手机笨拙地互相搜索、添加社交账号在嘈杂的环境里反复确认ID是否输对。那一刻我就在想如果每个人胸前挂着的那个工牌不只是一个印着名字和公司的塑料片而是一个能随时展示动态个人二维码的屏幕那该多方便。这就是“QR Display Badge”项目的核心构想。它本质上是一个微型、可穿戴的电子显示设备外形和尺寸与传统工牌或门禁卡套相似但其核心是一块低功耗的电子墨水屏或小型LCD屏用于实时显示一个可刷新的二维码。这个二维码可以关联到你的个人主页、电子名片、社交媒体、会议日程、甚至是临时生成的会议室链接或Wi-Fi密码。它解决的不仅仅是“忘带名片”的问题更是将静态的身份标识升级为动态的、可交互的数字门户。这个项目非常适合硬件爱好者、创客或是任何希望将数字身份与物理载体进行有趣结合的人。它涉及嵌入式开发、低功耗设计、无线通信和简单的服务器端逻辑是一个综合性很强的练手项目。接下来我将从设计思路到代码实现完整拆解如何从零制作一个属于自己的“智能动态工牌”。2. 核心设计思路与方案选型制作一个可用的QR Display Badge我们需要在有限的体积和功耗下平衡功能、成本和续航。这就像给一辆微型赛车设计动力系统既要跑得快又不能半路没电。2.1 核心功能定义与需求拆解首先我们必须明确这个工牌需要做什么显示核心清晰、稳定地显示一个二维码图像。内容更新能够通过无线方式如蓝牙或Wi-Fi接收新的二维码信息并更新显示。低功耗运行在两次更新之间设备应处于极低功耗的休眠状态以保证数周甚至数月的续航。便携与耐用尺寸应接近普通工牌便于佩戴且有一定的结构强度。基于这些需求我们否决了使用高性能单片机驱动彩色LCD的方案因为其功耗对于需要长期佩戴的设备来说是灾难性的。我们的目光自然投向了电子墨水屏。2.2 为什么选择电子墨水屏电子墨水屏有几个无可替代的优势完美契合本项目超低功耗它只在刷新图像时消耗电能图像显示后无需供电即可保持。这意味着我们的设备99%的时间都可以在深度睡眠中度过极大地延长了电池寿命。强光可视类似于纸质印刷品依靠环境光反射在阳光下反而更清晰非常适合展会、户外等场景。视觉友好无背光不闪烁长时间观看不易疲劳。当然它也有缺点刷新速度慢通常需要1-3秒且早期屏幕在刷新时会有明显的全屏闪烁“鬼影”。但对于一个几分钟甚至几小时才更新一次二维码的工牌来说刷新慢完全不是问题。针对“鬼影”我们可以通过优化驱动波形和定期进行全局刷新来缓解。2.3 主控与通信方案选型主控芯片需要足够“聪明”以处理图像生成和通信协议又要足够“节俭”以控制功耗。ESP32系列这是我们的首选。以ESP32-C3或ESP32-S3为例它们内置Wi-Fi和蓝牙LE单芯片即可解决通信问题。特别是其丰富的低功耗模式在深度睡眠下电流可低至10μA左右。同时它拥有足够的计算能力来运行二维码生成算法。nRF52840如果你更侧重蓝牙连接和极致的低功耗这是一个专业的选择。但它通常需要外接芯片来实现Wi-Fi增加了复杂性。普通Arduino通信模块例如ATmega328P搭配ESP8266或HC-05蓝牙模块。这种方案成本可能略低但开发复杂度、功耗控制和体积都会面临更大挑战。综合来看ESP32-C3是一个平衡点性价比高功耗控制优秀双模无线社区支持完善。因此本项目将基于ESP32-C3进行展开。2.4 供电与结构设计考量电池一块小容量的锂聚合物电池如200mAh-500mAh是理想选择。它体积小、重量轻、能量密度高。配合ESP32的深度睡眠即使每天更新数次二维码续航数周也轻而易举。充电集成一个微型USB-C或磁吸充电接口。考虑到美观和防水磁吸充电是更优雅但成本稍高的方案。结构可以使用3D打印外壳。外壳设计需要预留屏幕开口、充电接口、复位按钮并考虑如何固定电池和主板。一个巧妙的设计是做成“卡套”式背面可以插入真正的工牌或名片。3. 硬件清单与电路连接详解工欲善其事必先利其器。以下是制作一个基础版QR Display Badge所需的全部硬件以及它们如何“对话”。3.1 核心部件采购清单部件名称推荐型号/规格数量备注主控芯片ESP32-C3开发板模组1推荐带USB-C接口的迷你开发板如Seeed Studio XIAO ESP32C3。电子墨水屏2.9英寸黑白/三色1分辨率296x128带SPI接口。三色黑/白/红可显示更醒目的信息。电池3.7V 锂电池1容量300mAh左右尺寸需与外壳匹配。充电管理模块TP4056微型模块1负责安全地为锂电池充电。电源开关微型拨动开关1用于彻底断电。结构件3D打印外壳1套包含前盖、后盖可能还有屏幕保护亚克力板。连接线杜邦线母对母若干用于初期原型连接。后期可用焊锡直接连接。注意选择电子墨水屏时务必确认其驱动IC型号如SSD1680、UC8151D。不同的驱动IC需要不同的库购买前最好在Arduino库管理器中搜索一下是否有对应的支持库。3.2 电路连接原理与实操接线整个系统的电力与信号流向是这样的锂电池通过TP4056模块充电并输出3.7V电压。这个电压一路直接供给电子墨水屏通常屏的驱动板自带3.3V LDO稳压另一路则通过一个开关再经过ESP32开发板上的稳压电路为ESP32芯片提供电力。数据则通过SPI总线在ESP32和屏幕之间传输。下面是以ESP32-C3以XIAO ESP32C3引脚为例连接一款常见SSD1680驱动IC的2.9寸屏的接线表电子墨水屏引脚连接到 ESP32-C3 引脚功能说明VCC3.3V电源正极接ESP32的3.3V输出GNDGND电源地DIN (MOSI)D4 (GPIO6)SPI数据输入主出从入CLK (SCK)D5 (GPIO7)SPI时钟信号CS (SS)D6 (GPIO8)片选低电平有效DC (D/C)D7 (GPIO9)数据/命令选择RST (RESET)D8 (GPIO10)复位引脚低电平复位BUSYD9 (GPIO3)忙状态指示高电平表示屏幕忙接线实操要点先断电操作在连接任何线路前确保电池未连接USB未供电。电源分离先将ESP32与屏幕的GND连接好再连接VCC。确保电源极性绝对正确反接极易烧毁屏幕。SPI引脚确认ESP32的SPI引脚是硬件定义的但也可以软件模拟。上表使用的是XIAO ESP32C3的硬件SPI引脚能获得最佳性能。如果你用的其他开发板需要查阅其引脚图找到对应的MOSI,SCK,CS等引脚。BUSY引脚的重要性务必连接BUSY引脚。屏幕刷新需要时间在此期间BUSY引脚会拉高。程序必须检测这个引脚等待其变低后才能发送下一条指令否则会导致通信混乱和显示异常。这是我早期调试时忽略而导致屏幕“卡死”的教训。4. 软件开发与环境搭建硬件是躯体软件是灵魂。我们将使用Arduino IDE来编写和上传代码因为它对ESP32和各类显示库的支持非常友好。4.1 开发环境配置步骤安装Arduino IDE从官网下载并安装最新版。添加ESP32开发板支持打开文件-首选项在“附加开发板管理器网址”中输入https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json打开工具-开发板-开发板管理器搜索“esp32”安装“Espressif Systems”提供的ESP32平台。安装必要的库GxEPD2这是一个功能强大、支持多种墨水屏的库。在项目-加载库-管理库中搜索并安装。QRCode用于生成二维码位图。同样在库管理中搜索安装。WiFi和WebServerESP32内置无需额外安装。4.2 核心代码逻辑剖析代码主要分为三大部分二维码生成与显示、Wi-Fi连接与Web服务器、低功耗管理。第一部分二维码生成与显示这是最核心的功能。我们利用QRCode库将字符串如一个网址编码成二维码矩阵然后将其绘制到墨水屏的帧缓冲区中。#include GxEPD2_BW.h // 假设使用黑白屏 #include qrcode.h // 定义你的屏幕型号例如 GxEPD2_290_T94 GxEPD2_BWGxEPD2_290_T94, GxEPD2_290_T94::HEIGHT display(...); void displayQRCode(const char* qrText) { // 创建二维码对象 QRCode qrcode; uint8_t qrcodeData[qrcode_getBufferSize(3)]; // 版本3的二维码 qrcode_initText(qrcode, qrcodeData, 3, ECC_LOW, qrText); // 计算二维码在屏幕上的起始位置使其居中 int qrSize qrcode.size; int scale min(display.width(), display.height()) / (qrSize 2); int offsetX (display.width() - qrSize * scale) / 2; int offsetY (display.height() - qrSize * scale) / 2; display.firstPage(); do { display.fillScreen(GxEPD_WHITE); // 清屏为白 // 遍历二维码矩阵黑色模块画黑方块 for (int y 0; y qrSize; y) { for (int x 0; x qrSize; x) { if (qrcode_getModule(qrcode, x, y)) { display.fillRect(offsetX x * scale, offsetY y * scale, scale, scale, GxEPD_BLACK); } } } } while (display.nextPage()); display.hibernate(); // 进入休眠模式省电 }这段代码的关键在于qrcode_initText函数它决定了二维码的版本和容错等级。版本越高能存储的信息越多但二维码点阵越大。对于普通的个人主页链接版本3通常足够。第二部分Wi-Fi与Web服务器为了让手机能方便地更新二维码内容我们在ESP32上内置一个简单的Web服务器。当手机连接到ESP32发出的Wi-Fi热点或ESP32连接家庭Wi-Fi后通过IP访问时会看到一个表单输入新的网址后提交即可更新工牌显示。#include WiFi.h #include WebServer.h // 方式1ESP32作为热点AP模式 const char* ap_ssid QRBadge-AP; const char* ap_password 12345678; // 建议设置密码 WebServer server(80); String currentQRText https://your-default-link.com; void handleRoot() { String html form action/update methodPOST; html New QR Code URL: input typetext nameqrtextbr; html input typesubmit valueUpdate Badge; html /form; server.send(200, text/html, html); } void handleUpdate() { if (server.hasArg(qrtext)) { currentQRText server.arg(qrtext); displayQRCode(currentQRText.c_str()); // 调用显示函数 server.send(200, text/plain, QR Code Updated!); // 更新后可以进入深度睡眠 esp_deep_sleep_start(); } } void setup() { // ... 屏幕初始化 WiFi.softAP(ap_ssid, ap_password); server.on(/, handleRoot); server.on(/update, HTTP_POST, handleUpdate); server.begin(); }这里有一个重要的取舍AP模式虽然方便手机直接连接但ESP32在作为热点时功耗相对较高。另一种更省电的模式是Wi-Fi STA 深度睡眠唤醒。即工牌大部分时间深度睡眠每隔一段时间如每小时唤醒连接到你预设的家庭Wi-Fi检查服务器上是否有新的二维码指令。这需要你有一个始终在线的服务器甚至可以是内网穿透的但续航可以长达数月。第三部分低功耗管理为了实现超长续航我们必须让ESP32在显示完二维码后立刻进入深度睡眠模式。在这种模式下除了RTC实时时钟和少数几个用于唤醒的GPIO其他电路全部关闭功耗极低。// 在setup()的最后或完成一次显示更新后 void goToDeepSleep() { Serial.println(Entering deep sleep); // 设置唤醒源例如通过GPIO0上的按键唤醒外部唤醒 // esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0); // 低电平唤醒 // 或者定时唤醒内部唤醒单位微秒 esp_sleep_enable_timer_wakeup(3600 * 1000000ULL); // 休眠1小时 delay(100); // 等待串口发送完成 esp_deep_sleep_start(); // 进入深度睡眠 }在深度睡眠下所有变量都会丢失。如果你需要保存当前的二维码内容必须在睡眠前将其写入ESP32的RTC存储器或Preferences中唤醒后再读取。#include Preferences.h Preferences preferences; void saveQRText(String text) { preferences.begin(qrbadge, false); preferences.putString(qrtext, text); preferences.end(); } String loadQRText() { preferences.begin(qrbadge, true); String text preferences.getString(qrtext, https://default.com); preferences.end(); return text; }5. 外壳设计与组装工艺一个精致的外壳能让项目从“实验板”升级为“可佩戴的产品”。使用3D打印是最佳选择。5.1 3D建模要点你可以使用Fusion 360、Tinkercad等工具进行设计。设计时需注意精确测量用游标卡尺测量你的屏幕模组、ESP32开发板、电池和充电模块的精确尺寸并预留0.2-0.3mm的装配公差。分层结构外壳通常分为前盖和后盖。前盖需要开一个与屏幕显示区域完全一致的窗口。可以在窗口内侧设计一个凹槽用于嵌入一片透明的亚克力板来保护屏幕。固定柱与卡扣设计螺丝柱或卡扣结构来固定主板和电池。对于电池可以使用双面胶或设计一个带盖板的电池仓。接口开口为USB-C充电口、复位按钮等预留开口。佩戴方式可以在后盖上设计一个别针卡槽或者直接做一个穿绳孔。5.2 打印与后处理材料推荐使用PLA或PETG。PLA容易打印PETG强度更高、更耐热。层高选择0.15mm或0.12mm的层高可以获得更光滑的表面尤其是显示窗口的边缘。支撑对于悬空结构如固定柱的顶部需要生成支撑。记得在切片软件中仔细检查。组装打印完成后小心地去除支撑。先进行“干装配”即不接线把所有零件放进去看看是否合适。确认无误后再开始焊接和固定内部元件。建议使用尼龙螺丝或塑料卡扣避免金属短路。6. 功能扩展与优化思路基础版本完成后你可以根据兴趣添加更多酷炫功能多信息分页显示通过增加一个按钮让屏幕可以在二维码、姓名/职位、实时天气、会议倒计时等信息之间切换。这需要修改代码管理多个显示页面。蓝牙LE广播除了显示二维码ESP32还可以通过蓝牙LE广播一个包含同样链接的Eddystone URL信标。这样附近开启蓝牙的手机即使不扫码也可能在通知栏收到你的个人主页链接提示。电池电量显示在屏幕角落用一个小图标或文字显示剩余电量百分比。这需要读取电池电压通过ESP32的ADC引脚并根据电池放电曲线进行换算。自动亮度调节虽然墨水屏不需要背光但你可以增加一个光线传感器在环境光暗时将二维码周围的背景色变为黑色如果屏幕支持以提高对比度对于三色屏。云端同步开发一个简单的手机App或网页二维码内容保存在云端。工牌每次唤醒后同步云端数据实现跨设备、跨地点的内容管理。7. 常见问题与故障排除实录在制作过程中你几乎一定会遇到下面这些问题。这里是我踩过坑后的经验总结。问题现象可能原因排查步骤与解决方案屏幕全白/全黑无任何显示1. 电源未接通或接反。2. SPI引脚接错。3. 屏幕初始化代码不对驱动IC型号不匹配。1. 用万用表检查屏幕VCC和GND间是否有3.3V电压。2. 逐一核对DIN, CLK, CS, DC, RST, BUSY引脚连接。3. 确认GxEPD2库中初始化对象的型号与你购买的屏幕完全一致。二维码显示错乱、残缺1. 帧缓冲区数据错误。2. 未等待BUSY信号。3. 二维码版本过低信息溢出。1. 检查displayQRCode函数中的绘图逻辑特别是fillRect的坐标计算。2. 确保在每次发送刷新指令后都有检测BUSY引脚状态的延迟或循环等待。3. 尝试提高qrcode_initText中的二维码版本号如从3改为5。ESP32无法进入深度睡眠或唤醒后程序不运行1. 唤醒源配置错误。2. 某些引脚在睡眠时保持上拉/下拉导致电流过大。3. 程序从头开始运行但未恢复保存的数据。1. 检查esp_sleep_enable_timer_wakeup或ext0_wakeup的参数是否正确。2. 在睡眠前将未使用的GPIO设置为输入模式并禁用上拉下拉。3. 在setup()函数开头调用loadQRText()读取保存的数据并判断是否是深度睡眠唤醒esp_sleep_get_wakeup_cause()。Web服务器能连接但无法提交数据1. 表单action路径或方法错误。2. 服务器处理函数未正确解析POST参数。3. ESP32内存不足处理请求时崩溃。1. 检查HTML表单中的action“/update”和method“POST”。2. 确保handleUpdate函数使用server.hasArg和server.arg来获取参数。3. 优化代码减少全局变量使用String时注意避免内存碎片。对于复杂应用考虑使用异步Web服务器。电池续航远低于预期1. 未成功进入深度睡眠。2. 屏幕刷新过于频繁。3. 外设如LED未断电。1. 用万用表串联测量深度睡眠时的整机电流应低于100μA。如果过高按上一条排查。2. 确保只有在需要时才调用display.nextPage()和display.hibernate()。3. 检查开发板上是否有常亮的电源LED必要时可物理移除或通过代码控制其关闭。一个关键的实操心得在焊接所有元件之前一定要先在面包板上完成全部功能的原型验证。确认屏幕能显示、Wi-Fi能连接、代码逻辑正确后再进行焊接和组装。焊接时优先焊接电源和地线并再次确认没有短路。给主板和屏幕供电前可以先用一个可调电源限流比如100mA观察电流是否异常这能有效避免因接线错误导致的“烟花”。制作QR Display Badge的过程是一个典型的软硬件结合项目。它考验了你对低功耗设计的理解、嵌入式编程的功底以及解决实际问题的耐心。当这个小小的工牌成功显示出一个属于你自己的、可以随时更新的二维码时那种将创意变为实物的成就感是纯软件项目难以比拟的。它不仅仅是一个工具更是一个有趣的社交媒介和技术名片向他人展示着你动手创造的能力。