news 2026/6/2 14:57:44

基于MicroPython与LINE Notify的物联网设备通知系统开发实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于MicroPython与LINE Notify的物联网设备通知系统开发实践

1. 项目概述:让MCU开口说话

在物联网项目里,让设备“开口说话”,主动把状态、数据或者告警信息推送到你的手机上,是一个既实用又酷炫的功能。想象一下,家里的温湿度传感器检测到异常高温,能立刻给你发条消息;或者你DIY的智能鱼缸,在水质变差时能及时通知你。这种主动通知的能力,是区分一个“玩具”和一个“实用工具”的关键。

过去,要实现这个功能,你可能需要折腾复杂的MQTT服务器、自己搭建Webhook,或者研究各种云平台繁琐的API。对于资源有限的微控制器(MCU)来说,这无疑增加了开发和维护的复杂度。而LINE Notify这个服务,恰好提供了一个极其简单的解决方案:它本质上就是一个通过HTTP POST请求就能发送消息到LINE聊天室的通道。对于嵌入式开发者,尤其是使用MicroPython的玩家,这简直是天作之合。

MicroPython让我们能在ESP8266、ESP32这类MCU上用Python语法轻松编程,而围绕它生态出现的一些优秀库,则进一步把复杂度封装了起来。就像这个项目里用到的My_NetHTTP_LINE库,它的目标非常明确——把“通过WiFi联网,构造HTTP请求,向LINE Notify发送消息”这一系列操作,浓缩成两、三行直观的代码。你不再需要关心HTTP头的构造、URL编码或者连接管理,只需要关注最核心的两件事:你的WiFi密码和LINE令牌(Token)。接下来,我们就从最基础的准备开始,一步步拆解如何让你的MCU变身成一个智能通知器。

2. 前期准备与环境搭建

在写下第一行代码之前,我们需要把“舞台”搭好。这包括硬件设备、软件工具以及关键的云端服务配置。别担心,每一步我都会解释清楚为什么这么做,以及有哪些容易踩坑的地方。

2.1 硬件与软件准备

硬件选择:ESP8266 vs ESP32核心硬件是一块支持WiFi和MicroPython的MCU开发板。最常见的选择是ESP8266(如NodeMCU、Wemos D1 mini)和ESP32系列。

  • ESP8266:性价比之王,单核,足以胜任网络连接和简单的消息发送任务。如果你的项目只需要联网发通知,没有其他复杂计算或外设需求,ESP8266完全够用,而且更便宜。
  • ESP32:功能更强大,双核处理器,主频更高,内存更大,还多了蓝牙功能。如果你的项目未来需要连接更多传感器、处理更复杂的数据,或者需要用到蓝牙,ESP32是更面向未来的选择。

注意:无论选择哪款,务必确保板子有可靠的USB转串口芯片(如CP2102、CH340),并且驱动已在你的电脑上安装好。连接不稳定是后续一切问题的万恶之源。

软件工具链

  1. MicroPython固件:你需要将MicroPython解释器“刷入”你的MCU。去MicroPython官网下载对应你板型(如esp8266-xxx.binesp32-xxx.bin)的最新稳定版固件。
  2. 烧录工具:对于ESP系列,esptool.py是官方的命令行烧录工具,功能强大。如果你更喜欢图形界面,像ThonnyIDE内置的烧录功能或者Flash Download Tools(乐鑫官方)也不错。
  3. 开发环境(IDE):强烈推荐Thonny。它对MicroPython的支持是“开箱即用”级的。连接板子后,它不仅能直接作为Python编辑器,还能充当一个简单的文件管理器,上传下载文件到MCU的内部文件系统,以及使用其自带的REPL(交互式命令行)进行调试,这对我们后续上传库文件至关重要。
  4. 库文件:本项目依赖的核心库文件(My_NetHTTP.pyMy_NetHTTP_LINE.py, 以及可选的My_Wifi.py)。你需要提前获取这些.py文件。

2.2 获取LINE Notify令牌(Token)

