在快节奏的生活中一只可爱的桌面宠物或许是解压的最佳伙伴。市面上的电子宠物大多功能单一、不可编程而专业机器人平台又价格高昂、门槛过高。本项目基于深圳大夏龙雀科技 BT36 蓝牙模块与 STM32F103C6T6A 主控仅用面包板 杜邦线 4个SG90舵机 一块OLED屏 一节18650电池就打造出一只可蓝牙遥控、会做表情、能动作卖萌的桌面宠物机器人。配套开发了微信小程序作为控制端实现了从硬件到软件的全栈设计。一、项目背景1.1 创作初衷一直想做一个既有技术含量又充满趣味的DIY项目。工业类项目虽然硬核但缺乏传播力纯玩具类又显得技术深度不足。最终选择了桌面宠物机器人这个方向——趣味性强可爱的外形、多种表情、跳舞卖萌天然适合展示分享技术覆盖全涉及嵌入式开发、蓝牙通信、PWM舵机控制、I2C显示驱动、微信小程序开发技术栈完整门槛低可复制面包板搭建、耗材便宜、结构简单读者跟着教程就能复刻1.2 核心功能功能模块具体功能运动控制前进 / 后退 / 左转 / 右转 / 停止表情系统开心 / 困困 / 生气 / 惊讶 四种表情炫彩灯效呼吸灯 / 彩虹灯 / 闪烁灯 / 常亮灯组合动作跳舞 / 打招呼 / 卖萌控制方式微信小程序 蓝牙遥控器双模式供电方式单节18650锂电池移动便携二、整体架构桌面宠物机器人采用应用层小程序、遥控— 通信层BT36蓝牙— 控制层STM32— 执行层舵机、OLED、LED四层架构2.1 工作原理蓝牙连接大夏龙雀 BT36 模块上电后自动广播手机微信小程序或蓝牙遥控器搜索并建立 BLE 连接指令下发用户在小程序端点击方向键、表情按钮或灯效按钮指令通过 BLE 透传至 BT36UART通信BT36 通过 UART 将指令发送给 STM32F103C6T6A 主控指令解析STM32 解析指令格式执行对应的舵机运动、OLED表情切换或RGB灯效变换状态回复执行完成后通过蓝牙回复 ACK小程序端更新状态显示。2.2 硬件选型模块型号接口数量说明主控STM32F103C6T6A-×1LQFP-48封装资源充足蓝牙大夏龙雀 BT36UART×1BLE5.3主从一体AT指令配置显示0.96 OLEDI2C×1128×64分辨率SSD1306驱动舵机SG90 微型舵机PWM×4180°旋转重量轻适合桌面级灯光RGB LED共阴PWM×1三原色混合实现炫彩效果电源18650 锂电池-×13.7V/2000mAh以上续航持久搭建面包板 杜邦线-若干免焊接快速原型验证三、硬件设计3.1 硬件连接总览全部电路通过面包板 杜邦线搭建无需PCB零基础也能快速上手。连接示意图如下3.2 引脚分配// STM32F103C6T6A 引脚分配 #define SERVO_LEFT_LEG_PIN GPIO_Pin_0 // PA0 - 左腿 #define SERVO_RIGHT_LEG_PIN GPIO_Pin_1 // PA1 - 右腿 #define SERVO_LEFT_FOOT_PIN GPIO_Pin_2 // PA2 - 左前足 #define SERVO_RIGHT_FOOT_PIN GPIO_Pin_3 // PA3 - 右前足 #define OLED_SDA_PIN GPIO_Pin_7 // PB7 - I2C SDA #define OLED_SCL_PIN GPIO_Pin_6 // PB6 - I2C SCL #define BT_TX_PIN GPIO_Pin_9 // PA9 - USART1 TX #define BT_RX_PIN GPIO_Pin_10 // PA10 - USART1 RX #define LED_R_PIN GPIO_Pin_8 // PA8 - TIM1 CH1 #define LED_G_PIN GPIO_Pin_9 // PB9 - TIM4 CH4 #define LED_B_PIN GPIO_Pin_8 // PB8 - TIM4 CH33.3 舵机驱动原理SG90舵机的驱动信号是20ms周期的PWM波高电平宽度从0.5ms到2.5ms对应0°到180°高电平宽度对应角度0.5ms0°1.0ms45°1.5ms90°中位2.0ms135°2.5ms180°通过STM32定时器PWM输出动态调整CCR寄存器即可控制舵机角度。四只舵机分别控制两条后腿和两只前足通过协调不同的角度组合实现前进、后退、转向等步态。3.4 电源方案单节18650锂电池3.7V标称电压直接为整个系统供电STM32F103C6T6A工作电压2.0~3.6V核心板自带的LDO即可实现MCU供电SG90舵机工作电压4.8V典型3.7V也能工作但扭矩稍小桌面宠物重量轻完全够用BT36蓝牙模块支持3.3~5V宽电压3.7V直接供电OLED显示屏3.3V供电由STM32的3.3V引脚我们使用的锂电池充放电方案是TP4056直接粘贴在面包板上方便使用Type-C接口直接对18650锂电池进行充电。四、机械结构设计桌面宠物采用4舵机方案结构简单、动作灵活4.1 四舵机布局后腿 ×2左右各一只负责主要的行走动力输出摆动范围约60°前足 ×2左右各一只负责辅助支撑和姿态调整使动作更自然可爱4.2 步态原理通过四只舵机的角度协调变化实现不同运动前进步态左前足抬起 → 右腿后蹬 → 身体前倾右前足抬起 → 左腿后蹬 → 身体继续前进交替循环实现蹒跚学步的可爱效果转向原理左转右腿加速前摆左腿减速或小幅后摆身体向左偏转右转左腿加速前摆右腿减速或小幅后摆身体向右偏转4.3 结构材质我们使用的刚好是面包板无需任何焊接即可实现电路的快速搭建可以用建议先用简单材料验证步态满意后再做精致外壳。五、OLED表情系统小小的OLED屏幕是宠物的灵魂之窗通过绘制不同表情赋予宠物性格5.1 四种基础表情表情触发场景视觉效果开心正常待机 / 收到指令执行成功弯弯笑眼 上扬嘴角困困长时间无操作 / 夜晚模式眯成一条缝 Zzz生气连续撞墙 / 被频繁打扰倒八字眉 嘴角下撇惊讶首次连接 / 收到新指令圆眼睛 O型嘴5.2 表情绘制实现使用SSD1306驱动的0.96寸OLED128×64通过I2C通信// 表情数据结构 typedef struct { const uint8_t *face_data; // 表情位图数据 uint8_t width; // 表情宽度 uint8_t height; // 表情高度 } Expression_t; // 表情枚举 typedef enum { EXP_HAPPY 0, // 开心 EXP_SLEEPY 1, // 困困 EXP_ANGRY 2, // 生气 EXP_SURPRISE 3 // 惊讶 } Expression_Type; // 切换表情函数 void OLED_ShowExpression(Expression_Type exp) { // 清屏 OLED_Clear(); // 在屏幕中央绘制表情 uint8_t x (128 - expressions[exp].width) / 2; uint8_t y (64 - expressions[exp].height) / 2; OLED_DrawBMP(x, y, expressions[exp].width, expressions[exp].height, expressions[exp].face_data); // 可附加装饰脸颊红晕等 if(exp EXP_HAPPY) { OLED_DrawCircle(30, 40, 5, 1); // 左脸颊 OLED_DrawCircle(98, 40, 5, 1); // 右脸颊 } OLED_Refresh(); }表情图案可以用LCD Image Converter或类似工具将图片转换为C数组直接嵌入代码中。六、RGB炫彩灯效RGB LED是宠物的氛围担当四种灯效模式随心切换6.1 四种灯效模式模式效果描述适用场景呼吸灯PWM渐变亮灭温柔如呼吸待机状态安静优雅彩虹灯RGB三色循环渐变炫彩夺目跳舞时活泼热闹闪烁灯快速闪烁活泼俏皮开心/惊讶时常亮灯稳定单色光柔和护眼夜灯模式温暖陪伴6.2 PWM混色原理三路独立PWM每路8位分辨率0~255可混合出约1677万种颜色// RGB颜色设置函数 void RGB_SetColor(uint8_t r, uint8_t g, uint8_t b) { // 直接修改CCR寄存器0~255映射到0~ARR TIM_SetCompare1(TIM1, r); // R通道 TIM_SetCompare3(TIM4, g); // G通道 TIM_SetCompare4(TIM4, b); // B通道 } // 呼吸灯效果 void LED_Breathing_Effect(void) { static uint8_t brightness 0; static uint8_t direction 1; if(direction) { brightness; if(brightness 200) direction 0; } else { brightness--; if(brightness 0) direction 1; } RGB_SetColor(brightness, brightness / 2, 0); // 暖橙色呼吸 }七、蓝牙通信协议通信核心是深圳大夏龙雀科技 BT36 蓝牙模块这是整个项目的无线桥梁。7.1 BT36 模块特性BT36 是大夏龙雀出品的高性价比 BLE 5.3 模块采用 DIALOG DA14535 芯片主从一体设计。在本项目中它的优势体现在BLE 5.3 协议连接速度快、功耗低、抗干扰能力强主从一体既可作从机被手机连接也可作主机连接遥控器AT指令丰富支持修改设备名、波特率、UUID、发射功率等参数响应迅速10ms宽电压工作3.3V~5V直接接锂电池无需额外电平转换UART透传透明传输模式开发简单像操作串口一样使用蓝牙通信距离远空旷环境下可达数十米桌面场景绰绰有余在实际开发中BT36的稳定性令人印象深刻——电机PWM信号产生的电磁干扰对蓝牙通信几乎没有影响连接稳定不掉线这对于面包板搭建的原型项目来说非常关键。7.2 通信协议设计采用简洁易解析的文本指令协议便于调试和扩展7.3 串口解析实现// 蓝牙数据接收缓冲区 #define BT_RX_BUF_SIZE 64 uint8_t bt_rx_buf[BT_RX_BUF_SIZE]; uint8_t bt_rx_index 0; // USART1 中断接收BT36连接 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { uint8_t ch USART_ReceiveData(USART1); if(ch \n || bt_rx_index BT_RX_BUF_SIZE - 1) { bt_rx_buf[bt_rx_index] \0; // 完整指令解析处理 BT_Parse_Command((char*)bt_rx_buf); bt_rx_index 0; } else if(ch ! \r) { bt_rx_buf[bt_rx_index] ch; } } } // 指令解析函数 void BT_Parse_Command(char *cmd) { if(strncmp(cmd, FWD, 3) 0) { Servo_WalkForward(); OLED_ShowExpression(EXP_HAPPY); BT_SendString(OK\r\n); } else if(strncmp(cmd, BACK, 4) 0) { Servo_WalkBackward(); BT_SendString(OK\r\n); } else if(strncmp(cmd, LEFT, 4) 0) { Servo_TurnLeft(); BT_SendString(OK\r\n); } else if(strncmp(cmd, RIGHT, 5) 0) { Servo_TurnRight(); BT_SendString(OK\r\n); } else if(strncmp(cmd, STOP, 4) 0) { Servo_Stop(); BT_SendString(OK\r\n); } else if(strncmp(cmd, EXP:, 4) 0) { uint8_t exp_num cmd[4] - 0; if(exp_num 3) { OLED_ShowExpression(exp_num); BT_SendString(OK\r\n); } } else if(strncmp(cmd, LED:, 4) 0) { uint8_t led_num cmd[4] - 0; if(led_num 3) { LED_SetMode(led_num); BT_SendString(OK\r\n); } } else if(strncmp(cmd, ACT:, 4) 0) { Action_Execute(cmd 4); BT_SendString(OK\r\n); } else { BT_SendString(ERR\r\n); } }八、系统控制流程8.1 主循环结构int main(void) { // 系统初始化 SystemInit(); Servo_Init(); // 舵机PWM初始化 OLED_Init(); // OLED初始化 RGB_Init(); // RGB灯PWM初始化 USART1_Init(9600); // 蓝牙串口初始化BT36默认9600 // 开机动画 OLED_ShowExpression(EXP_HAPPY); LED_SetMode(LED_BREATHING); Servo_WaveHello(); // 开机打招呼 while(1) { // 检查是否收到蓝牙指令 if(bt_cmd_ready) { BT_Parse_Command(bt_cmd_buffer); bt_cmd_ready 0; } // LED灯效任务 LED_Task_Handler(); // 待机检测 if(HAL_GetTick() - last_cmd_time 10000) { if(current_expression ! EXP_SLEEPY) { OLED_ShowExpression(EXP_SLEEPY); LED_SetMode(LED_BREATHING); // 柔和呼吸 } } } }8.2 组合动作实现组合动作是让宠物活起来的关键通过编排一系列舵机角度序列实现// 跳舞动作序列 void Action_Dance(void) { OLED_ShowExpression(EXP_HAPPY); LED_SetMode(LED_RAINBOW); // 彩虹灯效 // 左右摇摆 前足摆动 for(int i 0; i 4; i) { Servo_SetAngle(SERVO_LEFT_LEG, 60 i * 15); Servo_SetAngle(SERVO_RIGHT_LEG, 120 - i * 15); Delay_Ms(200); } for(int i 0; i 4; i) { Servo_SetAngle(SERVO_LEFT_LEG, 120 - i * 15); Servo_SetAngle(SERVO_RIGHT_LEG, 60 i * 15); Delay_Ms(200); } // 前足上下摆动 for(int i 0; i 3; i) { Servo_SetAngle(SERVO_LEFT_FOOT, 45); Servo_SetAngle(SERVO_RIGHT_FOOT, 45); Delay_Ms(150); Servo_SetAngle(SERVO_LEFT_FOOT, 135); Servo_SetAngle(SERVO_RIGHT_FOOT, 135); Delay_Ms(150); } Servo_Stop(); LED_SetMode(LED_BREATHING); } // 打招呼动作 void Action_Hello(void) { OLED_ShowExpression(EXP_HAPPY); // 右前足抬起挥动 for(int i 0; i 3; i) { Servo_SetAngle(SERVO_RIGHT_FOOT, 30); Delay_Ms(200); Servo_SetAngle(SERVO_RIGHT_FOOT, 60); Delay_Ms(200); } Servo_Stop(); }九、微信小程序控制端为了让宠物的控制更便捷、作品更完整开发了配套的微信小程序控制端通过 BLE 直接连接 BT36 模块9.1 小程序功能架构小程序包含三个主要页面页面功能控制页方向控制 表情切换 灯效选择 快捷动作设置页舵机角度微调、响应速度设置、自动休眠时间关于页作品介绍、版本信息、教程链接9.2 BLE连接核心代码// 小程序端 - 蓝牙连接与控制 const DEVICE_NAME DX-BT36; // BT36默认设备名 const SERVICE_UUID 0000FFE0-0000-1000-8000-00805F9B34FB; const CHAR_UUID 0000FFE1-0000-1000-8000-00805F9B34FB; let deviceId null; let connected false; // 搜索并连接设备 function connectDevice() { wx.startBluetoothDevicesDiscovery({ services: [SERVICE_UUID], success: (res) { console.log(开始搜索设备); wx.onBluetoothDeviceFound((devices) { const device devices.devices.find(d d.name DEVICE_NAME || d.localName DEVICE_NAME ); if(device) { wx.stopBluetoothDevicesDiscovery(); createConnection(device.deviceId); } }); } }); } // 建立连接 function createConnection(id) { wx.createBLEConnection({ deviceId: id, success: () { deviceId id; connected true; wx.showToast({ title: 连接成功, icon: success }); // 监听特征值变化 wx.notifyBLECharacteristicValueChange({ deviceId, serviceId: SERVICE_UUID, characteristicId: CHAR_UUID, success: () { wx.onBLECharacteristicValueChange((res) { const data ab2str(res.value); console.log(收到:, data); }); } }); } }); } // 发送指令 function sendCommand(cmd) { if(!connected) { wx.showToast({ title: 请先连接设备, icon: none }); return; } const buffer str2ab(cmd \r\n); wx.writeBLECharacteristicValue({ deviceId, serviceId: SERVICE_UUID, characteristicId: CHAR_UUID, value: buffer, success: () console.log(发送:, cmd) }); } // 工具函数字符串转ArrayBuffer function str2ab(str) { const buffer new ArrayBuffer(str.length); const view new Uint8Array(buffer); for(let i 0; i str.length; i) { view[i] str.charCodeAt(i); } return buffer; } function ab2str(buffer) { return String.fromCharCode.apply(null, new Uint8Array(buffer)); } // 方向控制按钮 const control { forward: () sendCommand(FWD), backward: () sendCommand(BACK), turnLeft: () sendCommand(LEFT), turnRight: () sendCommand(RIGHT), stop: () sendCommand(STOP), }; // 表情切换 const expressions { happy: () sendCommand(EXP:0), sleepy: () sendCommand(EXP:1), angry: () sendCommand(EXP:2), surprise: () sendCommand(EXP:3), }; // 灯效切换 const ledModes { breathing: () sendCommand(LED:0), rainbow: () sendCommand(LED:1), blink: () sendCommand(LED:2), solid: () sendCommand(LED:3), }; // 快捷动作 const actions { dance: () sendCommand(ACT:DANCE), hello: () sendCommand(ACT:HELLO), cute: () sendCommand(ACT:CUTE), };9.3 小程序界面设计要点方向控制区D-pad方向键布局中间键为停止符合游戏手柄使用习惯表情切换区4个表情按钮横向排列点击即切换状态反馈清晰灯效选择区4种灯效彩色按钮视觉上即传达灯光氛围快捷动作区跳舞/打招呼/卖萌三个大按钮一键触发组合动作状态栏顶部实时显示连接状态已连接显示绿色圆点十、项目总结这款桌面宠物机器人虽然只用面包板搭建但麻雀虽小五脏俱全从硬件到软件实现了完整的全栈设计10.1 项目亮点全栈自主设计从电路搭建、嵌入式程序到微信小程序端到端完整实现技术覆盖面广BT36深度适配充分发挥大夏龙雀 BT36 蓝牙模块的性能优势BLE5.3稳定连接、AT指令灵活配置、宽电压适配面包板入门友好无需PCB、无需焊接所有耗材易购降低了复刻门槛适合教学和推广趣味性与传播性可爱的表情、灵动的动作、微信小程序控制天然适合短视频和社交分享扩展性强可以不断添加新表情、新动作、新传感器触摸/声音/光线持续迭代10.2 成本清单物料单价参考数量小计STM32F103C6T6A 最小系统板约15元×115元大夏龙雀 BT36 蓝牙模块约20元×120元SG90 微型舵机约5元×420元0.96 OLED 显示屏约8元×18元RGB LED 电阻约1元×11元18650 锂电池 电池盒约10元×110元面包板 杜邦线约10元若干10元总计--约84元