IIC与编码电机通讯

i2cdetect -y -r -a 1查找设备地址;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import smbus#需要安装的库文件
import time

I2C_ADDR = 0x34 # I2C设备地址
ADC_BAT_ADDR = 0 # 电压地址
MOTOR_TYPE_ADDR = 20 # 编码电机类型设置
MOTOR_ENCODER_POLARITY_ADDR = 21 # 设置编码方向极性
MOTOR_FIXED_PWM_ADDR = 31 # 固定PWM控制
MOTOR_FIXED_SPEED_ADDR = 51 # 固定转速控制
MOTOR_ENCODER_TOTAL_ADDR = 60 # 4个编码电机各自的总脉冲值

MOTOR_TYPE_WITHOUT_ENCODER = 0
MOTOR_TYPE_TT = 1 #TT 编码电机
MOTOR_TYPE_N20 = 2 #N20 编码电机
MOTOR_TYPE_JGB37_520_12V_110RPM = 3 #磁环每转是 44 个脉冲 减速比:90默认
# 初始化I2C总线
bus = smbus.SMBus(1)

#写入字节
def wire_write_byte(val):
try:
bus.write_byte(I2C_ADDR, val)
return True
except IOError:
return False

#将数据组写入到指定寄存器的i2c设备
def wire_write_data_array(reg, val):
try:
bus.write_i2c_block_data(I2C_ADDR, reg, val)
return True
except IOError:
return False


#从指定寄存器读取一个字节的数据
def wire_read_data_byte(reg):
try:
val = bus.read_byte_data(I2C_ADDR, reg)
return val
except IOError:
return None


# 从指定寄存器开始读取指定长度的数据数组。
def wire_read_data_array(reg, length):
try:
data = bus.read_i2c_block_data(I2C_ADDR, reg, length)
return data
except IOError:
return None

def main():
# 初始化
bus.open(1)
wire_write_data_array(MOTOR_TYPE_ADDR, [MOTOR_TYPE_TT]) # 设置电机类型
wire_write_data_array(MOTOR_ENCODER_POLARITY_ADDR, [1]) # 设置编码器极性

# 控制电机
# 速度
p1 = [50, 50, 50, 50]
p2 = [-50, -50, -50, -50]
s1 = [2, 2, 2, 2]
s2 = [-2, -2, -2, -2]

wire_write_data_array(MOTOR_FIXED_SPEED_ADDR, p1) # 设置电机前进速度
# wire_write_data_array(MOTOR_FIXED_PWM_ADDR, p1) # 可以选择使用PWM控制电机
wire_write_data_array(MOTOR_FIXED_SPEED_ADDR, s1) # 设置电机后退速度

print("电机控制中...")
time.sleep(0.7)

wire_write_data_array(MOTOR_FIXED_SPEED_ADDR, p2)
wire_write_data_array(MOTOR_FIXED_SPEED_ADDR, s2)

print("电机控制完成")

# 读取电压
voltage_data = wire_read_data_array(ADC_BAT_ADDR, 2)
voltage = voltage_data[0] + (voltage_data[1] << 8)
print("电压:", voltage, "mV")

# 读取电机累积转动量
encode_total_data = wire_read_data_array(MOTOR_ENCODER_TOTAL_ADDR, 16)
encode_total = [
int.from_bytes(encode_total_data[i:i+4], byteorder='little')
for i in range(0, len(encode_total_data), 4)
]
print("电机累积转动量:", encode_total)

if __name__ == "__main__":
main()

手柄操控:

查询手柄映射关系:

1:使用Pygame的pygame.joystick.Joystick对象的get_button方法来动态检查按钮是否按下,并查找其按钮编号。以下是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import pygame

# 初始化pygame
pygame.init()

# 设置手柄
joystick = pygame.joystick.Joystick(0)
joystick.init()

# 主循环
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

# 获取按钮状态
button_0_state = joystick.get_button(0)
button_1_state = joystick.get_button(1)

# 检查按钮状态并执行操作
if button_0_state == 1:
print("Button 0 is pressed")
# 执行相应操作

if button_1_state == 1:
print("Button 1 is pressed")
# 执行相应操作

# 清理
pygame.quit()

在这个示例中,joystick.get_button(0) 返回按钮0的状态,1表示按下,0表示未按下。你可以类似地检查其他按钮的状态。

2:使用测试工具进行测试:你可以使用jstest命令行工具来测试手柄并获取按钮的编号。首先,确保手柄已连接到Jetson设备。然后,打开终端并执行以下命令

1
2
sudo apt-get install joystick
jstest /dev/input/js0#手柄连接后会在文件夹中生成js0文件若有多个手柄则会生成多个js文件

这将启动手柄测试工具,并在终端中显示按钮和轴的状态。按下按钮时,你将看到相关的按钮编号。这可以帮助你确定哪个按钮对应哪个编号。

一旦你确定了按钮的编号,你可以在你的Pygame代码中使用相应的编号来处理按钮按下事件。