这是连接你的代码和LINE账户的“钥匙”。没有它,消息不知道该发给谁。

  1. 访问 LINE Notify 官网 (请自行搜索正确网址),使用你的LINE账户登录。
  2. 点击页面右上角你的头像,进入“个人页面”。
  3. 找到“发行存取令牌”(Issue access token)选项。
  4. 输入一个令牌名称,例如“我的ESP32通知器”。这主要用于你自己识别这个令牌的用途。
  5. 选择消息要发送到的目标。你可以选择“透过1对1聊天接收LINE Notify的通知”,这样消息会单独发给一个名为“LINE Notify”的好友;也可以选择一个你所在的群组,这样所有群成员都能看到设备消息。出于隐私考虑,建议先使用1对1聊天进行测试。
  6. 点击“发行”。页面上会一次性显示一串长字符,这就是你的LINE_NOTIFY_TOKEN务必立即复制并妥善保存,因为页面刷新后将无法再次查看,只能重新生成。

实操心得:令牌是最高权限凭证,泄露意味着别人可以用你的令牌任意发消息。因此:

  • 绝对不要将令牌硬编码在提交到公开仓库的代码中。
  • 在MicroPython中,一个常见的做法是将令牌(以及WiFi密码)保存在一个单独的、名为secrets.pyconfig.py的文件里,然后在主程序中导入。上传时只上传主程序,将包含敏感信息的文件通过Thonny等工具单独上传,并确保.gitignore文件忽略了它。
  • 令牌可以在LINE Notify个人页面随时作废(失效)和重新生成。

2.3 库文件的上传与管理

原始资料提到了上传库文件到MCU,这里详细展开。MCU运行MicroPython时,需要一个文件系统来存放你的主程序main.py和依赖的库文件。我们通过串口连接,用工具将这些文件上传到MCU的闪存中。

使用Thonny上传(推荐给初学者):

  1. 将MCU通过USB线连接电脑,在Thonny中选择正确的端口和解释器(MicroPython ESP32/ESP8266)。
  2. 在Thonny下方窗格,通常可以看到“设备”和“本机”两个文件浏览器。
  3. 在“本机”侧找到你下载好的My_NetHTTP.pyMy_NetHTTP_LINE.py等文件。
  4. 右键点击文件,选择“上传到 /”,或者直接拖拽到“设备”侧的根目录下。
  5. 上传成功后,你可以在MCU的文件系统中看到它们。

使用命令行工具(如ampy):如果你习惯命令行,可以安装adafruit-ampy工具。

# 上传单个文件 ampy --port COM3 put My_NetHTTP_LINE.py # 上传整个目录(谨慎使用) # ampy --port COM3 put lib/

注意事项

  • 文件命名一致性:确保你上传的文件名和代码中import语句里的名字完全一致,包括大小写。MicroPython的文件系统有时对大小写敏感。
  • 存储空间:ESP8266的可用文件系统空间可能较小(通常1MB左右),注意不要上传无关的大文件。ESP32则宽裕很多。
  • 库的依赖My_NetHTTP_LINE.py依赖于My_NetHTTP.py(处理基础的HTTP请求)。因此两个文件必须同时存在。My_Wifi.py是可选的,如果你用自己的WiFi连接代码,可以不用它。

3. 核心库原理与代码深度解析

现在,硬件就绪,令牌在手,库文件也已上传。让我们深入看看,那神奇的2~3行代码背后,到底发生了什么。理解原理,不仅能帮你更好地使用它,还能在出问题时快速定位。

3.1 My_NetHTTP_LINE 库的工作机制

My_NetHTTP_LINE库是一个高级封装,它的目标是极致简化。我们看看它可能的核心实现逻辑(以下为概念性代码,并非原库 exact 代码):

