https://mc.dfrobot.com.cn/thread-2660-1-1.html
Firmata是一个PC与MCU通讯的一个常用协议。我们可以直接在咱们的Arduino Expansion Shield for Raspberry Pi扩展板上下载一个StandardFirmata代码,然后通过在树莓派上编写串口软件可以直接访问并控制扩展板上Arduino的GPIO、PWM、ADC等资源。
arduino端下载
树莓派上Firmata的安装与测试
在这里我们使用pyfirmata进行测试,首先安装pyfirmata模块,然后进入python交互界面导入模块看看是否报错,如果报错说明没有安装好
root@raspberrypi:/home/pi# pip3 install pyfirmata
然后看看你的Raspberry Pi Meet Arduino 扩展板 USB串口是什么号码,当前的USB串口是 ttyACM1
root@raspberrypi:/home/pi# ls -l /dev/tty*
crw------- 1 root root 4, 8 Jan 1 1970 /dev/tty8
crw------- 1 root root 4, 9 Jan 1 1970 /dev/tty9
crw-rw---T 1 root dialout 166, 1 Jun 22 12:56 /dev/ttyACM1
crw-rw---- 1 root tty 204, 64 Jun 22 12:17 /dev/ttyAMA0
crw-rw---T 1 root dialout 5, 3 Jan 1 1970 /dev/ttyprintk
进入python命令界面 输入命令测试下通信是否正确 ,这里的串口是ttyACM1
下面测试了使板上D13口的LED闪烁,然后又测试了模拟口上LM35温度传感器输入的电压,0.0567是电压值
root@raspberrypi:/home/pi# python
<pre>>>>from pyfirmata import Arduino, util
>>> board = Arduino('/dev/ttyACM1')
>>> board.digital[13].write(1)
>>> board.digital[13].write(0)
>>> it = util.Iterator(board)
>>> it.start()
>>> board.analog[0].enable_reporting()
>>> board.analog[0].read()
0.0567
至此说明Firmata运行起来了,你可以看看相关《Firmata详解》 和 pyFirmata 的操作格式,即可通过串口连接Raspberry Pi Meet Arduino 扩展板,从而使树莓派增加多个GPIO、PWM、ADC等功能。
在测试中我发现速度并没有简单协议快,我觉得如果是固定功能,制定一个小巧的私有协议是更方便快捷的,可以看看咱们前面测试的 ADC采集通信例子
游戏手柄遥控小车程序
import pygame
import time
from pyfirmata import Arduino, PWM
# 连接到Arduino
board = Arduino('/dev/ttyACM0') # 根据实际情况修改串口地址
# 设置5号引脚为PWM输出
motor1_forward = board.get_pin(f'p:{5}:p')
motor1_reverse = board.get_pin(f'p:{6}:p')
motor2_forward = board.get_pin(f'p:{9}:p')
motor2_reverse = board.get_pin(f'p:{10}:p')
# 初始化pygame
pygame.init()
# 初始化手柄
controller = pygame.joystick.Joystick(0)
controller.init()
def control_motors(x_axis, y_axis):
motor1_speed = y_axis + x_axis
motor2_speed = y_axis - x_axis
# Ensure motor speeds are within the valid range of -1 to 1
motor1_speed = max(-1, min(1, motor1_speed))
motor2_speed = max(-1, min(1, motor2_speed))
# Control motor directions based on speed values
if motor1_speed >= 0:
motor1_forward.write(motor1_speed)
motor1_reverse.write(0)
else:
motor1_forward.write(0)
motor1_reverse.write(-motor1_speed)
if motor2_speed >= 0:
motor2_forward.write(motor2_speed)
motor2_reverse.write(0)
else:
motor2_forward.write(0)
motor2_reverse.write(-motor2_speed)
# 主循环
while True:
# 从事件队列中获取事件
for event in pygame.event.get():
if event.type == pygame.JOYAXISMOTION:
# 获取左摇杆的X和Y轴值
left_stick_x = controller.get_axis(0)
left_stick_y = controller.get_axis(1)
# 获取右摇杆的X和Y轴值
right_stick_x = controller.get_axis(3)
right_stick_y = controller.get_axis(4)
# 打印摇杆数值
print("Left Stick X: {:.2f}, Left Stick Y: {:.2f}".format(left_stick_x, left_stick_y))
print("Right Stick X: {:.2f}, Right Stick Y: {:.2f}".format(right_stick_x, right_stick_y))
control_motors(left_stick_x, left_stick_y)
time.sleep(0.01)