近期,DFRobot 发布行空板 M10 扩展板组合 —— 行空板 M10 电机 IO 扩展板与 M10 电池扩展板。该组合专为行空板(UNIHIKER)M10 在机器人控制、物联网终端、移动创客项目开发中面临的移动供电难题、接口数量不足、动态控制复杂等场景痛点,提供了便携式开发解决方案。
1 硬件简介
1.1 电池扩展板
行空板 M10 电池扩展板采用 9mm 超薄设计,搭载 800mAh 锂电池,结合隐藏式弹针连接方式,与 M10 组合后整机厚度仅增加 6.6mm ,4 颗 LED 电量指示灯,充电电路及充电指示功能。
1.2 电机 IO 扩展板
行空板 M10 电机 IO 扩展板提供 3 路数字 / 模拟接口、1 路 3.3V I2C 接口、1 路 5V I2C 接口以及 2 路直流电机驱动接口,板载的 2 颗 WS2812 可编程 RGB 灯珠、1 颗红外发射管和 1 颗红外接收管。
2 任务一:“自由行走”的智能小车
任务目标:
1、基于行空板M10+行空板 M10 电池扩展板+行空板 M10 电机 IO 扩展板,完成小车的搭建。
2、编写基于Mind+的行空板 M10 扩展板用户库,实现对扩展板红外发射管、红外接收管、WS2812灯、电机接口以及舵机功能的测试。
步骤1 硬件搭建
如上图所示,先将金手指转接板插到行空板M10的金手指上,接着使用M3的螺丝将电池扩展板固定在行空板 M10 上,最后将电机IO扩展板用 M3螺丝固定在电池扩展板上。

将N20减速电机固定在小车底盘,将小车底盘用M3螺丝固定在IO扩展板上,再将电机电源线插到电机 IO 扩展板的 M1 和 M2 接口。
将舵机链接到P0接口。
步骤2 用户库编写

步骤3 用户库导入
在 Mind+ Python模式下,导入项目所需的用户库。
用户库加载地址:https://gitee.com/hmilycheng/ext-Unihiker_IOExtension

步骤4 程序编写
完成下图所示程序编写。

步骤5 程序运行
import time
from unihiker import GUI
from shield import SHIELD
from pinpong.extension.unihiker import *
from pinpong.board import Board,Pin,NeoPixel,IRRemote,IRRecv,Servo
# 事件回调函数
def ir_callback(data):
print(data)
txt_ir.config(text=data)
u_gui=GUI()
Board().begin()
shield = SHIELD()
ir = shield.ir
ir.set_receive_callback(ir_callback)
RGB = NeoPixel(Pin((Pin.P13)),3)
txt_moto=u_gui.draw_text(text="",x=60,y=70,font_size=40, color="#0000FF")
txt_ir=u_gui.draw_text(text="",x=30,y=150,font_size=30, color="#0000FF")
RGB.brightness(128)
RGB.clear()
while True:
ir.send(0xfd807f)
RGB.range_color(0,1,0x00FF00)
txt_moto.config(text="前进")
shield.m1.run(1,512)
shield.m2.run(1,512)
shield.servo1.write_angle(0)
time.sleep(5)
RGB.range_color(0,1,0xFFFFFF)
txt_moto.config(text="后退")
shield.m1.run(0,512)
shield.m2.run(0,512)
shield.servo1.write_angle(90)
time.sleep(5)
3 任务二:远程巡检机器人
3.1 任务目标
本项目在原有"自由行"智能小车基础上增加USB摄像头,实现远程监控和遥控功能。通过SIoT服务器构建完整的物联网监控系统,支持远程控制、实时视频传输和环境数据监测。
3.2 硬件清单
序号 | 名称 | 数量 | 链接 | 备注 |
1 | 行空板M10 | 1 | https://www.dfrobot.com.cn/goods-3404.html | |
2 | 行空板M10电机IO扩展板+电池扩展板 | 1 | https://www.dfrobot.com.cn/goods-4127.html | |
4 | USB摄像头 | 1 | https://www.dfrobot.com.cn/goods-2847.html | |
5 | 多功能环境传感器 | 1 | https://www.dfrobot.com.cn/goods-2821.html |
3.3 系统架构

3.4 功能实现
环境监测:实时显示温度、湿度、海拔、气压、CO2、TVOC
视频监控:Base64格式传输实时视频
运动控制:前进/后退/左转/右转/停止
灯光控制:远程开关LED灯
3.5 添加用户库
添加“官方库”——行空板M10、OpenCV、MQTT-py

添加“用户库”——base64、多功能环境传感器v1