# My_NetHTTP_LINE.py 概念性源码分析 import My_NetHTTP # 导入底层HTTP库 class myNotify: def __init__(self, token): # 保存令牌,并构造LINE Notify API的固定URL self.url = "https://notify-api.line.me/api/notify" self.headers = { "Authorization": "Bearer " + token, # LINE API要求的认证头格式 "Content-Type": "application/x-www-form-urlencoded" } # 实例化一个底层的HTTP客户端 self.http = My_NetHTTP.My_NetHTTP() # 假设My_NetHTTP类名为My_NetHTTP def send(self, message, package=None, sticker=None): # 构建请求体,最基本的参数是 'message' data = "message=" + self._urlencode(message) # 如果提供了贴图参数,则添加到请求体中 if package is not None and sticker is not None: data += "&stickerPackageId=" + str(package) + "&stickerId=" + str(sticker) # 调用底层HTTP库的POST方法 # 这里封装了实际的网络请求、错误处理等复杂细节 response = self.http.post(self.url, data=data, headers=self.headers) # 可能还会检查response状态码(如200成功,401令牌错误等) return response

从这段概念代码可以看出,这个库主要做了以下几件事:

  1. 初始化:接收你的令牌,并组合成LINE API要求的Authorization: Bearer {token}请求头格式。这是HTTP协议中一种标准的令牌认证方式。
  2. 消息构造:将你要发送的文本消息进行URL编码(处理空格、中文等特殊字符),形成message=你的内容的标准表单数据格式。
  3. 贴图支持:如果调用时传入了packagesticker参数,它会将这两个参数拼接到请求体中。
  4. 发起请求:最终,它调用更底层的My_NetHTTP库,向https://notify-api.line.me/api/notify这个固定的API地址,发送一个HTTP POST请求。

那么,底层的My_NetHTTP库又做了什么?它很可能封装了MicroPython标准库urequestssocket的复杂操作,包括:

  • 建立TCP连接。
  • 按照HTTP协议格式,组装完整的HTTP请求报文(请求行、请求头、空行、请求体)。
  • 处理网络读写超时。
  • 接收服务器的响应并解析状态码和响应体。
  • 处理网络连接异常。

正是这种分层设计,才让顶层的我们能够用line.send(“Hello”)这样简单的方式完成通信。

3.2 代码逐行解读与最佳实践

让我们结合一个更完整的示例,逐行分析并融入最佳实践。

# 示例:complete_notify.py from My_Wifi import myWifi # 导入WiFi连接库 from My_NetHTTP_LINE import myNotify # 导入LINE通知库 import time # 1. WiFi连接配置 WIFI_SSID = "你的WiFi名称" WIFI_PASSWORD = "你的WiFi密码" LINE_TOKEN = "你的LINE令牌" # 强烈建议从配置文件导入 # 2. 创建WiFi对象并连接 wifi = myWifi() print("正在连接WiFi...") if wifi.connect(WIFI_SSID, WIFI_PASSWORD): print("WiFi连接成功!") # 3. 创建LINE通知对象 line = myNotify(LINE_TOKEN) # 初始化,传入令牌 # 4. 发送纯文本消息 print("正在发送文本消息...") response = line.send("【设备启动通知】ESP32已成功上线,IP地址:" + wifi.get_ip()) # 这里可以检查response,例如 if response.status_code == 200: ... # 5. 发送带贴图的消息 # packageId 和 stickerId 需要从LINE官网查询 print("正在发送带贴图的消息...") line.send("今日天气晴好,一切正常!😊", package=1, sticker=113) # 贴图ID 1-113 对应的是“微笑”表情 # 6. 模拟设备运行后发送告警 time.sleep(5) # 模拟运行5秒 # 假设这里读取传感器,发现温度过高 simulated_temperature = 38.5 if simulated_temperature > 35: line.send(f"【高温告警】检测到温度过高:{simulated_temperature}°C!请及时处理。", package=2, sticker=165) # 贴图ID 2-165 对应的是“吃惊”或“警告”类表情,更符合告警场景 # 7. 断开WiFi(可选,对于常开设备通常保持连接) wifi.disconnect(3) # 参数3可能代表延迟3秒断开 print("通知发送完毕,WiFi已断开。") else: print("WiFi连接失败,请检查配置。")

