回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

行空板M10扩展板智能小车“进化论” 简单

头像 豆爸 2025.06.16 89 0

近期,DFRobot 发布行空板 M10 扩展板组合 —— 行空板 M10 电机 IO 扩展板与 M10 电池扩展板。该组合专为行空板(UNIHIKER)M10 在机器人控制、物联网终端、移动创客项目开发中面临的移动供电难题、接口数量不足、动态控制复杂等场景痛点,提供了便携式开发解决方案。​

1 硬件简介​

1.1 电池扩展板

行空板M10电池扩展板功能图.png

行空板 M10 电池扩展板采用 9mm 超薄设计,搭载 800mAh 锂电池,结合隐藏式弹针连接方式,与 M10 组合后整机厚度仅增加 6.6mm ,4 颗 LED 电量指示灯,充电电路及充电指示功能。

1.2 电机 IO 扩展板

行空板M10电机IO扩展板功能图.png

行空板 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螺丝固定在电池扩展板上。​

微信图片_202506180940111111.png

将N20减速电机固定在小车底盘,将小车底盘用M3螺丝固定在IO扩展板上,再将电机电源线插到电机 IO 扩展板的 M1 和 M2 接口。

将舵机链接到P0接口。

步骤2 用户库编写

blocks.png

步骤3 用户库导入

在 Mind+ Python模式下,导入项目所需的用户库。

用户库加载地址:https://gitee.com/hmilycheng/ext-Unihiker_IOExtension

1749897237802.png

步骤4 程序编写

完成下图所示程序编写。

example.png

步骤5 程序运行

1750084463823.png

代码
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 系统架构

 

Snipaste_2025-07-06_16-32-38.png

 

3.4 功能实现

 

环境监测:实时显示温度、湿度、海拔、气压、CO2、TVOC

视频监控:Base64格式传输实时视频

运动控制:前进/后退/左转/右转/停止

灯光控制:远程开关LED灯

 

3.5 添加用户库

 

添加“官方库”——行空板M10、OpenCV、MQTT-py

1751784622044.png

 

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

 

1751784683472.png

 

 

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。

义教信息科技 基于行空板K10的博物馆环境监测物联系统图8

注意:启动时需要将SIoT添加到允许应用通过防火墙,勾选专用网络和公用网络,否则外部设备可能无法访问

义教信息科技 基于行空板K10的博物馆环境监测物联系统图1
启动之后会弹出小黑窗启动服务器。

image.png
在浏览器输入 上图中地址192.168.123.29:8080 即可打开网页,输入账号siot,密码dfrobot,点击“登录”。

义教信息科技 基于行空板K10的博物馆环境监测物联系统图10

登录成功后,即可单击“新建主题(Topic)”创建主题。

义教信息科技 基于行空板K10的博物馆环境监测物联系统图2

新建主题如下:

ED90EFBC-F76C-46c8-BC52-B9A09649EFA0.png

 

3.6 流程图

 

deepseek_mermaid_20250706_4e5de8.png

 

3.7 程序编写

 

1、编写程序

 

screenshots-使用摄像头.mp-1751785852624.png

 

代码
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、连接行空板,上传程序

 

image.png

 

3.7 web端控制程序

 

web.png

附件

评论

user-avatar