3.6 SIOT服务器
1. 下载SIoT V2
下载链接:
腾讯微云下载(推荐):
链接: https://share.weiyun.com/6SFhgLQj
百度云盘下载:
链接:https://pan.baidu.com/s/17clVjJXWTZh02FteKy3mcA?pwd=mind
提取码:mind
阿里云盘下载:
https://www.aliyundrive.com/s/tCqwJwGtZzL
提取码: 3h4x
谷歌云盘下载:
链接: 点击下载
2. 启动SIoT V2
下载后win版本的SIoT V2解压,双击start SIoT.bat即可启动新版SIoT。
注意:启动时需要将SIoT添加到允许应用通过防火墙,勾选专用网络和公用网络,否则外部设备可能无法访问
启动之后会弹出小黑窗启动服务器。
在浏览器输入 上图中地址192.168.123.29:8080 即可打开网页,输入账号siot,密码dfrobot,点击“登录”。
登录成功后,即可单击“新建主题(Topic)”创建主题。
新建主题如下:

3.6 流程图

3.7 程序编写
1、编写程序

import sys
sys.path.append("/root/mindplus/.lib/thirdExtension/nick-base64-thirdex")
sys.path.append("/root/mindplus/.lib/thirdExtension/doudad-environment-thirdex")
sys.path.append("/root/mindplus/.lib/thirdExtension/doudad-unihiker_ioextension-thirdex")
import cv2
import siot
import time
from unihiker import GUI
from shield import SHIELD
from pinpong.board import Board
from pinpong.extension.unihiker import *
from pinpong.libs.dfrobot_bme280 import BME280
import base64
from io import BytesIO
from PIL import Image
from pinpong.libs.dfrobot_ccs811 import CCS811, CCS811_Ecycle
from pinpong.board import Board,Pin,NeoPixel,IRRemote,IRRecv,Servo
# 事件回调函数
def u_sensor_thread_function():
while True:
if p_ccs811.check_data_ready():
siot.publish_save(topic="siot/temp", data=p_bme280.temp_c())
siot.publish_save(topic="siot/humidity", data=p_bme280.humidity())
siot.publish_save(topic="siot/pressure", data=p_bme280.press_pa())
siot.publish_save(topic="siot/altitude", data=p_bme280.cal_altitudu())
siot.publish_save(topic="siot/CO2", data=p_ccs811.co2_ppm())
siot.publish_save(topic="siot/TVOC", data=p_ccs811.tvoc_ppb())
time.sleep(1)
def u_video_thread_function():
while True:
ret, img = vd.read()
siot.publish_save(topic="siot/video", data=base642base64(img))
def on_message_callback(client, userdata, msg):
if (msg.topic == "siot/control"):
if (msg.payload.decode() == "forward"):
shield.m1.run(1,512)
shield.m2.run(1,512)
elif (msg.payload.decode() == "back"):
shield.m1.run(0,512)
shield.m2.run(0,512)
elif (msg.payload.decode() == "left"):
shield.m1.run(1,512)
shield.m2.run(0,512)
elif (msg.payload.decode() == "right"):
shield.m1.run(0,512)
shield.m2.run(1,512)
else:
shield.m1.stop()
shield.m2.stop()
siot.init(client_id="9570056851423367",server="192.168.123.29",port=1883,user="siot",password="dfrobot")
u_gui=GUI()
siot.connect()
siot.loop()
siot.set_callback(on_message_callback)
Board().begin()
shield = SHIELD()
vd = cv2.VideoCapture()
vd.set(cv2.CAP_PROP_FRAME_WIDTH,640)
vd.set(cv2.CAP_PROP_FRAME_HEIGHT,480)
vd.open(0)
def frame2base64(frame):
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame) #将每一帧转为Image
output_buffer = BytesIO() #创建一个BytesIO
img.save(output_buffer, format='JPEG') #写入output_buffer
byte_data = output_buffer.getvalue() #在内存中读取
base64_data = base64.b64encode(byte_data) #转为BASE64
return base64_data #转码成功 返回base64编码
def base642base64(frame):
data=str('data:image/png;base64,')
base64data = str(frame2base64(frame))
framedata = base64data[2:(len(base64data)-1)]
base642base64_data = data + str(framedata)
return base642base64_data
def encode_image(filename):
ext = filename.split(".")[-1]
with open(filename, "rb") as f:
img = f.read()
data = base64.b64encode(img).decode()
src = "data:image/{ext};base64,{data}".format(ext=ext, data=data)
return src
Board().begin()
p_bme280 = BME280(0x76)
p_ccs811 = CCS811(0x5A)
p_ccs811.set_meas_cycle(CCS811_Ecycle.eCycle_250ms)
p_ccs811.write_base_line(17531)
siot.getsubscribe(topic="siot/control")
video_thread=u_gui.start_thread(u_video_thread_function)
sensor_thread=u_gui.start_thread(u_sensor_thread_function)
2、连接行空板,上传程序

3.7 web端控制程序

附件
附件
评论