关键点解析与最佳实践:

  • WiFi连接判断if wifi.connect(...):这是一个好习惯。确保网络连通后再进行后续的网络操作,避免程序因网络问题而崩溃。
  • 令牌管理:在实际项目中,LINE_TOKENWIFI_SSIDWIFI_PASSWORD不应直接写在主代码里。创建一个config.py文件:
    # config.py WIFI_SSID = "my_home_wifi" WIFI_PASSWORD = "super_secret_password" LINE_TOKEN = "abcdefghijklmnopqrstuvwxyz123456"
    在主程序中import config,然后使用config.LINE_TOKEN。上传代码时,只上传主程序,config.py通过Thonny单独上传。
  • 消息内容:消息内容可以动态拼接。如上例中,将获取到的设备IP地址加入通知,使得消息更具信息量。使用f-string(Python 3.6+)或format()方法让字符串组合更清晰。
  • 错误处理:示例中省略了详细的错误处理。在生产代码中,你应该用try...except包裹send方法,捕获可能发生的网络异常、内存错误等,并记录日志或通过其他途径告警。
  • 贴图的情感化应用:选择与消息内容情绪相符的贴图,能极大提升通知的友好度和可读性。告警用“紧张”、“吃惊”的贴图,正常报告用“微笑”、“OK”的贴图。

4. 实战进阶:构建一个温湿度监控通知器

理解了基础,我们来做一个更有实际意义的项目:一个基于DHT11/DHT22温湿度传感器和ESP32的监控器,它定期读取环境数据,并在温度或湿度超过阈值时,向LINE发送告警通知。

4.1 硬件连接与依赖库

所需材料:

  • ESP32开发板 x1
  • DHT11或DHT22温湿度传感器 x1
  • 杜邦线若干
  • 微型USB数据线

接线方式(以DHT11为例):

  • DHT11 VCC 引脚 -> ESP32 3.3V
  • DHT11 GND 引脚 -> ESP32 GND
  • DHT11 DATA 引脚 -> ESP32 GPIO 4 (可根据需要更改)

额外的MicroPython库:除了之前的网络库,我们还需要dht库来读取传感器数据。好消息是,dht通常是MicroPython固件内置的标准库之一,无需额外上传。如果没有,你需要找到dht.py文件并上传。

4.2 完整项目代码实现

