
1. 项目概述一个为宠物设计的智能启动器最近在GitHub上看到一个挺有意思的项目叫“CoPawLaunch”。光看名字可能有点摸不着头脑但拆解一下就能明白它的核心“CoPaw”显然是“合作”和“爪子”的结合暗示了宠物尤其是猫狗的参与“Launch”则是启动、发射的意思。所以这大概率是一个让宠物通过某种互动方式来触发或控制某个设备或应用的智能项目。我作为一个养了十几年猫狗、又喜欢折腾点智能家居的“铲屎官”对这个方向特别有共鸣。我们总想给毛孩子们更好的生活但市面上大多数宠物智能产品要么是简单的自动喂食器、饮水机要么是单向的监控摄像头。真正能让宠物主动参与、形成“人宠互动”或“宠物与环境互动”闭环的产品少之又少。CoPawLaunch这个项目从标题就透露出一种“让宠物自己动手动爪”的创意它可能是一个通过宠物触碰、按压或经过特定区域来触发一系列有趣反馈比如播放音乐、投喂零食、打开玩具的智能装置。这个项目非常适合那些热爱宠物、喜欢DIY、并且对物联网或嵌入式开发有点兴趣的朋友。它不只是一个冷冰冰的代码仓库更像是一个桥梁连接了我们的技术热情和对宠物的关爱。接下来我就结合自己的经验和理解来深度拆解一下这样一个项目可能会涉及到的核心思路、技术选型以及实操中会遇到的各种“坑”。2. 核心设计思路与方案选型2.1 从“宠物行为”到“触发信号”的映射设计这类项目的首要问题也是最有意思的部分就是如何定义“Paw Launch”这个动作。宠物不会按按钮它们的互动方式和我们截然不同。我们需要选择一个既容易被宠物自然触发又足够可靠、能准确被设备识别的交互方式。常见的宠物可触发传感器有以下几种各有优劣压力传感器/薄膜开关这是最直观的“按钮”替代品。你可以把它藏在垫子、猫抓板或者特制的“启动板”下面。当宠物踩上去达到一定重量时电路导通产生信号。优点原理简单成本极低触发明确。缺点容易被误触发比如东西掉上去需要宠物有“踩踏”的意识对于猫来说可能不如拍打有吸引力。红外对射/激光光束传感器在通道或门口安装一对红外发射和接收管。当宠物穿过阻断光束时触发信号。优点非接触式非常可靠适合统计进出次数或作为“启动门槛”。缺点安装需要校准且只能检测“通过”这一行为互动感较弱。PIR被动红外运动传感器就是常见的智能安防人体传感器。它能检测到一定范围内的热源移动。优点检测范围广安装方便宠物只要进入区域就能触发。缺点无法区分是宠物还是人也无法识别具体的互动动作是靠近还是拍打误触发率高。电容式触摸传感器可以做成一块金属触摸板。当宠物或人的爪子接触时由于生物体的电容特性会改变传感器的电容值从而触发。优点互动感强可以做成各种形状如一个铜制的爪子印看起来酷。缺点电路稍复杂需要调试灵敏度潮湿环境或爪子沾水可能导致误触发。声音传感器麦克风简单识别检测特定的声音比如犬吠、猫叫或者更简单的——拍打声。优点非常自然宠物叫一声或拍一下就能触发。缺点环境噪音干扰大识别算法复杂容易受电视声、窗外噪音影响。我的选型建议与理由 对于一个DIY项目我强烈推荐“压力传感器”或“红外对射”作为起点。它们的信号是二进制的有/无处理起来最简单直接用单片机的数字IO口就能读取。特别是压力传感器你可以把它集成到一个宠物本来就喜欢的物件里比如一个柔软的猫窝边缘或者一个狗玩具内部通过训练让宠物关联“按压”和“奖励”。实操心得不要一开始就追求复杂的交互。先用最可靠的方式让整个流程跑通宠物触发 - 设备响应获得正反馈。复杂性可以后期叠加。我曾用一个薄膜开关和纸板做了一个简易的“打地鼠”玩具给猫玩它很快就学会了用爪子拍打有开关的那个洞来让玩具弹出这个过程本身就充满了乐趣。2.2 核心控制器大脑的选择传感器产生了信号谁来处理并执行“Launch”的动作这里就是核心控制器的选型。Arduino Uno/Nano物联网项目的经典入门选择。优点是生态极其丰富有无数关于传感器、执行器的库和教程学习成本低。缺点是性能有限如果要处理复杂逻辑或连接多路外设可能吃力而且原生不支持Wi-Fi/蓝牙需要额外模块。ESP8266如NodeMCU或ESP32这是当前智能硬件项目的绝对主流。它们本身就是为物联网而生集成了Wi-Fi功能性能也远超传统Arduino。ESP8266性价比之王足以胜任连接云端、处理HTTP请求等任务。ESP32功能更强大双核处理器还自带蓝牙如果需要更复杂的多任务处理或蓝牙连接比如连接手机App它是更好的选择。树莓派 Pico/RP2040基于树莓派自家芯片的方案性能强劲价格便宜但物联网生态相对ESP系列稍弱更适合作为学习嵌入式或需要大量GPIO和计算能力的项目。直接使用智能家居平台模块如涂鸦、小米IoT模块等。优点是能快速接入对应生态但DIY自由度低通常需要企业资质或特定开发流程不适合个人爱好者快速原型开发。我的选型建议与理由 对于CoPawLaunch这类项目ESP32几乎是完美的选择。理由如下无线连接是刚需我们很可能希望把触发事件记录下来或者通过手机收到通知甚至远程控制“Launch”的内容。ESP32自带的Wi-Fi功能是基础。足够的性能冗余双核处理器可以一个核心专用于处理传感器输入和响应保证实时性另一个核心处理网络通信互不干扰。丰富的GPIO和接口可以轻松连接多种传感器和执行器如舵机、电机、继电器。庞大的社区支持遇到任何问题几乎都能找到解决方案和现成代码。2.3 “Launch”什么执行器的想象力“启动”之后发生什么这才是项目乐趣的灵魂。这里完全可以大开脑洞物理反馈类舵机控制一个挡板打开让零食滚出来或者摆动一个逗猫棒。继电器控制普通家电的开关比如打开一台自动抛球机启动一个电动羽毛玩具。小型电机驱动一个传送带送出玩具或食物。声光反馈类RGB LED灯带宠物触发后灯光亮起或变换颜色营造氛围。蜂鸣器或小型MP3模块播放一段特定的声音比如奖励的“叮咚”声或者主人录制的鼓励话语。网络联动类发送网络请求触发IFTTT、Webhook从而在智能家居中执行一系列动作如打开客厅灯、在电视上显示宠物的照片、甚至给你的手机发送一条“你的猫刚刚启动了好运装置”的推送。控制多媒体通过集成开源媒体播放器触发播放一段宠物喜欢的视频比如鸟叫视频或音乐。我的建议从一个简单的、即时可见的反馈开始。比如宠物按压踏板旁边的LED灯闪烁同时舵机转动打开一个小零食仓。这种即时、正向的反馈对于训练宠物使用这个装置至关重要。网络联动可以作为第二阶段升级的目标。3. 系统架构与核心组件详解基于以上思路我们可以勾勒出一个典型的CoPawLaunch系统架构。它分为三层感知层、控制层、执行/云层。3.1 硬件组件清单与连接假设我们构建一个基础版本使用压力传感器作为触发ESP32作为大脑通过舵机打开零食仓并用LED灯提供视觉反馈。组件型号示例数量作用大致连接方式主控制器ESP32 DevKit V11系统大脑处理逻辑连接网络核心触发传感器FS4002 薄膜压力传感器1检测宠物按压动作接ESP32的某个GPIO口如GPIO4并配合上拉电阻执行器1SG90 9g微型舵机1控制零食仓门开关信号线接ESP32的PWM引脚如GPIO5执行器2WS2812B RGB LED灯珠3提供彩色灯光反馈数据线接ESP32的某个GPIO口如GPIO18电源5V/2A USB电源适配器1为整个系统供电为ESP32供电并通过面包板或PCB为其他模块供电其他面包板、杜邦线、电阻若干电路连接-连接示意图文字描述ESP32的3.3V和GND引脚连接到面包板的电源轨。薄膜压力传感器一端接GND另一端接GPIO4并在GPIO4与3.3V之间连接一个10KΩ上拉电阻确保未按压时引脚为高电平。SG90舵机的棕色线GND接面包板GND红色线VCC通常5V接面包板5V轨注意ESP32的USB供电一般能带动一个SG90但为稳定建议5V外接橙色线信号接GPIO5。WS2812B LED的VCC接5VGND接GNDDIN数据输入接GPIO18。注意事项舵机在启动和转动时电流较大可能引起ESP32复位。如果出现这种情况务必为舵机提供独立的5V电源可与ESP32共地或者在大电流电源路径上并联一个100-470μF的电解电容以稳定电压。3.2 软件逻辑与核心代码解析我们使用Arduino IDE进行开发因为它对ESP32和各类传感器库支持友好。核心逻辑流程初始化设置串口、连接Wi-Fi、初始化传感器引脚为输入、舵机引脚为输出、初始化LED库。主循环持续读取压力传感器引脚的电平。如果检测到低电平表示被按压则进入“触发处理程序”。触发处理程序防抖处理等待几十毫秒再次读取确认按压有效避免抖动误触发。执行反馈 a. 控制舵机从0度转到90度打开仓门。 b. 让RGB LED呈现一个庆祝性的流光效果。 c. 可选通过网络发送一条触发日志到服务器。复位与等待等待一段时间如5秒然后舵机转回0度关门LED恢复待机状态。在此期间忽略新的触发信号防止连续触发。关键代码片段示例#include WiFi.h #include Adafruit_NeoPixel.h // 用于WS2812B LED // 引脚定义 const int pressureSensorPin 4; const int servoPin 5; const int ledPin 18; const int numLeds 3; // 全局对象 Adafruit_NeoPixel pixels(numLeds, ledPin, NEO_GRB NEO_KHZ800); // Wi-Fi信息 const char* ssid 你的Wi-Fi名称; const char* password 你的Wi-Fi密码; // 状态变量 bool isTriggered false; unsigned long lastTriggerTime 0; const unsigned long cooldownPeriod 5000; // 冷却时间5秒 void setup() { Serial.begin(115200); pinMode(pressureSensorPin, INPUT_PULLUP); // 使用内部上拉简化电路 // 连接Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(WiFi connected); // 初始化LED pixels.begin(); pixels.show(); // 初始化为全灭 setStandbyLight(); // 设置待机灯光 // 初始化舵机使用LEDC PWM通道模拟舵机信号更稳定 ledcSetup(0, 50, 16); // 通道050Hz频率16位分辨率 ledcAttachPin(servoPin, 0); moveServo(0); // 初始位置0度关门 } void loop() { // 读取传感器状态低电平表示被按压 int sensorState digitalRead(pressureSensorPin); // 如果传感器被触发且不在冷却期内 if (sensorState LOW !isTriggered (millis() - lastTriggerTime cooldownPeriod)) { // 加入简单防抖 delay(50); if (digitalRead(pressureSensorPin) LOW) { triggerLaunchSequence(); } } // 其他常驻任务如维持Wi-Fi连接、检查网络指令等可以放在这里 } void triggerLaunchSequence() { isTriggered true; lastTriggerTime millis(); Serial.println(Paw Launch Detected!); // 1. 灯光反馈 - 快速闪烁绿色 for(int i0; i5; i) { pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // 绿色 pixels.setPixelColor(1, pixels.Color(0, 255, 0)); pixels.setPixelColor(2, pixels.Color(0, 255, 0)); pixels.show(); delay(200); pixels.clear(); pixels.show(); delay(200); } // 2. 执行舵机动作 - 开门 moveServo(90); // 转到90度位置开门 delay(3000); // 保持开门状态3秒让宠物取食 // 3. 可选发送网络通知 sendNotification(); // 4. 复位 moveServo(0); // 关门 setStandbyLight(); // 恢复待机灯光 isTriggered false; Serial.println(Launch Sequence Completed.); } void moveServo(int angle) { // 将角度0-180映射到PWM脉宽通常500-2500微秒 // ESP32 LEDC 16位分辨率下50Hz对应的周期是20000微秒 int pulseWidth map(angle, 0, 180, 500, 2500); // 映射到微秒 int duty map(pulseWidth, 0, 20000, 0, 65535); // 映射到16位占空比 ledcWrite(0, duty); delay(15); // 给舵机一点时间转动 } void setStandbyLight() { // 设置待机状态为缓慢呼吸的蓝色 // 这里简化处理设为低亮蓝色 pixels.setPixelColor(0, pixels.Color(0, 0, 20)); pixels.setPixelColor(1, pixels.Color(0, 0, 20)); pixels.setPixelColor(2, pixels.Color(0, 0, 20)); pixels.show(); } void sendNotification() { // 示例使用HTTP GET请求触发IFTTT Webhook WiFiClient client; const char* host maker.ifttt.com; const char* eventName copaw_launch; const char* key 你的IFTTT密钥; if (client.connect(host, 80)) { String url /trigger/ String(eventName) /with/key/ String(key); client.print(String(GET ) url HTTP/1.1\r\n Host: host \r\n Connection: close\r\n\r\n); delay(10); client.stop(); Serial.println(Notification sent.); } }这段代码实现了一个完整的基础流程。moveServo函数使用了ESP32的LEDC PWM库比传统的Servo.h库更稳定特别是当同时使用Wi-Fi时。4. 进阶功能与网络服务集成基础版本跑通后我们可以让项目变得更“智能”更有记录和互动性。4.1 数据记录与可视化我们可以让ESP32在每次触发时将数据时间戳、触发类型发送到一个云端数据库或日志服务。这里有几个简单的方案IFTTT Google Sheets如上文代码所示触发IFTTT的Webhook让IFTTT自动在Google Sheets表格中新增一行记录。这是零代码服务器方案非常适合新手。Blynk / ThingSpeak使用专门的IoT平台。Blynk可以快速搭建手机App界面显示触发次数和历史ThingSpeak则擅长数据收集和简单可视化图表。自建简单HTTP服务器在局域网内的另一台电脑或树莓派上运行一个Python Flask或Node.js写的简易服务器ESP32向这个服务器的特定API端点发送POST请求即可。以自建Python Flask服务器为例# server.py (运行在你的电脑上) from flask import Flask, request, jsonify from datetime import datetime import sqlite3 import threading app Flask(__name__) def init_db(): conn sqlite3.connect(copaw_launch.db) c conn.cursor() c.execute(CREATE TABLE IF NOT EXISTS events (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, event_type TEXT)) conn.commit() conn.close() app.route(/log_event, methods[POST]) def log_event(): data request.json event_type data.get(type, paw_press) conn sqlite3.connect(copaw_launch.db) c conn.cursor() c.execute(INSERT INTO events (event_type) VALUES (?), (event_type,)) conn.commit() conn.close() print(fEvent logged: {event_type} at {datetime.now()}) return jsonify({status: success}), 200 if __name__ __main__: init_db() # 注意在局域网内运行确保电脑防火墙允许5000端口 app.run(host0.0.0.0, port5000, debugTrue)然后在ESP32代码中将sendNotification函数改为向这个本地服务器发送POST请求。4.2 远程控制与状态反馈我们不仅可以上报数据还可以让手机App或网页反向控制设备或者查看设备状态。MQTT协议这是物联网设备通信的“标准语言”。ESP32可以作为一个MQTT客户端订阅接收和发布发送消息到一个MQTT代理服务器如Mosquitto。你可以通过手机MQTT客户端App发布一条“FEED_NOW”的消息ESP32收到后立即执行一次投喂。同时ESP32每次触发后也发布一条消息到“DEVICE/TRIGGER”主题。WebSocket在ESP32上建立一个简单的WebSocket服务器。然后编写一个简单的HTML页面通过JavaScript连接这个WebSocket。这样就能实现网页实时显示触发状态甚至通过网页按钮控制设备。使用MQTT的简单示例需安装PubSubClient库#include PubSubClient.h #include WiFi.h WiFiClient espClient; PubSubClient client(espClient); const char* mqtt_server 你的MQTT代理IP; // 例如本地Mosquitto服务器 void callback(char* topic, byte* payload, unsigned int length) { Serial.print(Message arrived [); Serial.print(topic); Serial.print(] ); String message; for (int i 0; i length; i) { message (char)payload[i]; } Serial.println(message); // 如果收到远程投喂指令 if (String(topic) copaw/device/command) { if (message LAUNCH_NOW) { triggerLaunchSequence(); // 调用之前的触发函数 } } } void reconnectMQTT() { while (!client.connected()) { if (client.connect(ESP32_PawLauncher)) { client.subscribe(copaw/device/command); client.publish(copaw/device/status, online); } else { delay(5000); } } } void setup() { // ... 其他初始化代码 client.setServer(mqtt_server, 1883); // 默认端口1883 client.setCallback(callback); } void loop() { if (!client.connected()) { reconnectMQTT(); } client.loop(); // ... 原有的传感器检测循环 } // 在 triggerLaunchSequence 函数最后添加发布消息 void triggerLaunchSequence() { // ... 原有的灯光、舵机操作 // 发布触发消息 if (client.connected()) { client.publish(copaw/device/events, paw_launch_triggered); } // ... 后续复位操作 }这样你就拥有了一个可以双向通信的智能宠物启动器。5. 外壳设计与宠物安全考量硬件和软件都搞定后如何把它包装成一个宠物友好且耐用的产品是项目成功落地的最后一步也是至关重要的一步。5.1 结构设计与材料选择坚固性宠物尤其是狗可能会啃咬、抓挠设备。外壳必须坚固。亚克力板激光切割是一个好选择容易加工外观也漂亮。3D打印使用PETG或ABS材料则能做出更复杂的结构但需要一定的建模能力。安全性所有边角必须打磨圆滑避免划伤宠物。内部电路必须完全封闭防止宠物触及电线或电路板。螺丝等小零件一定要固定好防止脱落被误食。互动区域设计压力传感器所在的“启动板”区域应该设计得对宠物有吸引力。可以贴上不同材质的垫子如剑麻垫、软绒布或者在周围放置宠物喜欢的猫薄荷、零食碎屑来引导。零食/玩具仓设计仓门开关要顺畅舵机的力量要足够。出口大小要合适既能顺利送出奖励又不会一次掉出太多。考虑增加一个透明的观察窗让你和宠物都能看到里面的“奖励”。5.2 电源安全与线缆管理使用低压直流电源整个系统应使用5V或12V的直流电源适配器绝对避免220V市电直接进入宠物可接触的范围。电池备份考虑如果不想一直插着电源可以考虑加入18650锂电池和充放电管理模块但务必做好电池的物理防护和充放电保护电路防止过热或短路。线缆收纳所有外露的线缆要用螺旋管或线槽包裹起来防止被咬断。电源适配器最好放在宠物够不到的角落。实操心得血泪教训我曾经用一个纸壳做原型被家里的狗十分钟内拆成了碎片。所以在让宠物接触最终版本前务必先进行“破坏性测试”。你可以模拟宠物的拍打、啃咬动作检查外壳是否牢固零件是否松动。另外首次引入新设备时一定要在旁边观察。有些宠物可能会对突然的动作或声音感到害怕需要循序渐进地引导。可以先手动触发几次让宠物把设备和美好的奖励零食联系起来再进行自主触发训练。6. 项目优化与扩展方向当一个基础版本稳定运行后你可以考虑以下方向进行升级让CoPawLaunch变得更强大、更智能。6.1 多模态交互与识别单一的触发方式可能会腻或者容易被误触发。可以尝试融合多种传感器压力红外必须同时满足“踩上踏板”和“头部/身体穿过红外光束”才触发这样可以确保是宠物有意的完整动作而不是偶然路过踩到。声音识别使用更复杂的开发板如带麦克风的ESP32-S3或外接音频处理模块结合TinyML等轻量级机器学习框架尝试识别特定的叫声如“汪汪”两声作为触发条件。这门槛较高但非常酷。计算机视觉高阶使用树莓派摄像头配合OpenCV实现更复杂的交互。例如识别宠物是否做出了“击掌”的动作或者当宠物盯着某个目标看超过3秒后才触发。这需要较强的编程和算法能力。6.2 云端智能与数据分析将数据上传到云端后可以做更多事情行为模式分析分析宠物在一天中哪个时间段最活跃、触发最频繁。是早上你出门后还是晚上你回家前这些数据能帮你更好地了解宠物的作息和情绪。远程互动升级不止接收通知你可以开发一个简单的App在上班时看到宠物触发装置后可以手动点击App上的按钮额外多投放一次零食或者启动一个远程逗猫棒实现真正的远程互动。集成智能家居将CoPawLaunch深度接入Home Assistant等开源智能家居平台。可以设置自动化如果宠物在下午3点到5点之间触发了装置且今天户外天气不好通过API获取就自动打开客厅的智能灯播放一段轻松的音乐。6.3 游戏化与长期激励防止宠物对设备失去兴趣是关键。可变奖励机制不要每次都给同样的奖励。可以编写程序让每次触发有70%概率出零食20%概率亮起炫酷灯效并播放一段“恭喜”音效10%概率“中大奖”连续出三次零食。这种不确定性会极大增加宠物的探索欲。挑战模式增加第二个触发点或者要求宠物在限定时间内连续触发两次才能获得奖励。这可以锻炼宠物的智力和反应。数据面板为你的宠物建立一个专属的“成就面板”显示“今日启动次数”、“历史总次数”、“最快反应速度”等趣味数据分享给朋友也很有意思。7. 常见问题与故障排查实录在动手制作和调试过程中你几乎一定会遇到下面这些问题。这里是我踩过坑后总结的排查清单。问题现象可能原因排查步骤与解决方案ESP32无法连接Wi-Fi1. SSID/密码错误2. Wi-Fi信号太弱3. 路由器设置了MAC过滤或仅允许特定设备1. 检查代码中的SSID和密码注意大小写和特殊字符。2. 将设备靠近路由器测试。3. 在串口监视器中查看连接状态代码根据代码搜索具体含义。压力传感器一直触发或无反应1. 接线错误或接触不良2. 上拉/下拉电阻未正确配置3. 传感器本身损坏1. 用万用表测量传感器未按压时的电阻应为兆欧级按压时应导通接近0欧姆。2. 确保代码中使用了INPUT_PULLUP或者硬件上正确连接了上拉电阻。3. 更换一个传感器测试。舵机抖动或不转动1. 供电不足2. PWM信号问题3. 机械卡死1.这是最常见原因务必为舵机提供独立、充足的5V电源至少1A并与ESP32共地。2. 检查PWM频率是否为50Hz脉宽范围是否正确500-2500μs。使用ledcWrite函数更稳定。3. 手动转动舵机盘检查是否有阻碍。LED灯不亮或颜色错乱1. 数据线接反或接触不良2. 供电不足WS2812B全白时电流很大3. 库未正确初始化或引脚错误1. 确认VCC、GND、DIN接线正确。WS2812B对时序敏感数据线必须接指定的GPIO。2. 计算LED全亮时的总电流如3颗*60mA180mA确保电源能承受。3. 检查Adafruit_NeoPixel库是否安装begin()和show()函数是否调用。程序运行一段时间后死机或重启1. 内存泄漏尤其在网络操作后2. 看门狗定时器超时3. 电源波动1. 检查代码中动态内存分配如String拼接尽量使用静态缓冲区。确保网络客户端connect后最终会stop。2. 在长时间循环或阻塞操作中适时调用yield()或delay(0)让看门狗喂狗。3. 在电源输入端并联一个大电容如1000μF稳压。网络请求如HTTP/MQTT经常失败1. 网络不稳定2. 服务器地址或端口错误3. 未处理连接断开重连1. 增加Wi-Fi信号强度或在代码中加入重连机制。2. 用电脑ping一下服务器地址用网络调试工具测试端口是否开放。3.必须在loop()中实现重连逻辑如上面MQTT示例中的reconnectMQTT()函数。宠物对设备毫无兴趣1. 奖励不够有吸引力2. 触发方式太难或太隐蔽3. 设备外观或声音让宠物害怕1. 使用宠物最爱的高价值零食如冻干作为奖励。2. 降低触发门槛先用引导如用零食引诱爪子触碰进行训练。3. 首次运行时你自己先演示几次让宠物观察。关闭可能吓到它的蜂鸣器用柔和的灯光代替。这个项目从构思到实现再到不断迭代优化整个过程就像在为你和你的宠物共同打造一个专属的智能玩具。它不仅仅是技术的堆砌更是情感和创意的结合。当你看到家里的毛孩子第一次自己成功触发装置获得奖励时那种疑惑又兴奋的表情所有的调试和折腾都值了。最重要的是在这个过程中你不仅学到了硬件连接、嵌入式编程、网络通信的知识更收获了一段独一无二的、与宠物互动的美好记忆。