1. 项目概述:一个会“说话”的智能药盒伴侣
如果你也像我一样,需要定时服用一些有严格时间要求的药物,比如饭前半小时、饭后两小时这种,那你肯定懂那种“到底吃没吃”的纠结和“是不是到点了”的焦虑。传统的闹钟提醒太生硬,手机提醒又容易被淹没在信息流里。我一直想做一个既有明确提示,又能轻松完成服药确认的小装置。直到重温了《超能陆战队》里那个圆滚滚、暖呼呼的大白,灵感来了——为什么不做一个“大白灯”呢?它平时安静地亮着白光陪伴你,一到服药时间就变个颜色提醒你,你只需要把贴了标签的药盒往它面前“碰”一下,它就恢复平静,表示任务完成。
这个“Baymax Lamp”智能药盒提醒灯,核心就是利用物联网(IoT)技术,把提醒、确认和状态反馈这三个动作串联起来。硬件上,它极其简单:一个能联网的ESP8266微控制器(比如NodeMCU)、一个RGB LED灯珠、几张NFC标签,再加上一些废旧材料做的外壳。软件层面,我们借助Adafruit IO这个免费的物联网平台来设置定时任务和接收确认信号。整个项目的魅力在于,它用最低的成本和最简单的电路,实现了一个非常实用的自动化流程,并且那个用废旧灯泡和泡沫做的“大白”造型,让冷冰冰的科技设备瞬间有了温度和情感。
无论你是刚接触Arduino的新手,想找一个有趣又实用的项目练手,还是已经有一定经验的Maker,想为家人定制一个贴心的健康小助手,这个项目都非常适合。它不涉及复杂的电路知识,编程部分也有完整的代码可以参考和修改,重点在于理解整个物联网数据流的逻辑。接下来,我会带你从零开始,一步步拆解思路、准备材料、焊接电路、配置云端,直到最终让这个可爱的“大白”开始为你工作。
2. 核心思路与系统架构解析
2.1 需求拆解与方案选型
做一个提醒装置,最朴素的想法可能就是用一个带时钟模块的单片机,到点让蜂鸣器响或者灯闪。但这个方案有几个痛点:首先,修改提醒时间需要重新编程并烧录,非常不灵活;其次,如何优雅地“确认”操作是个问题,加个按钮显得简陋,且无法区分是“看了提醒”还是“真的吃了药”。
因此,我决定引入物联网架构。它的优势很明显:
- 远程与灵活配置:通过云平台,我可以在任何有网络的地方,用手机或电脑修改提醒时间、增加或删除提醒项,无需触碰硬件。
- 丰富的交互可能:云平台可以作为中枢,连接不同的触发器和执行器。在这里,定时器和NFC触碰都是“触发器”,而RGB灯是“执行器”。
- 状态同步与记录:理论上,所有通过云端传递的指令和确认都可以被记录下来,便于后续查看服药历史(本项目未深入开发此功能,但架构为此留出了可能)。
基于这些考虑,我选择了Adafruit IO作为云平台。它免费、稳定,对Arduino生态支持极好,提供了直观的“Feed”(数据流)和“Dashboard”(仪表盘)概念,非常适合我们这种数据量小、逻辑简单的项目。硬件核心选用NodeMCU(ESP8266),因为它内置Wi-Fi,价格低廉,性能足以驱动一个RGB LED并维持网络连接。
2.2 系统工作流程详解
整个系统的工作流程,可以看作一个清晰的“事件-响应”链条。理解这个链条,是成功制作和后期调试的关键。
常态:“大白”的肚子(RGB LED)发出柔和的白光,表示系统待机,一切正常。
提醒阶段:
- 云端定时触发:我在Adafruit IO上设置了一个定时任务,比如每天上午9点。时间一到,这个任务会自动向一个名为“BAYMAX”的专属数据通道(Feed)发布一条消息,消息内容是一个数字,比如“1”(代表第一种药)。
- 设备监听与接收:始终连接着Wi-Fi和Adafruit IO的NodeMCU,实时监听着“BAYMAX”这个Feed。一旦发现新消息(数字“1”),它就立刻读取。
- 硬件执行提醒:NodeMCU根据预先写好的规则进行匹配:如果收到“1”,就让RGB LED显示红色;如果收到“2”,显示蓝色,以此类推。于是,“大白”的肚子就从白色变成了特定颜色,视觉提醒非常直观。
确认与复位阶段:
- 用户动作:我看到颜色提醒后,找到对应的药盒(上面贴有预先配置好的NFC标签),用手机贴近标签“碰”一下。
- NFC触发HTTP请求:手机上的自动化APP(如Macrodroid)会识别这个特定的NFC标签,并自动执行一个预设动作:向Adafruit IO的“BAYMAX” Feed发送一条HTTP POST请求,请求的内容是数字“0”。
- 云端转发与设备响应:Adafruit IO收到“0”这个消息,同样会即时推送给正在监听的NodeMCU。NodeMCU收到“0”后,执行复位操作:将RGB LED的颜色重新设置为白色。
- 循环等待:系统恢复常态,等待下一个定时触发事件到来。
这个流程的核心在于,Adafruit IO充当了唯一的信息中转站。无论是来自云端的定时信号,还是来自手机的NFC确认信号,都汇聚到这里,再统一分发给硬件设备。这种设计解耦了触发器和执行器,使得系统扩展性极强。例如,未来你可以很容易地增加一个按钮、一个网页开关,或者另一个传感器的信号作为新的触发器,它们只需要向同一个Feed发送不同的数字即可,硬件端的代码几乎无需大改。
注意:安全性考量:Adafruit IO的访问需要密钥(AIO Key)。在配置手机APP时,这个密钥会存储在手机端。虽然本项目是个人使用,风险极低,但请务必保管好你的Active Key,不要公开分享你的项目Dashboard链接,以防他人恶意干扰你的设备。
3. 硬件准备与“大白”身体制作
3.1 电子元件清单与选购要点
硬件部分非常简单,总共只需要几样东西,大部分都能在常见的电子商城或网购平台找到:
- NodeMCU ESP8266开发板 x1:这是项目的大脑。务必选择基于ESP-12E/F模块的版本,其Wi-Fi性能和稳定性较好。价格通常在15-25元人民币。
- 共阴极RGB LED灯珠 x1:这是“大白”的发光肚子。“共阴极”非常重要,意味着红、绿、蓝三个发光二极管的负极是接在一起的。购买时一定要问清楚。价格约1-2元。
- NFC标签贴纸 x N:建议购买NTAG213或215型号的空白标签,兼容性好,且手机APP通常支持对其编程。你需要几个药盒就买几个,单价在1-3元。
- Micro USB数据线 x1:用于给NodeMCU供电和烧录程序。随便找一根手机旧线即可。
- 5V/1A USB电源适配器 x1:项目完成后长期供电用。任何手机充电头都行。
- 杜邦线(母对母)若干:用于连接NodeMCU和RGB LED,3根就够,但多备一些无妨。
- 废旧LED灯泡 x1:这是“大白”肚子的完美灯罩。去找一个坏掉的LED球泡灯,最好是塑料散光罩的那种,容易拆卸且安全。
- 高密度泡沫板(或快递包装中的泡沫):用于制作“大白”的头、手、脚。厚度在2-5厘米为宜。
- 工具:美工刀、砂纸(粗细各一张)、热熔胶枪(或强力胶)、黑色油性记号笔、尺子。
3.2 手工制作“大白”的身体
让项目充满乐趣的关键一步,就是赋予它一个可爱的外形。这里完全利用废旧材料,既环保又有成就感。
3.2.1 制作发光肚子(灯罩)
安全第一!处理废旧灯泡时务必小心。
- 找到灯泡的塑料散光罩与金属/塑料底座的连接处。通常这里是用硅胶粘合的,并不牢固。
- 用一字螺丝刀或小刀,小心地插入缝隙,慢慢撬开。一定要戴手套,并远离面部,防止塑料碎裂飞溅。就像原作者说的,我一开始也没注意,结果手滑被划了个小口子。
- 撬开后,你会看到内部的LED灯板和驱动电路。用钳子或剪刀将这些电子元件全部拆除,只留下一个空的塑料灯罩。清理干净内部的灰尘和胶渍。
- 这个纯净的、乳白色的塑料罩,将成为“大白”那标志性的、光线柔和的肚子。
3.2.2 塑造身体部件
- 设计图纸:将清理好的灯罩倒扣在一张白纸上,用笔沿着边缘描出它的轮廓。这个圆形就是“大白”身体的中心。以此为基础,在纸上画出“大白”简单的外形:一个大圆(身体),上面一个小椭圆(头),两侧简单的弧形(手臂),下面两个小圆柱(腿)。不需要很精确,有个大致比例就行。
- 切割泡沫:根据图纸,用美工刀在高密度泡沫板上切出头部(椭圆饼状)、手臂(两个长条水滴形)和腿(两个短圆柱)的粗坯。身体部分不需要单独切,因为灯罩本身就是身体。
- 精细打磨:这是让“大白”从“粗糙”变“可爱”的关键。电影里的大白由充气材料制成,圆润光滑。我们需要用砂纸模拟这种质感。
- 先用粗砂纸(如80目)大胆地打磨掉切割留下的棱角,把边缘磨圆,把手臂磨出微微弯曲的弧度。
- 然后换细砂纸(如240目以上)进行精细打磨,让泡沫表面尽可能光滑,减少颗粒感。打磨时最好在通风处或戴上口罩,避免吸入泡沫粉尘。
- 组装与上色:
- 头部:用黑色油性记号笔在头部椭圆的正面上画两条短横线作为眼睛,中间画一条竖线连接。如果想更立体,可以像我做的那样,找两颗小珠子或塑料半球,涂黑后粘上去。
- 粘合:用热熔胶枪,将头部、手臂、腿粘到灯罩(身体)的相应位置。热熔胶干得快,粘合力强,非常适合泡沫材料。注意保持对称,并确保灯罩的开口朝下或朝后(用于后期放入LED)。
- 整体检查:粘合后检查是否牢固,并用细砂纸对胶缝处进行轻微修饰,使过渡更自然。
至此,一个憨态可掬的“大白”外壳就准备好了。它的内部是空心的灯罩,正好用来容纳和扩散RGB LED的光线。
4. 云端平台(Adafruit IO)配置详解
硬件准备好后,我们来搭建项目的“神经中枢”——Adafruit IO。这是连接定时触发、手机确认和硬件执行的关键桥梁。
4.1 账户创建与核心概念建立
- 访问
io.adafruit.com,点击“Get Started for Free”注册一个新账户。使用邮箱注册即可。 - 理解核心概念:Adafruit IO有两个最重要的概念:
- Feed(数据流):可以把它想象成一个专属的、有名字的“邮箱”。所有数据(比如我们项目里的数字1,2,3,0)都往这个邮箱里发送或从里面读取。在本项目中,我们只需要一个Feed。
- Dashboard(仪表盘):这是一个可视化面板,你可以把Feed的数据以图表、开关、滑块等形式放在上面,方便查看和控制。对于我们,主要是用它来创建和管理定时触发器。
4.2 创建Feed与Dashboard
- 登录后,点击顶部导航栏的“Feeds”,然后点击“New Feed”。
- 在创建页面,Name(名称)输入
BAYMAX(建议全大写,与代码中保持一致)。Description(描述)可以留空或简单填写。点击“Create”创建。提示:Feed的名称在后续编程和配置中会多次用到,保持统一可以避免很多因拼写错误导致的问题。
- 点击顶部导航栏的“Dashboards”,然后点击“New Dashboard”。
- 同样,Name输入
BAYMAX,点击“Create”。创建后,点击进入这个新的Dashboard。
4.3 获取访问密钥(AIO Key)
这是硬件和手机APP能够与你的Adafruit IO账户“对话”的密码,至关重要。
- 在Adafruit IO页面的右上角,点击你的用户名,在下拉菜单中选择“View AIO Key”。
- 你会看到一个弹出窗口,里面显示你的“Username”和“Active Key”(一长串字母数字混合的字符串)。
- 立即将这两项信息妥善保存到一个文本文件中。Active Key相当于你的账户密码,不要泄露,也不要上传到公开的代码仓库。
4.4 设置定时触发器(Scheduled Trigger)
这是实现“定时提醒”功能的核心配置。
- 在Adafruit IO页面顶部,点击“Actions”选项卡,然后点击“New Action”。
- 选择触发器类型:在“Choose a trigger”下,找到并点击“Scheduled”卡片上的“Choose this action”。
- 配置时间:
- Time Period: 选择“Hourly”。
- 下方会出现更详细的选项。选择“Every day at”,然后在后面的时间输入框中填入你的第一个服药时间,例如
09:00(代表上午9点)。注意使用24小时制。
- 配置动作:
- Then: 选择“Publish Message to”。
- Feed: 点击选择框,找到并选择你刚才创建的
BAYMAXFeed。 - With: 在输入框中填入一个数字,比如
1。这个数字将代表第一种药。
- 点击“Create Action”保存。这样,每天上午9点,Adafruit IO就会自动向
BAYMAX这个Feed发送一条内容为“1”的消息。 - 重复添加:你需要为每一种药或每一个服药时间点创建一个独立的Action。重复步骤1-5,创建第二个提醒(比如下午14:00),在“With”栏填入
2;创建第三个(比如晚上21:00),填入3,以此类推。实操心得:Adafruit IO的免费版对数据发送频率有一定限制(通常每分钟不超过30次)。对于我们这种一天几次的服药提醒完全够用,但请不要设置每分钟触发一次的极端测试,以免触发速率限制。
5. 硬件电路连接与核心代码剖析
5.1 电路连接:极其简单的三线连接
电路连接只有三步,但引脚对应关系不能错。我们使用NodeMCU的数字输出引脚(Digital Pin)来模拟PWM信号,以控制RGB LED的颜色和亮度。
- 识别RGB LED引脚:取共阴极RGB LED灯珠。它有4条腿。最长的那条腿是共阴极(GND)。另外三条腿,长度略有不同,分别对应红色(R)、绿色(G)、蓝色(B)。通常,第二长的腿是绿色,剩下的两条分不清红蓝也没关系,接错了只是颜色不对,可以后期在代码里调整。
- 连接导线:
- 将RGB LED的红色(R)引脚,通过一根杜邦线,连接到NodeMCU的
D5引脚(对应GPIO14)。 - 将RGB LED的绿色(G)引脚,连接到NodeMCU的
D6引脚(对应GPIO12)。 - 将RGB LED的蓝色(B)引脚,连接到NodeMCU的
D7引脚(对应GPIO13)。 - 将RGB LED的共阴极(GND)引脚,连接到NodeMCU上任意一个
GND引脚。
- 将RGB LED的红色(R)引脚,通过一根杜邦线,连接到NodeMCU的
- 供电:完成上述连接后,用Micro USB线将NodeMCU连接到电脑(用于烧录程序)或5V充电器(用于最终运行)。
注意事项:NodeMCU的
Dx引脚编号(如D5)是开发板上的丝印,它对应着ESP8266芯片内部不同的GPIO编号。在Arduino IDE中编程时,我们直接使用D5这样的宏定义即可,IDE会帮我们做好映射。务必按照上述引脚连接,因为代码中已经固定了引脚定义。
5.2 Arduino代码详解与个性化修改
以下是完整的Arduino代码,并附有详细注释。你需要将其复制到Arduino IDE中,并根据你的网络和Adafruit IO信息进行修改。
// 智能药盒提醒灯 - Baymax Lamp // 依赖库:Adafruit MQTT Library #include <ESP8266WiFi.h> #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" /************************* WiFi 和 Adafruit IO 配置 *****************************/ #define WLAN_SSID "你的Wi-Fi名称" // 修改为你的Wi-Fi SSID #define WLAN_PASS "你的Wi-Fi密码" // 修改为你的Wi-Fi密码 #define AIO_SERVER "io.adafruit.com" #define AIO_SERVERPORT 1883 // 使用MQTT端口, 8883为SSL端口 #define AIO_USERNAME "你的Adafruit用户名" // 修改为你的Adafruit IO用户名 #define AIO_KEY "你的Active Key" // 修改为你的AIO Key /***************************** 引脚定义 ***************************************/ #define RED_PIN D5 // RGB LED红色引脚连接至NodeMCU的D5 #define GREEN_PIN D6 // RGB LED绿色引脚连接至NodeMCU的D6 #define BLUE_PIN D7 // RGB LED蓝色引脚连接至NodeMCU的D7 /*************************** 全局对象 ****************************************/ WiFiClient client; // 建立MQTT客户端对象,参数:WiFi客户端,服务器,端口,用户名,密钥 Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); // 订阅名为“BAYMAX”的Feed Adafruit_MQTT_Subscribe medicineFeed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/baymax"); // Feed名称需小写 /*************************** 函数声明 ****************************************/ void MQTT_connect(); void setColor(int red, int green, int blue); void setup() { Serial.begin(115200); delay(10); // 初始化RGB LED引脚为输出模式 pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); // 启动时先设置为白色(全亮),表示系统就绪 setColor(255, 255, 255); // 连接Wi-Fi Serial.println(); Serial.println(); Serial.print("正在连接到: "); Serial.println(WLAN_SSID); WiFi.begin(WLAN_SSID, WLAN_PASS); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.println("Wi-Fi连接成功!"); Serial.print("IP地址: "); Serial.println(WiFi.localIP()); // 设置MQTT订阅 mqtt.subscribe(&medicineFeed); } void loop() { // 确保MQTT连接正常 MQTT_connect(); // 检查是否有新消息到达 Adafruit_MQTT_Subscribe *subscription; while ((subscription = mqtt.readSubscription(5000))) { // 等待5秒 // 如果收到来自“baymax”feed的消息 if (subscription == &medicineFeed) { Serial.print(F("收到新消息: ")); String message = (char *)medicineFeed.lastread; // 读取消息内容 Serial.println(message); // 根据消息内容(字符串格式的数字)设置LED颜色 if (message == "1") { Serial.println(F("显示颜色:红色 (第一种药)")); setColor(255, 0, 0); // 红色 } else if (message == "2") { Serial.println(F("显示颜色:蓝色 (第二种药)")); setColor(0, 0, 255); // 蓝色 } else if (message == "3") { Serial.println(F("显示颜色:绿色 (第三种药)")); setColor(0, 255, 0); // 绿色 } else if (message == "0") { Serial.println(F("显示颜色:白色 (确认/待机)")); setColor(255, 255, 255); // 白色 } else { // 如果收到未知消息,可设置为其他颜色或关闭,这里设为白色 Serial.println(F("未知指令,恢复白色")); setColor(255, 255, 255); } } } // 如果长时间没有收到消息,可以ping一下服务器保持连接 if (!mqtt.ping()) { Serial.println(F("MQTT连接断开,尝试重连...")); mqtt.disconnect(); } } // 连接或重连MQTT服务器的函数 void MQTT_connect() { int8_t ret; // 如果已连接,则直接返回 if (mqtt.connected()) { return; } Serial.print("正在连接MQTT服务器... "); uint8_t retries = 3; while ((ret = mqtt.connect()) != 0) { // 连接返回0表示成功 Serial.println(mqtt.connectErrorString(ret)); Serial.println("5秒后重试..."); mqtt.disconnect(); delay(5000); retries--; if (retries == 0) { // 多次重连失败,系统重启可能是个好选择 Serial.println("MQTT连接失败,系统重启中..."); ESP.restart(); } } Serial.println("MQTT连接成功!"); } // 设置RGB LED颜色的函数 // 参数:red, green, blue 取值范围为0-255,0最暗,255最亮 // 注意:由于是共阴极LED,我们使用阳极PWM控制,输出高电平(255)时最亮。 void setColor(int red, int green, int blue) { // 将颜色值写入对应的PWM引脚 analogWrite(RED_PIN, red); analogWrite(GREEN_PIN, green); analogWrite(BLUE_PIN, blue); }代码修改与烧录步骤:
- 安装开发环境:在Arduino IDE中,安装ESP8266开发板支持。打开“文件”->“首选项”,在“附加开发板管理器网址”中添加:
http://arduino.esp8266.com/stable/package_esp8266com_index.json。然后在“工具”->“开发板”->“开发板管理器”中搜索“esp8266”并安装。 - 安装库:在“项目”->“加载库”->“管理库”中,搜索并安装“Adafruit MQTT Library”。
- 修改配置:在代码开头的配置部分,准确填写四行信息:
WLAN_SSID: 你的Wi-Fi网络名称(2.4GHz频段,ESP8266不支持5GHz)。WLAN_PASS: 你的Wi-Fi密码。AIO_USERNAME: 你的Adafruit IO用户名(在AIO Key页面查看)。AIO_KEY: 你的Adafruit IO Active Key。
- 自定义颜色与逻辑:
if (message == "1")等语句定义了数字对应的颜色。你可以修改setColor(255, 0, 0)中的三个数字来改变颜色。这三个数字分别代表红、绿、蓝的亮度(0-255)。例如setColor(255, 100, 0)是橙色。- 如果你想增加第四种药,只需在Adafruit IO上创建一个发送数字“4”的定时触发器,然后在这里添加一个
else if (message == "4")的语句块,并设置你想要的颜色。 - 在
else if (message == "0")块中,setColor(255, 255, 255)是设置为白色。如果你想在确认后关闭灯光,可以改为setColor(0, 0, 0)。
- 选择开发板与端口:在Arduino IDE的“工具”菜单下,“开发板”选择“NodeMCU 1.0 (ESP-12E Module)”;“端口”选择你的NodeMCU所连接的COM口(Windows)或/dev/cu.usbxxx(Mac)。
- 编译与上传:点击“验证”(对勾图标)检查代码无误,然后点击“上传”(右箭头图标)将程序烧录到NodeMCU中。上传时,可能需要按住NodeMCU上的“FLASH”或“BOOT”按钮再点击上传,具体视板子而定。
6. NFC标签配置与手机端自动化设置
这是实现“碰一下确认”功能的关键。我们需要让手机在识别到特定NFC标签时,自动向Adafruit IO发送一个“0”的信号。
6.1 Android手机配置(使用MacroDroid)
MacroDroid是一款强大且易用的Android自动化工具。
- 安装与基础设置:从Google Play商店安装MacroDroid。打开应用,它会请求一些必要的权限(如NFC、网络等),请全部允许。
- 创建新宏:点击主界面右下角的“+”号,选择“添加宏”。
- 设置触发器:
- 点击“触发器”,在列表中找到并选择“NFC标签”。
- 在NFC标签设置界面,选择“写入新标签”。
- 将你的NFC标签贴纸靠近手机背部的NFC感应区(通常在摄像头附近)。手机会发出振动或提示音,并显示“标签已写入成功”。这意味着MacroDroid已经将这个特定标签的ID记录了下来,作为触发这个宏的唯一凭证。
- 设置动作:
- 点击“动作”,在列表的“网络/通信”类别下找到并选择“HTTP请求”。
- 方法:选择
POST。 - URL:这是最关键的一步。URL格式为:
https://io.adafruit.com/api/v2/{AIO_USERNAME}/feeds/{feed_name}/data- 将
{AIO_USERNAME}替换为你的Adafruit IO用户名。 - 将
{feed_name}替换为你的Feed名称,必须全部小写。在我们的例子中,就是baymax。 - 例如,如果你的用户名是
my_adafruit_user,那么完整的URL就是:https://io.adafruit.com/api/v2/my_adafruit_user/feeds/baymax/data
- 将
- 内容类型:切换到“内容主体”标签页,在“内容类型”中选择
application/json。 - 请求主体:在同一标签页的“主体”框中,输入以下JSON数据:
{"datum":{"value":"0"}}。这个格式是Adafruit IO API要求的,value字段的值"0"就是我们想要发送的数字。 - 请求头:切换到“标头参数”标签页,点击“+”号添加一个参数。
- 参数名称:输入
X-AIO-Key(注意大小写和中间的横线)。 - 值:输入你的Adafruit IOActive Key。
- 参数名称:输入
- 保存与测试:点击右上角的“保存”图标。现在,这个宏就配置好了。你可以将手机再次贴近那个NFC标签,MacroDroid会在屏幕顶部显示一个通知,执行HTTP请求。此时,你可以立即打开Adafruit IO的
BAYMAXFeed页面,应该能看到一条值为“0”的新数据出现,同时你的“大白”灯应该会变回白色。
6.2 iOS手机配置(使用“快捷指令”)
iOS系统自带的“快捷指令”App原生支持NFC触发,无需安装第三方软件。
- 创建新快捷指令:打开“快捷指令”App,点击底部中间的“自动化”,然后点击“创建个人自动化”。
- 选择触发器:在新页面中,找到并选择“NFC”。
- 扫描NFC标签:点击“扫描”,然后将你的NFC标签靠近iPhone顶部(听筒附近)。手机识别后会让你为这个标签命名,例如“药盒确认”。
- 添-加动作:点击“下一步”,然后点击“添加操作”。
- 添加网络请求动作:
- 在搜索框中输入“URL”,选择“URL”操作。在URL框中输入与Android配置中相同的URL:
https://io.adafruit.com/api/v2/{AIO_USERNAME}/feeds/baymax/data。 - 再次点击“添加操作”,搜索“获取URL内容”,选择该操作。
- 点击“获取URL内容”操作框中的“显示更多”。
- 方法:选择
POST。 - 请求头:点击“添加新标头”。
- 键:输入
X-AIO-Key。 - 值:输入你的Adafruit IOActive Key。
- 键:输入
- 请求体:选择
JSON。- 点击“JSON”字样旁边的“{ }”字典图标。
- 在键值对列表中,点击“添加新项”。
- 键:输入
datum。 - 值:点击右侧的“>”,选择“字典”。
- 在这个新字典中,再“添加新项”。
- 键:输入
value。 - 值:输入
0。
- 在搜索框中输入“URL”,选择“URL”操作。在URL框中输入与Android配置中相同的URL:
- 完成:点击“下一步”,务必关闭“运行前询问”的开关,这样手机在识别到NFC标签时才会自动执行,无需确认。最后点击“完成”。
注意事项:iOS的“快捷指令”自动化在手机锁屏状态下可能无法立即触发NFC,有时需要唤醒屏幕。这是iOS系统的权限限制。测试时请确保手机屏幕是点亮状态。Android端的MacroDroid通常没有此限制。
7. 系统集成、测试与问题排查
7.1 最终组装与上电测试
- 内部固定:将连接好导线的RGB LED小心地放入“大白”的肚子(灯泡灯罩)里。可以用一点点热熔胶将LED固定在灯罩内壁,避免晃动。确保导线能从“大白”身体底部或背后引出。
- 隐藏控制器:将NodeMCU开发板用双面胶或扎带固定在“大白”身体的背面或底部,尽量保持美观。
- 连接电源:将NodeMCu的Micro USB口连接到5V充电器上,并接通电源。
- 观察启动:
- 上电后,NodeMCU板载的蓝色LED会快速闪烁几次(系统启动),然后开始连接Wi-Fi(慢闪)。此时,“大白”的肚子应亮起白色。
- 打开电脑的串口监视器(Arduino IDE中,“工具”->“串口监视器”,波特率设为115200),可以看到连接Wi-Fi和Adafruit IO的日志信息。当看到“MQTT连接成功!”时,说明硬件端已准备就绪。
7.2 全流程功能测试
现在,让我们模拟一次完整的服药提醒流程:
- 等待或模拟触发:等到你设定的第一个服药时间(例如9:00),或者为了测试,你可以手动在Adafruit IO的Dashboard里,找到你为
BAYMAXFeed创建的Gauge控件,直接在里面输入数字“1”并发送。 - 观察提醒:几秒钟内,“大白”的肚子应该从白色变为红色(或你为数字“1”设置的颜色)。这表示提醒已成功触发。
- 执行确认:拿起你的手机,解锁屏幕(特别是iOS),贴近贴在药盒上的NFC标签。
- 观察复位:手机应会有轻微振动或提示(取决于设置)。同时,“大白”的肚子应在1-2秒内变回白色。在Adafruit IO的Feed页面,你会看到一条值为“0”的新数据记录。
7.3 常见问题与排查技巧实录
即使按照教程一步步操作,也可能会遇到一些小问题。这里我整理了在制作和调试过程中可能遇到的典型问题及其解决方法。
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 上电后LED不亮,串口无输出 | 1. 电源问题。 2. NodeMCU损坏或接触不良。 3. USB线仅能传数据不能供电。 | 1. 检查USB电源适配器是否正常(可给手机充电测试)。 2. 换一根已知良好的Micro USB线。 3. 尝试将NodeMCU连接到电脑USB口,看电脑是否能识别串口。 |
| 串口显示Wi-Fi连接失败 | 1. Wi-Fi信息(SSID/密码)错误。 2. 路由器设置了MAC过滤或仅限5GHz。 3. 信号太弱。 | 1. 反复检查代码中的WLAN_SSID和WLAN_PASS,注意大小写和特殊字符。2. 确认路由器2.4GHz网络开启,且未屏蔽新设备。 3. 将设备靠近路由器测试。 |
| 串口显示连接Adafruit IO失败 | 1. AIO用户名或Active Key错误。 2. 网络问题导致无法访问境外服务器。 | 1. 核对代码中的AIO_USERNAME和AIO_KEY,确保与网页上查看的一致,且没有多余空格。2. 检查网络连通性。在串口监视器初始化部分添加 Serial.println("Start");,确认程序运行到此。 |
| LED颜色显示不正确 | 1. RGB LED引脚接错。 2. 共阴/共阳搞错。 3. 代码中颜色值设置错误。 | 1. 检查杜邦线是否按D5->红,D6->绿,D7->蓝连接。可尝试交换红蓝线测试。2. 确认购买的是共阴极RGB LED。 3. 在 setColor函数中,临时将三个参数都设为255,应得到白色;都设为0,灯应熄灭。 |
| 定时到点无提醒(灯不变色) | 1. Adafruit IO定时触发器未正确设置。 2. MQTT连接断开,设备未收到消息。 | 1. 登录Adafruit IO,检查Actions中的定时任务时间、Feed名称和发送值是否正确。2. 在串口监视器中观察,正常情况下应有周期性的MQTT Ping记录。如果长时间无消息,可能是网络波动导致断连,代码中的重连逻辑会尝试恢复。 |
| 手机碰NFC标签无反应 | 1. NFC标签损坏或手机NFC功能未开启。 2. 手机自动化配置错误(URL、Key)。 3. iOS手机锁屏状态。 | 1. 用手机读取其他门禁卡或公交卡,测试手机NFC功能是否正常。换一个NFC标签测试。 2. 检查MacroDroid或快捷指令中的URL和AIO Key是否填写正确。URL中的Feed名称必须小写。 3. 对于iPhone,尝试唤醒屏幕后再触碰标签。 |
| 碰标签后灯不变回白色 | 1. 手机HTTP请求发送失败。 2. Adafruit IO未收到“0”信号。 3. 设备端代码未正确处理“0”。 | 1. 检查手机网络(Wi-Fi/移动数据)是否通畅。 2. 查看Adafruit IO上 BAYMAXFeed的实时数据流,看触碰标签后是否有值为“0”的新数据点出现。如果没有,问题在手机端配置。3. 如果有“0”数据点出现但灯不变,检查设备串口日志,看是否打印了“收到新消息: 0”。如果没有,是MQTT订阅问题;如果有,是代码中颜色设置部分的问题。 |
一个关键的调试技巧:利用串口监视器和Adafruit IO Feed页面。串口监视器是硬件端的“眼睛”,所有网络连接状态、收到的消息内容都会打印在这里。Adafruit IO Feed页面是云端的“日志”,所有进出云端的数据(无论是定时触发还是手机发送)都会在这里留下记录。当问题发生时,同时观察这两个地方,就能快速定位问题是出在云端配置、网络通信还是硬件端逻辑上。
8. 项目扩展与优化思路
这个“大白”智能药盒提醒灯的基础版本已经非常实用,但它的物联网架构决定了其强大的可扩展性。这里分享几个我实践过或正在规划的升级思路,希望能给你带来更多灵感。
1. 增加更多传感器,实现环境互动:
- 温湿度传感器(如DHT11):让“大白”可以播报室内环境状况。你可以在代码中定期读取传感器数据,并通过Adafruit IO发送到另一个Feed,在Dashboard上创建温湿度图表。
- 人体红外传感器(PIR):就像我最初设想的那样,在“大白”内部集成一个PIR传感器。通过代码判断人体持续静止的时间,当超过设定阈值(如1小时)时,控制LED闪烁特定颜色(如黄色),提醒你该起来活动一下了。这个触发逻辑同样可以通过向
BAYMAXFeed发送一个新数字(如“4”)来实现。
2. 优化提醒方式与用户体验:
- 增加声音提醒:连接一个小型无源蜂鸣器。在收到服药提醒(颜色变化)的同时,让蜂鸣器发出几声柔和的“嘀嘀”声,实现声光双重提醒,对于在另一个房间的人更有效。
- 实现渐进式提醒:如果第一次提醒后一段时间(如10分钟)仍未确认服药,可以让LED从常亮改为呼吸灯效果(亮度周期性变化),或者改变颜色(如从红色变为闪烁的橙色),提醒强度逐步升级。
- 本地化定时备份:目前完全依赖网络和云端定时。可以增加一个DS3231高精度时钟模块,在代码中实现一套本地定时逻辑。云端定时作为主触发,本地时钟作为备份。当网络断开时,设备依然能依靠本地时钟工作,并在网络恢复后同步状态,大大提高系统的可靠性。
3. 深化数据记录与可视化:
- 记录服药历史:每次手机触碰NFC标签确认服药时,MacroDroid或快捷指令除了发送“0”复位信号,还可以同时向另一个专门的Feed(如
baymax_log)发送一条包含时间戳的数据。这样,在Adafruit IO上就能形成一个简单的服药日志。 - 集成IFTTT或Webhook:Adafruit IO支持将Feed数据通过Webhook发送到其他服务。你可以设置规则,如果超过设定时间未确认服药(即Feed值未从“1”变回“0”),则触发IFTTT,向你的手机发送一条推送通知,甚至拨打电话,实现多层保障。
4. 外观与结构的改进:
- 3D打印外壳:如果你有3D打印机,可以为NodeMCU和线路设计一个精致的内壳,再为“大白”本身设计一个可开合的外壳,方便维护和更换电池(如果改用电池供电)。
- 无线供电与便携化:使用锂电池和充电管理模块为整个系统供电,摆脱电源线的束缚。你可以把“大白”放在床头、办公桌、甚至随身携带,真正实现随时随地提醒。
这个项目的精髓在于,它提供了一个清晰的物联网应用范式:感知(定时/NFC)-> 云端处理(Adafruit IO)-> 执行(LED)。一旦你掌握了这个范式,就可以举一反三,用同样的核心组件(ESP8266 + Adafruit IO),搭配不同的传感器和执行器,创造出无数个解决生活小痛点的智能设备。从提醒吃药,到提醒喝水、提醒休息,再到控制台灯、浇花,想象力是唯一的边界。希望这个“大白”不仅能成为你健康管理的小帮手,更能成为你踏入物联网创意世界的一块敲门砖。