# main.py - 温湿度监控与LINE告警系统 import time import dht from machine import Pin from My_Wifi import myWifi from My_NetHTTP_LINE import myNotify # 1. 配置文件(实际使用时请分离到config.py) CONFIG = { 'wifi_ssid': '你的WiFi', 'wifi_pass': '你的密码', 'line_token': '你的令牌', 'sensor_pin': 4, # DHT数据线连接的GPIO引脚 'check_interval': 30, # 检查间隔(秒) 'temp_threshold_high': 28.0, # 温度告警上限(摄氏度) 'temp_threshold_low': 10.0, # 温度告警下限 'humi_threshold_high': 80.0, # 湿度告警上限(百分比) 'humi_threshold_low': 20.0 # 湿度告警下限 } # 2. 初始化硬件与网络 def init_system(): # 初始化DHT传感器 dht_sensor = dht.DHT11(Pin(CONFIG['sensor_pin'])) # 使用DHT11,如果是DHT22改为DHT22 # 初始化WiFi wifi = myWifi() print("系统初始化...") if not wifi.connect(CONFIG['wifi_ssid'], CONFIG['wifi_pass']): print("[严重错误] WiFi连接失败,系统停止。") # 对于无法联网的设备,可以考虑让LED闪烁报警 while True: time.sleep(1) # 阻塞,等待人工干预或重启 print(f"WiFi连接成功,IP: {wifi.get_ip()}") # 初始化LINE通知器 line_bot = myNotify(CONFIG['line_token']) # 发送系统启动通知 line_bot.send(f"🌡️ 温湿度监控器已启动 @ {wifi.get_ip()}, 开始监控...") return dht_sensor, wifi, line_bot # 3. 读取传感器数据(包含简单错误处理) def read_sensor_data(sensor): try: sensor.measure() # 触发一次测量 temperature = sensor.temperature() humidity = sensor.humidity() # DHT11可能返回None或错误值,增加检查 if temperature is None or humidity is None: print("读取传感器数据失败,返回None。") return None, None # 有时DHT11会读出极端错误值,增加合理性检查 if -40 < temperature < 80 and 0 <= humidity <= 100: return temperature, humidity else: print(f"传感器数据异常:temp={temperature}, humi={humidity}") return None, None except OSError as e: # 常见的传感器读取超时错误 print(f"读取传感器时发生OSError: {e}") return None, None except Exception as e: print(f"读取传感器时发生未知错误: {e}") return None, None # 4. 检查阈值并发送通知 def check_and_notify(temp, humi, line_bot, last_alert): current_time = time.time() message_parts = [] # 用于组合消息 alert_level = 0 # 告警级别 0:正常,1:警告,2:严重 # 检查温度 if temp is not None: if temp > CONFIG['temp_threshold_high']: message_parts.append(f"🔥 温度过高:{temp}°C") alert_level = max(alert_level, 2) elif temp < CONFIG['temp_threshold_low']: message_parts.append(f"❄️ 温度过低:{temp}°C") alert_level = max(alert_level, 2) else: message_parts.append("温度传感器读数无效") alert_level = max(alert_level, 1) # 检查湿度 if humi is not None: if humi > CONFIG['humi_threshold_high']: message_parts.append(f"💦 湿度过高:{humi}%") alert_level = max(alert_level, 2) elif humi < CONFIG['humi_threshold_low']: message_parts.append(f"🏜️ 湿度过低:{humi}%") alert_level = max(alert_level, 2) else: message_parts.append("湿度传感器读数无效") alert_level = max(alert_level, 1) # 决定是否发送通知以及发送什么 if alert_level > 0: # 存在告警 alert_msg = " | ".join(message_parts) # 防骚扰机制:相同的告警,至少间隔10分钟才发送一次 if alert_msg != last_alert.get('msg') or (current_time - last_alert.get('time', 0)) > 600: print(f"发送告警:{alert_msg}") if alert_level == 2: line_bot.send(alert_msg, package=2, sticker=165) # 严重告警用紧张贴图 else: line_bot.send(alert_msg, package=1, sticker=113) # 一般警告用提醒贴图 last_alert['msg'] = alert_msg last_alert['time'] = current_time else: # 状态正常,可以定期发送一次心跳(例如每小时一次),这里省略以节省消息数 # if current_time - last_heartbeat > 3600: ... # line_bot.send(f"✅ 状态正常 - 温度:{temp}°C, 湿度:{humi}%") pass return last_alert # 5. 主循环 def main(): sensor, wifi, line_bot = init_system() last_alert = {'msg': '', 'time': 0} # 记录上一次告警内容和时间 normal_read_count = 0 while True: print(f"\n--- 第{normal_read_count+1}次检查 ---") temp, humi = read_sensor_data(sensor) if temp is not None and humi is not None: print(f"当前环境:温度 {temp}°C, 湿度 {humi}%") # 更新最后一次告警状态 last_alert = check_and_notify(temp, humi, line_bot, last_alert) normal_read_count += 1 else: print("本次传感器读取失败,跳过检查。") # 连续多次失败可以升级为告警 # error_count += 1 # if error_count > 5: ... # 等待下一个检查周期 time.sleep(CONFIG['check_interval']) # 运行主程序 if __name__ == '__main__': main()

4.3 项目优化与扩展思路

这个基础版本已经可以工作,但还有很大的优化和扩展空间:

  1. 深度睡眠与省电:如果设备由电池供电,频繁的WiFi连接和传感器读取非常耗电。可以利用ESP32的深度睡眠(Deep Sleep)功能。让设备每隔一段时间(如5分钟)唤醒,连接WiFi、读取传感器、发送通知(如果需要),然后立刻进入深度睡眠。这可以将平均电流从几十mA降至几十μA,极大延长续航。

    from machine import deepsleep # 在主循环末尾或发送通知后 print("进入深度睡眠,{}秒后唤醒。".format(sleep_time_ms // 1000)) deepsleep(sleep_time_ms) # 单位是毫秒
  2. 数据上报与可视化:除了即时告警,你还可以将数据定期上报到物联网平台(如ThingsBoard、Blynk、或者自建的InfluxDB+ Grafana),用于绘制长期的历史曲线图,分析环境变化趋势。这需要设备具备更稳定的网络连接和更复杂的数据封装能力。

  3. 多通道通知:不要只依赖LINE。可以集成其他通知方式,比如Telegram Bot、Bark(iOS)、Server酱(微信)等。在check_and_notify函数中,可以同时调用多个通知发送函数,实现通知冗余,确保重要告警不被遗漏。

  4. 本地显示与交互:增加一个OLED屏幕(如SSD1306),实时显示当前的温湿度数据和WiFi状态。再增加一两个按钮,可以手动触发一次读取、切换显示模式,或者进入配置模式(通过Web Server或蓝牙)来修改WiFi密码和阈值,这样就不需要每次都修改代码并重新上传了。

