- 未特殊说明,一切树莓派操作皆在
小黑框(终端)
中进行STM32单片机的操作皆在创建的 Keil 项目中进行 - 项目创建方法:Keil创建STM32项目并烧录使用
- 关于初始化函数的位置
通过树莓派接收图片信息并测量标志距离,根据所得距离信息与预设
危险距离
对比,启动串口,根据是否在危险距离以内
发送停止
或启动
信息到单片机,单片机根据接收的启停信号来重新开始运动或停止运动,运动过程中机器狗的步伐完全由单片机控制
详见 树莓派初始化文档 和 Keil创建STM32项目并烧录使用
具体步骤如下
- 定时拍摄
- 自启动测距
# 代码 1
# 创建定时使用的脚本
nano XXX.sh # XXX 是脚本名,`.sh` 是脚本文件的后缀
# sudo nano XXX.sh # 上一行命令失败使用这个
# 代码 2
# 脚本添加内容 - 直接复制粘贴到上一步命令成功后所在的界面即可
# 功能:循环拍摄,循环次数为 1min/(拍摄延时 + 1 到 0.5 秒)
# 循环次数数值可以大,定时任务会自动打断上一轮未完成的定时任务
# ----------- 只添加这条线以下的内容 ------------------
#! /bin/bash
for i in $(seq 1 30) # 控制循环次数用
do
libcamera-jpeg -o tmp.jpg -t 1000
done
/你的路径/XXX.sh # 最好写从根目录到该文件的绝对路径,不容易出错
# 代码 4
# 创建测距的 python 文件
nano XXX.py # XXX 是脚本名,`.py` 是 python 文件的后缀
# sudo nano XXX.py # 上一行命令失败使用这个
参考资料如下
- 开机启动使用
- 自启动服务应在
/etc/systemd/system/
文件夹下,但为了方便,服务文件在被自启动的文件所在文件夹也有一份备份,请在该备份中更改,并在更改后将其复制到应在的文件夹,如sudo cp distance_measurement.service /etc/systemd/system/distance_measurement.service
- 自启动服务应在
- 定时使用脚本
- 最低使用间隔:1min -> 可通过循环命令和
sleep
命令解决 - cron 服务启、停、状态查看
- 注意:
- 调用的脚本中一定要使用绝对路径,或在内部自行定义路径,一定不要直接使用全局的环境变量,否则既不会报错,也不会正常运行
- cron 命令调用生成的内容有时候会自带写保护,影响不大
- 最低使用间隔:1min -> 可通过循环命令和
- 摄像头使用
- 特定图形(颜色块)测距
具体实现
- 初始化开启串口
- 使用 python 代码控制串口发送
- python 环境配置并激活虚拟环境
- 创建
.py
文件并在文件中添加如下代码(详情查看下方代码 4.1.1
、代码 4.1.2
) - 运行刚才的文件(详情查看下方
代码 4.1.3
) - 接收查看:树莓派与电脑正确连接后打开任意串口助手软件开启串口后皆可看见结果
# 代码 4.1.1
# 创建名为 python 文件;xxx 是文件名,可更改;`.py` 不允许更改
nano xxx.py
# 有些文件夹创建文件会要求根权限,则这么写,当然,最好不要在这种文件夹下操作
# sudo nano xxx.py
# 运行后会自动进入创建的文件
# 代码 4.1.2
# 以下代码添加到刚刚创建的文件(创建后会自动进入)
import serial # 添加串口包
ser = serial.Serial("/dev/ttyAMA0", 115200) # 设置串口端口和波特率,前者自行查看,一般用本部分的串口初始化者和我的是一样的
ser.flushInput() # 清除缓存
ser.write("Hello World\r\n".encode()) # 发送数据 \r\n可以实现换行 encode()默认是'utf-8'
# ctrl + o,回车:保存
# ctrl + x:退出该文件
# 代码 4.1.3
# 运行刚刚的文件
python3 xxx.py # python3 文件名
参考资料
使用步骤
- 正确接线
- 开启对应配置并检查文件完整性
- 找到 stm32f4xx_hal_conf.h 中对应定义的定义并解除注释
- 查看 驱动文件夹 下是否存在
串口驱动文件 stm32f4xx_hal_uart.c
和 stm32f4xx_hal_uart.h
- 如果没有,请自行在 官网 下载整个 HAL 库,并分别复制这两个文件到正确的文件夹下
- 找到 stm32f4xx_hal_conf.h 中对应定义的定义并解除注释
- 串口初始化(详见 myUart.c 注释)
- 两个函数解决串口常规使用问题
- 串口发送函数:
HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
UART_HandleTypeDef *huart
:已经初始化的串口结构体const uint8_t *pData
:将要发送的字符串uint16_t Size
:将要发送的字符串的大小uint32_t Timeout
:超时响应,超过设置的时间无论是否发送完成将会跳出串口发送
- 串口接收函数:
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
UART_HandleTypeDef *huart
:已经初始化的串口结构体const uint8_t *pData
:将要接收的字符所存放的指针uint16_t Size
:将要接收的字符的大小uint32_t Timeout
:超时响应,超过设置的时间无论是否接收完成将会跳出串口接收
- 串口发送函数:
- 另外:串口同样可以使用中断来控制,不过由于暂时无该需求,就未研究
参考资料
使用步骤
- 引脚输出的
PWM
信号控制 180 度舵机的输出角度
- 使用
高级定时器
根据当前应该输出的脚步状态
控制引脚输出PWM
信号 - 使用
基本定时器
根据时间
控制当前应该输出的脚步状态
- 舵机选择
- MG90S-180 度舵机
- 【淘宝】限时满70减3 https://m.tb.cn/h.gSzxWhPoudoI3sg?tk=Y7Tf3bsHA3S MF6563 「SG90 9G经典舵机 180/360度 数字舵机云台遥控飞机马达固定翼航模」 点击链接直接打开 或者 淘宝搜索直接打开
- 数据
- 初始配置
- 开启对应配置并检查文件完整性:同串口,不过开启的是
TIM
- 代码配置:详见 myYIM.c 的
高级定时器使用
部分的注释 - 关于死区:在生成的参考波形 OCxREF 的基础上,可以插入死区时间,用于生成两路互补的输出信号 OCx 和
OCxN,死区时间的大小必须根据与输出信号相连接的器件及其特性来调整。
- 关于通道与引脚对应:这次我们使用的是 TIM8,通道 1、2、3、4 分别对应引脚 PC6、PC7、PC8、PC9(也可自行调整,不过只有这几个在本开发板上引出针脚了,图中的
CHx 是各个通道)
- 开启对应配置并检查文件完整性:同串口,不过开启的是
- 使用
- 先在
main.c
使用自写的MX_TIM_Advance_Init
初始化 PWM - 后通过
__HAL_TIM_SetCompare(__HANDLE__, __CHANNEL__, __COMPARE__)
调节占空比__HANDLE__
:调节的定时器,这里填htim_advance
即可,已经设置好了extern
关键字__CHANNEL__
:通道号,调哪个通道写哪个即可,我的代码中使用LEF_SMALL_RIGHT
之类的是因为在main.h
里#define
了,方便代码和实际物件的对应__COMPARE__
:调整后的占空比数值,实际占空比为__COMPARE__/2^16
- 先在
- 初始配置
- 开启对应配置并检查文件完整性:同串口,开启的也是
TIM
- 开启对应配置并检查文件完整性:同串口,开启的也是
- 使用/撰写方法
- 控制脚步
- 通过前面提到过的
__HAL_TIM_SetCompare(__HANDLE__, __CHANNEL__, __COMPARE__)
控制输出的 PWM 占空比控制对应舵机的角度 - 将机器狗走动时的体态分解,使其成为一个个状态,每个状态中的各个舵机输出的 PWM 信号不同,这样,一个状态就能变成一个函数,一个调节各个舵机到正确 PWM 值的函数
- 创建
Robot_Control
函数,其核心是内部带有static
关键字的参数state
,代表各个状态,state
是多少就会调用多少号状态 - 定时器回调函数内调用
Robot_Control
函数,每次调用都会更新state
,又由于该参数是static
,每次调用Robot_Control
函数时不会清零,而是会在原先的state
值基础上进行更新
- 通过前面提到过的
参考资料