现在喜欢用树莓派5进行开发,有硬件接口,调试程序很方便。
MA730 与树莓派 5 硬件连接图
首先,根据手册第 2 页的俯视图(TOP VIEW),引脚定义如下:
引脚号 名称 功能描述
1 SSD SSI 数据输出 (我们不用)
2 A ABZ 增量编码器输出 A (我们不用)
3 Z ABZ 增量编码器输出 Z (我们不用)
4 MOSI SPI 数据输入
5 CS SPI 片选
6 B ABZ 增量编码器输出 B (我们不用)
7 MISO SPI 数据输出
8 GND 电源地
9 PWM PWM 输出 (我们不用)
10 TEST 工厂测试用,必须接地
11 MGL 磁场过低指示 (我们不用)
12 SCLK SPI 时钟
13 VDD 3.3V 电源
14 NC 不连接
15 SSCK SSI 时钟 (不用)
16 MGH 磁场过高指示 (不用)
连接示意图
请按照下表将 MA730 的引脚与树莓派 5 的 GPIO 引脚一一对应连接。
MA730 引脚 树莓派 5 GPIO 引脚 树莓派 5 物理引脚号 说明
13 (VDD) 3.3V DC Power Pin 1 3.3V 电源
8 (GND) Ground Pin 6 电源地
12 (SCLK) GPIO 11 (SPI0_SCLK) Pin 23 SPI 时钟
4 (MOSI) GPIO 10 (SPI0_MOSI) Pin 19 主出从入
7 (MISO) GPIO 9 (SPI0_MISO) Pin 21 主入从出
5 (CS) GPIO 8 (SPI0_CE0_N) Pin 24 SPI 片选 0
10 (TEST) Ground Pin 6 必须接地
提醒:
TEST 引脚 (Pin 10):根据MA730手册第 8 页的引脚功能描述,此引脚仅供工厂测试使用,必须连接到 GND。如果悬空,传感器可能无法正常工作。
共地:确保树莓派的 GND 和 MA730 的 GND 可靠连接,这是所有通信的基础。
MA730 通信协议关键点
查看手册磁铁采用径向磁铁,同轴方式安装
由于磁铁尺寸太小,为了便于测试操作,将磁铁嵌入到一块橡皮中。
SPI 模式:Mode 1 (CPOL=0, CPHA=1) 或 Mode 3 (CPOL=1, CPHA=1)。MA730 通常在 SCK 空闲为低,第二个边沿采样数据,即 Mode 1 最为常见。如果读取数据异常,请尝试切换 Mode 3。
数据格式:
MA730 输出 16 位数据。
最高位 (Bit 15) 是状态位 (Status Bit),0 表示数据有效,1 表示错误。
接下来 14 位 (Bit 14-1) 是角度数据 (14-bit resolution)。
最低位 (Bit 0) 通常未使用或为奇偶校验位(取决于配置,默认通常忽略)。
角度计算:Angle = (Raw_Data & 0x7FFF) * 360.0 / 16384.0
import spidev
import time
# 初始化 SPI
spi = spidev.SpiDev()
spi.open(0, 0) # 打开 SPI 总线 0,设备 0 (CE0)
spi.max_speed_hz = 1000000 # 设置 SPI 时钟频率为 1MHz
spi.mode = 0b11 # 【关键修改】根据手册,MA730 使用 SPI Mode 3
def read_ma730_angle():
# 【关键修改】读取角度不需要发送命令字,只需发送占位字节来产生时钟
# 传感器会在 CS 拉低时自动输出 16 位角度数据
resp = spi.xfer2([0x00, 0x00])
# 将接收到的两个字节合并为一个 16 位整数
raw_data = (resp[0] << 8) | resp[1]
# 【关键修改】根据手册,角度数据是 14 位,位于高 14 位
# 因此需要将数据右移 2 位
angle_14bit = raw_data >> 2
# 将 14 位原始数据转换为实际角度 (0 - 360度)
# 14位分辨率对应 2^14 = 16384 个刻度
angle_degrees = (angle_14bit / 16384.0) * 360.0
return angle_degrees
try:
print("开始读取 MA730 角度数据...")
while True:
angle = read_ma730_angle()
print(f"Current Angle: {angle:.2f}°")
time.sleep(0.1) # 100ms 读取一次
except KeyboardInterrupt:
print("\n程序已退出")
finally:
spi.close()
运行结果如下
为了便于观察,程序改进一下加个滑动条,可以直观观察角度变化情况。
代码如下:
import spidev
import time
import tkinter as tk
from tkinter import ttk
# SPI配置
SPI_BUS = 0
SPI_DEV = 0
SPI_SPEED = 125000
spi = spidev.SpiDev()
spi.open(SPI_BUS, SPI_DEV)
spi.mode = 3
spi.max_speed_hz = SPI_SPEED
def read_ma730():
resp = spi.xfer2([0x00, 0x00])
time.sleep(0.0015)
raw_word = (resp[0] << 8) | resp[1]
angle_raw = (raw_word >> 2) & 0x3FFF
trk_bit = (raw_word >> 1) & 0x01
angle_deg = angle_raw * 360.0 / 16384.0
return angle_raw, angle_deg, trk_bit
# GUI窗口更新函数
def update_ui():
raw_val, deg, trk = read_ma730()
# 更新进度条 0~360映射0~100
progress_val = deg / 360 * 100
bar_var.set(progress_val)
# 更新文字显示
text_label.config(text=f"原始值: {raw_val:5d} | 角度: {deg:.2f}° | TRK锁定: {trk}")
root.after(50, update_ui) # 50ms刷新一次
# 创建GUI窗口
root = tk.Tk()
root.title("MA730 角度滑动条")
root.geometry("600x120")
# 进度条变量
bar_var = tk.DoubleVar()
progress_bar = ttk.Progressbar(root, variable=bar_var, maximum=100, length=520)
progress_bar.pack(pady=20)
# 文字标签
text_label = tk.Label(root, font=("Arial", 12))
text_label.pack()
# 循环刷新
update_ui()
root.mainloop()
# 窗口关闭后释放SPI
spi.close()
运行结果如下:
最后测试和舵机联动
采用SG90舵机
信号线 → BCM18;舵机电源接5V,GND必须和树莓GND连在一起
测试代码如下:
import spidev
import time
import tkinter as tk
from tkinter import ttk
from gpiozero import Servo
# ===================== 配置区 =====================
# SPI MA730参数
SPI_BUS = 0
SPI_DEV = 0
SPI_SPEED = 125000
# 舵机配置 BCM18
SERVO_PIN = 18
# SG90舵机标准脉宽
MIN_PULSE = 0.0005 # 500us 0°
MAX_PULSE = 0.0025 # 2500us 180°
# ==================================================
# 初始化SPI
spi = spidev.SpiDev()
spi.open(SPI_BUS, SPI_DEV)
spi.mode = 3
spi.max_speed_hz = SPI_SPEED
# 初始化舵机
servo = Servo(SERVO_PIN, min_pulse_width=MIN_PULSE, max_pulse_width=MAX_PULSE)
# 读取MA730原始角度
def read_ma730():
resp = spi.xfer2([0x00, 0x00])
time.sleep(0.0015) # 时序间隔防失锁
raw_word = (resp[0] << 8) | resp[1]
angle_raw = (raw_word >> 2) & 0x3FFF
trk_bit = (raw_word >> 1) & 0x01
angle_deg = angle_raw * 360.0 / 16384.0
return angle_raw, angle_deg, trk_bit
# 传感器0~360° → 舵机 -1 ~ 1(gpiozero标准值域)
def angle_to_servo_val(sensor_deg):
# 360°映射舵机0~180°
servo_deg = sensor_deg / 2
# 0°→-1,180°→1
val = (servo_deg / 90) - 1
# 限制边界防止超行程
return max(-1, min(1, val))
# GUI刷新循环
def update_ui():
raw_val, deg, trk = read_ma730()
# 更新进度条
bar_var.set(deg / 360 * 100)
text_label.config(text=f"原始值:{raw_val:5d} | 传感器角度:{deg:.2f}° | TRK锁定:{trk}")
# 驱动舵机
servo.value = angle_to_servo_val(deg)
root.after(50, update_ui)
# 创建GUI窗口
root = tk.Tk()
root.title("MA730 角度条 + 舵机跟随 Pi5兼容")
root.geometry("620x130")
bar_var = tk.DoubleVar()
progress_bar = ttk.Progressbar(root, variable=bar_var, maximum=100, length=540)
progress_bar.pack(pady=20)
text_label = tk.Label(root, font=("Arial", 12))
text_label.pack()
# 关闭窗口释放资源
def close_all():
servo.detach()
spi.close()
root.destroy()
root.protocol("WM_DELETE_WINDOW", close_all)
update_ui()
root.mainloop()
结果见视频,舵机的摇臂随着磁铁的旋转改变角度,初步达到预期目的。
存在问题,采集的角度数据有跳变,须要进行平滑处理。
下步计划,将角度传感器安装到模型摇杆上,进行完整测试。