5. 常见问题排查与调试技巧

即使按照步骤操作,你也可能会遇到一些问题。这里汇总了一些常见坑点及其解决方法。

5.1 网络连接类问题

问题现象可能原因排查步骤与解决方案
wifi.connect()始终返回False或超时。1. WiFi SSID/密码错误。
2. 路由器设置了MAC地址过滤或隐藏了SSID。
3. ESP板与路由器距离过远或信号太差。
4. 路由器不支持ESP的某些WiFi模式(较少见)。
1.仔细核对SSID和密码,注意大小写和特殊字符。
2. 在路由器后台暂时关闭MAC过滤,或将ESP的MAC地址加入白名单。对于隐藏SSID,myWifi库可能不支持,需查看其文档或改用标准network库手动连接。
3. 将设备靠近路由器测试。
4. 尝试在手机热点下测试,以排除路由器兼容性问题。
连接WiFi成功,但发送LINE消息时失败。1. 网络临时波动。
2. DNS解析失败(无法解析notify-api.line.me)。
3. 防火墙或网络策略阻止了对外部HTTPS(443端口)的访问。
1. 增加重试机制。在send方法外用try...except包裹,失败后延迟几秒重试1-2次。
2. 尝试在代码中先用urequests.get('http://example.com')测试是否能访问普通HTTP网站,以排除基础网络问题。
3. 在某些企业或学校网络,访问外部服务可能受限。尝试切换到手机热点网络测试。
设备运行一段时间后网络断开,无法重连。1. WiFi路由器重启或网络不稳定。
2. ESP32/ESP8266的WiFi驱动或电源管理存在bug,导致长时间运行后断线。
3. 代码中没有断线重连机制。
1. 在主循环中增加网络状态检查。可以定期(如每10次循环)ping一个网关或外网地址,如果失败,则调用wifi.disconnect()然后重新执行wifi.connect()
2. 查阅MicroPython论坛,有时更新到最新稳定版固件可以解决一些已知的驱动问题。
3.务必实现重连逻辑,这是物联网设备稳定性的关键。

5.2 代码与库相关错误

问题现象可能原因排查步骤与解决方案
ImportError: no module named 'My_NetHTTP_LINE'1. 库文件没有上传到MCU。
2. 库文件上传到了错误的目录(如子目录)。
3. 文件名拼写错误(大小写、下划线)。
1. 使用Thonny的文件管理器,确认My_NetHTTP_LINE.pyMy_NetHTTP.py存在于MCU的根目录(/)。
2. 确保import语句中的模块名与文件名完全一致
NameError: name 'myNotify' is not definedfrom My_NetHTTP_LINE import myNotify语句执行失败,但错误被忽略或发生在之前。检查上一条import语句是否成功。确保库文件存在且语法正确。可以在REPL中单独执行from My_NetHTTP_LINE import myNotify测试。
发送消息后程序崩溃或无响应。1. 内存不足(尤其在ESP8266上,同时处理字符串和网络请求易发生)。
2. 网络操作阻塞了看门狗(WDT),导致复位。
1. 使用gc.collect()在关键操作(如组包大字符串、发送请求)后手动回收内存。
2. 将耗时的网络操作放在try...finally块中,或在其中插入短时间的time.sleep(0)以喂狗。对于ESP32,可以考虑将网络任务放在另一个核心上运行(需使用_thread库)。
能发送文本,但发送贴图失败。1.packageIdstickerId参数类型错误(应为整数)。
2. 参数值超出了有效范围。
3. 库的send方法在处理可选参数时存在bug。
1. 确认传入的参数是整数,如line.send("msg", package=1, sticker=113)
2. 去LINE官方贴图列表页面,确认你使用的ID组合是有效的、免费的贴图。
3. 尝试发送不带贴图的消息确认基础功能正常。然后检查库文件源码(如果开源),看贴图参数拼接逻辑是否正确。

