上一节我们说到了机械臂的关节与关节舵机驱动程序的基本原理;这一节我们将使用STM32单片机来实现机械臂运动的编程。
0. 本节基本内容
本节主要介绍了如何利用单片机蓝牙-串口中断控制6路舵机转角;具体涉及的技术点为:
- 配置STM32单片机的Timer3与Timer8比较输出
- 配置STM32的串口中断,基于中断传输帧格视的数据
- 配置HC-05蓝牙,并与笔记本上的蓝牙调试器进行配对
- 使用笔记本电脑通过蓝牙控制机械臂执行一些固定动作
本节的操作需要准备以下硬件:
- 一台机械臂
- 一个机械臂的驱动小半
- 蓝牙HC-05模块
- 串口转USB小板(建议用CH340)
- 一台带有蓝牙功能的笔记本电脑(或者外接一个蓝牙)
(本教程中涉及到的这些小工具和硬件,可以通过文末的联系方式 联系我来要链接)
1. 写单片机程序的准备工作
首先在我的舵机主控板上,舵机对应的单片机IO口如下:
也就是说,前四个舵机对应着Timer3的四个通道,后四个舵机对应着Timer8的四个通道。
为了使我们的电脑与单片机进行通信,我们还需要用到串口;在这里我们使用单片机的串口4(UART4),电路连接如图所示,其中TX对应PC10引脚,RX对应PC11引脚:
我们现在配置单片机的工程,具体的配置方法可以参考我之前的教程,或者点击这个链接下载现成的工程文件。
在这个工程中,我们需要完成两个重要的驱动文件,第一个是舵机的驱动(servo.c),第二个是串口的驱动(usart.c)
2. 舵机驱动
舵机驱动在上一章讲过,这次我们来细化一下
首先,既然利用了Timer3与Timer8,我们首先就把这两个Timer的初始化过程封装成一个函数:
void Servo_Init(void)
{
// 初始化PWM定时器
TIM3_Init(); // 在这个函数里添加上一章初始化Timer3的代码
TIM8_Init(); //在这个函数里添加上一章初始化Timer8的代码
}
然后,我们再来封装一个驱动机械臂各个舵机的函数,名字就起为void Set_Servo_PWM(uint8_t channel, uint16_t pwm),其中channel表时要控制第几个舵机,pwm表示要对这路舵机输出的占空比:
void Set_Servo_PWM(uint8_t channel, uint16_t pwm)
{
TIM_TypeDef *tim;
if(channel > 8)
{
return;
}
if(pwm > 2500)
{
return;
}
else if(pwm < 500)
{
return;
}
if(channel > 4)
{
tim = TIM8;
channel -= 4;
}
else
{
tim = TIM3;
}
switch(channel)
{
case 1: tim->CCR1 = pwm; break;
case 2: tim->CCR2 = pwm; break;
case 3: tim->CCR3 = pwm; break;
case 4: tim->CCR4 = pwm; break;
default:
break;
}
}
接下来,我们在main函数中添加一系列固定的动作状态,看看舵机能不能按照我们预定义的动作来运动:
while(1)
{
for(i=4;i>0;i--)
{
Set_Servo_PWM(i,1500);
delay_ms(200);
}
USART_SendData(UART4,'a'); //Debug
for(i=4;i>0;i--)
{
Set_Servo_PWM(i,1300);
delay_ms(200);
}
USART_SendData(UART4,'b'); //Debug
}
执行完这些操作后,通电,我们就能够看到一个妖娆且抖动的机械臂
3. 使用蓝牙-串口将机械臂无线连接到电脑
3.1 配置蓝牙芯片
我们使用HC-05的蓝牙芯片来进行与电脑之间的通讯,蓝牙芯片共有VCC,GND,RX,TX四个引脚,其中RX和TX应当分别连接单片机串口的TX和RX:
蓝牙RX----单片机TX 蓝牙TX----单片机RX
在使用之前,我们首先对蓝牙进行一些基本的配置,具体操作为把蓝牙芯片通过USB-TTL串口转接小班连接到电脑。 同时我这里有个HC-05的一键配置软件,通过这个软件对蓝牙进行基本的配置(比如配置蓝牙名称,波特率等等),详细的配置方法请参考:外部链接
3.2 配置单片机和电脑端
蓝牙配置好后便相当于透传模块(可以理解为此时蓝牙就是一台无线的USB-TTL转接小板);我们打开电脑(以Win10为例),可以在电脑端看到蓝牙芯片的名字;连接这个蓝牙后,在蓝牙选项里查看设备对应的COM口,这个COM就是电脑与机械臂的通讯端口。
4. 基于串口数据协议实现舵机控制协议的传输
关于串口通讯的基本理论可看我以前的教程。
因为舵机的控制还是相对简单的,所以我们封装的数据也可以简单一些;我们统一一个数据包的长度为8个字节;其中两个字节为包头部,都用0xff来标识;而后六个字节就是机械臂每个关节所处的角度,127代表正中心,0和255分别代表极限值。当然这种方法控制的精度不是很高,但是对于一个脑电/肌电驱动的机械臂,已经是很够用了。
上位机下发的数据如下:
地址偏移 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
字节内容 | 0xff(固定值) | 0xff(固定值) | 第一个舵机角度 | 。。。 | 。。。 | 。。。 | 。。。 | 第六个舵机角度 |
所以,我们来在单片机的串口中断里每读取8个字节后进行一次处理,即可实现对机械臂控制相关的通讯。
void UART4_IRQHandler()
{
static uint8_t temp[8];
static uint8_t addr = 0;
if(USART_GetITStatus(UART4, USART_IT_RXNE)!=RESET)
{
temp[addr]=USART_ReceiveData(UART4);
addr++;
if(addr>=8)
{
/*开始进行一个数据包的处理*/
if((temp[0]==0xff)&&(temp[1]==0xff))
{
Set_Servo_PWM(1,temp[2]*7+611); //按比例调整舵机参数(127对应1500,0对应611,255对应2396)
Set_Servo_PWM(2,temp[3]*7+611);
Set_Servo_PWM(3,temp[4]*7+611);
Set_Servo_PWM(4,temp[5]*7+611);
Set_Servo_PWM(5,(255-temp[6])*7+611); //因为我的5号舵机装反了,所以修改一下方向
Set_Servo_PWM(6,temp[7]*7+611);
USART_SendData(UART4,VV); //VV是一个自定义的反馈数据
}
else
{
USART_SendData(UART4,0xff);
}
addr=0; //等待接收下一个数据包
}
}
}
5. 写一个简单的上位机实现电脑控制机械臂运动
接下来我们可以按照制定的协议来控制机械臂的运动,用一个Python脚本即可,脚本的核心是一个Python的类,使用这个类可以向机械臂发送其运动相关指令。
import serial
import numpy as np
import threading
import time
class Serial_Arm:
def __init__(self,port='COM9'):
self.ser=serial.Serial(port,115200,timeout=3.0)
self.vals=np.ones(8,dtype=np.uint8)*127
self.vals[0] = 255
self.vals[1] = 255
self.volt=1.0
def Set_Arm_Values(self,dat):
if(len(dat))!=6:
print('机械臂关节数量输入错误!')
return
vals=[]
for i in dat:
val = int(i * 127 / np.pi + 127)
if val < 0: val = 0
if val > 255: val = 255
vals.append(val)
self.vals[2:8]=vals
pPush=bytes(self.vals)
self.ser.write(pPush)
self.volt=ord(self.ser.read(1))
def Set_Arm_Joint(self,joint,val):
val=int(val*127/np.pi+127)
if val<0:val=0
if val>255:val=255
self.vals[joint+2]=val
print(self.vals)
pPush = bytes(list(self.vals))
print(pPush)
self.ser.write(pPush)
self.volt = ord(self.ser.read(1))
print(self.volt)
if __name__=='__main__':
s=Serial_Arm()
然后使用Pygame配合键盘,机械臂就动起来了~
下面是一个我让机械臂按电脑播放音频节奏抖动的小视频~
https://www.bilibili.com/video/BV1VT4y1d7cG?t=0.0
本章小结
本小节主要介绍了机械臂控制的相关原理性代码,上位机-下位机通讯方案,基于本小节的内容,底层的硬件相关内容已经基本可以完成;下一节我们将开始人体肌肉电/脑电的采集和分析介绍,以及脑控机械臂仿真环境的搭建。
评论(0)
您还未登录,请登录后发表或查看评论