5.3 LINE API 返回错误

send方法内部调用失败时,最可能的原因是LINE API返回了错误。虽然My_NetHTTP_LINE库可能没有直接暴露详细的错误信息,但我们可以通过修改库文件或使用更底层的urequests库来调试。

临时调试方法:

  1. My_NetHTTP_LINE.pysend方法中,找到发送请求和获取响应的代码行(通常是response = self.http.post(...))。
  2. 在这行之后,添加打印语句,输出响应的状态码和内容。
    # 在My_NetHTTP_LINE.py的send方法内添加 print("Status Code:", response.status_code) print("Response:", response.text)
  3. 重新上传该库文件到MCU并运行你的程序。常见的错误有:
    • 401:令牌无效或已过期。请重新在LINE Notify官网生成令牌。
    • 400:请求格式错误,例如消息体过长(LINE Notify限制消息长度)、贴图ID无效等。
    • 429:请求频率过高。LINE Notify对同一个令牌有发送频率限制(大概每小时1000条左右),请降低发送频率。

调试心法:

  • 分而治之:遇到问题,先把复杂系统拆开测试。先写一个最简单的脚本,只连WiFi;再写一个脚本,只发LINE文本;最后再组合。
  • 利用REPL:Thonny的REPL是强大的实时调试工具。你可以在里面逐行执行代码,即时查看变量和错误信息。
  • 打印日志:在关键步骤(连接WiFi前/后、发送消息前/后)添加print()语句输出状态,这是嵌入式调试最朴实但最有效的方法。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 14:57:42

基于超声波测距的颗粒炉料位监测报警系统设计与实现

1. 项目概述与核心需求解析颗粒炉&#xff08;Pellet Stove&#xff09;作为家庭供暖的常见设备&#xff0c;其燃料仓的料位管理一直是个不大不小的麻烦。很多老款或基础型号的炉子并没有配备低料位报警功能&#xff0c;这就导致了一个尴尬的局面&#xff1a;当你发现炉子熄火时…

作者头像 李华
网站建设 2026/6/2 14:55:22

基于74系列芯片的数字密码锁设计:从逻辑门到完整硬件系统

1. 项目概述与核心价值在电子设计与嵌入式系统开发的入门阶段&#xff0c;很多朋友会从单片机或Arduino入手&#xff0c;这当然是一条高效的路。但如果你真的想从底层理解一个控制系统是如何“思考”和“决策”的&#xff0c;亲手用最基础的数字逻辑电路搭建一个功能完整的系统…

作者头像 李华
网站建设 2026/6/2 14:51:34

从零构建Arduino磁悬浮装置:PID控制算法与硬件设计全解析

1. 项目概述&#xff1a;从零构建一个桌面级磁悬浮装置磁悬浮&#xff0c;听起来像是科幻电影里的技术&#xff0c;但它的核心原理其实并不遥远。简单来说&#xff0c;就是利用电磁力对抗重力&#xff0c;让一个物体稳稳地“飘”在空中。这项技术最广为人知的应用是磁悬浮列车&…

作者头像 李华
网站建设 2026/6/2 14:49:55

3步解锁英雄联盟回放文件:ROFL-Player深度解析与实战指南

3步解锁英雄联盟回放文件&#xff1a;ROFL-Player深度解析与实战指南 【免费下载链接】ROFL-Player (No longer supported) One stop shop utility for viewing League of Legends replays! 项目地址: https://gitcode.com/gh_mirrors/ro/ROFL-Player 你是否曾经遇到过这…

作者头像 李华