Skip to content

Commit 4bd264d

Browse files
committed
Merge branch 'develop-pandian' into develop
2 parents fcb4962 + f00e114 commit 4bd264d

File tree

10 files changed

+1509
-0
lines changed

10 files changed

+1509
-0
lines changed

m5stack/libs/module/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
_attrs = {
55
"DualKmeterModule": "dual_kmeter",
66
"Relay4Module": "relay_4",
7+
"Encoder4MotorModule": "encoder4_motor"
78
}
89

910
# Lazy loader, effectively does:

m5stack/libs/module/encoder4_motor.py

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
from .mbus import i2c1
2+
from .module_helper import ModuleError
3+
import struct
4+
import time
5+
6+
DEVADDR = 0x24
7+
8+
MTR_PWM_DUTY = 0x20
9+
MTR_ENCODER = 0x30
10+
MTR_SPEED = 0x40
11+
MTR1_MODE = 0x50
12+
MTR2_MODE = 0x60
13+
MTR3_MODE = 0x70
14+
MTR4_MODE = 0x80
15+
VIN_AMPS_FLT = 0x90
16+
VIN_ADC8 = 0xA0
17+
VIN_ADC12 = 0xB0
18+
VIN_AMPS_INT = 0xC0
19+
ENCODER_AB = 0xD0
20+
FIRM_VER = 0xFE
21+
I2C_ADDR = 0xFF
22+
23+
NORMAL_MODE = 0x00
24+
POSITION_MODE = 0x01
25+
SPEED_MODE = 0x02
26+
27+
class Encoder4MotorModule:
28+
def __init__(self, address: int = DEVADDR):
29+
'''
30+
init the i2c address
31+
address : 1 to 127
32+
'''
33+
self.mtr_i2c = i2c1
34+
self.i2c_addr = address
35+
if address >= 1 and address <= 127:
36+
self.i2c_addr = address
37+
self.available()
38+
self.mode = NORMAL_MODE
39+
40+
def available(self):
41+
check = False
42+
for i in range(3):
43+
if self.i2c_addr in self.mtr_i2c.scan():
44+
check = True
45+
break
46+
time.sleep(0.2)
47+
if not check:
48+
raise ModuleError("4Encoder motor module maybe not connect")
49+
50+
def set_motor_mode(self, pos, mode):
51+
'''
52+
pos: [ONE or TWO or THREE or FOUR]
53+
mode: [NORMAL_MODE or POSITION or SPEED]
54+
'''
55+
self.mode = mode
56+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR1_MODE+(0x10*pos), bytearray([mode]))
57+
58+
def set_all_motors_mode(self, mode):
59+
'''
60+
mode: [NORMAL_MODE or POSITION or SPEED]
61+
'''
62+
for i in range(0,3):
63+
self.set_motor_mode(i, mode)
64+
time.sleep_ms(150)
65+
66+
def set_motor_pwm_dutycycle(self, pos, duty):
67+
'''
68+
pos: [ONE or TWO or THREE or FOUR]
69+
duty: -127 ~ 127
70+
'''
71+
duty = min(max(duty, -128), 127)
72+
duty = struct.pack('>b', duty)
73+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR_PWM_DUTY+pos, duty)
74+
75+
def get_motor_encoder_value(self, pos):
76+
'''
77+
pos: [ONE or TWO or THREE or FOUR]
78+
'''
79+
buf = self.mtr_i2c.readfrom_mem(self.i2c_addr, MTR_ENCODER+(0x04*pos), 4)
80+
return struct.unpack('>i', buf)[0]
81+
82+
def set_motor_encoder_value(self, pos, value):
83+
'''
84+
pos: [ONE or TWO or THREE or FOUR]
85+
value: signed int 4byte
86+
'''
87+
value = struct.pack('>i', value)
88+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR_ENCODER+(0x04*pos), value)
89+
90+
def get_encoder_mode(self):
91+
'''
92+
return: 0[AB] or 1[BA] mode
93+
'''
94+
return self.mtr_i2c.readfrom_mem(self.i2c_addr, ENCODER_AB, 1)[0]
95+
96+
def set_encoder_mode(self, mode):
97+
'''
98+
mode: [AB or BA]
99+
'''
100+
self.mtr_i2c.writeto_mem(self.i2c_addr, ENCODER_AB, bytearray([mode]))
101+
time.sleep_ms(150)
102+
103+
def get_motor_speed_value(self, pos):
104+
'''
105+
pos: [ONE or TWO or THREE or FOUR]
106+
'''
107+
return self.mtr_i2c.readfrom_mem(self.i2c_addr, MTR_SPEED+pos, 1)[0]
108+
109+
def set_position_encoder_value(self, pos, value):
110+
'''
111+
pos: [ONE or TWO or THREE or FOUR]
112+
value: signed int 4byte
113+
'''
114+
value = struct.pack('<i', value)
115+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x04, value)
116+
117+
def set_position_max_speed_value(self, pos, value):
118+
'''
119+
pos: [ONE or TWO or THREE or FOUR]
120+
value: -127 ~ 127
121+
'''
122+
value = min(max(value, -128), 127)
123+
value = struct.pack('<b', value)
124+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x08, value)
125+
126+
def get_position_PID_value(self, pos):
127+
'''
128+
pos: [ONE or TWO or THREE or FOUR]
129+
'''
130+
return list(self.mtr_i2c.readfrom_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x01, 3))
131+
132+
def set_position_PID_value(self, pos, P, I, D):
133+
'''
134+
pos: [ONE or TWO or THREE or FOUR]
135+
P: 0 ~ 255
136+
I: 0 ~ 255
137+
D: 0 ~ 255
138+
'''
139+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x01, bytearray([P, I, D]))
140+
141+
def get_speed_PID_value(self, pos):
142+
'''
143+
pos: [ONE or TWO or THREE or FOUR]
144+
'''
145+
return list(self.mtr_i2c.readfrom_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x09, 3))
146+
147+
def set_speed_PID_value(self, pos, P, I, D):
148+
'''
149+
pos: [ONE or TWO or THREE or FOUR]
150+
P: 0 ~ 255
151+
I: 0 ~ 255
152+
D: 0 ~ 255
153+
'''
154+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x09, bytearray([P, I, D]))
155+
156+
def set_speed_point_value(self, pos, point):
157+
'''
158+
pos: [ONE or TWO or THREE or FOUR]
159+
point: -127 ~ 127
160+
'''
161+
point = min(max(point, -128), 127)
162+
point = struct.pack('<b', point)
163+
self.mtr_i2c.writeto_mem(self.i2c_addr, MTR1_MODE+(0x10*pos)+0x0c, point)
164+
165+
def get_vin_current_float_value(self):
166+
'''
167+
get input current value in float
168+
'''
169+
buf = self.mtr_i2c.readfrom_mem(self.i2c_addr, VIN_AMPS_FLT, 4)
170+
return round(struct.unpack('<f', buf)[0], 3)
171+
172+
def get_vin_current_int_value(self):
173+
'''
174+
get input current value in int
175+
'''
176+
buf = self.mtr_i2c.readfrom_mem(self.i2c_addr, VIN_AMPS_INT, 4)
177+
return (struct.unpack('<i', buf)[0]*10)
178+
179+
def get_vin_adc_raw8_value(self):
180+
'''
181+
get input volt adc 8bit raw value
182+
'''
183+
return self.mtr_i2c.readfrom_mem(self.i2c_addr, VIN_ADC8, 1)[0]
184+
185+
def get_vin_adc_raw12_value(self):
186+
'''
187+
get input volt adc 12bit raw value
188+
'''
189+
buf = self.mtr_i2c.readfrom_mem(self.i2c_addr, VIN_ADC12, 2)
190+
return struct.unpack('<h', buf)[0]
191+
192+
def get_vin_voltage(self):
193+
'''
194+
get input volt value
195+
'''
196+
value = self.get_vin_adc_raw12_value()
197+
return round(value/4095*3.3/(20/120), 2) # 20k/(20k+100k)
198+
199+
def get_device_spec(self, info):
200+
'''
201+
get device firmware version and i2c address
202+
info: [0xFE or 0xFF]
203+
'''
204+
return self.mtr_i2c.readfrom_mem(self.i2c_addr, info, 1)[0]
205+
206+
def set_i2c_address(self, addr):
207+
'''
208+
set i2c address
209+
addr: 1~127
210+
'''
211+
addr = min(max(addr, 1), 127)
212+
if addr != self.i2c_addr:
213+
self.mtr_i2c.writeto_mem(self.i2c_addr, I2C_ADDR, bytearray([addr]))
214+
self.i2c_addr = addr
215+
time.sleep_ms(150)
216+

m5stack/libs/module/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"mbus.py",
77
"relay_4.py",
88
"module_helper.py",
9+
"encoder4_motor.py",
910
),
1011
base_path="..",
1112
opt=0,

m5stack/libs/unit/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
"DAC2Unit": "dac2",
4444
"GESTUREUnit": "gesture",
4545
"THERMALUnit": "thermal",
46+
"SYNTHUnit": "synth",
47+
"SERVOS8Unit": "servos8",
48+
"RTC8563Unit": "rtc8563",
49+
"VMeterUnit": "vmeter",
50+
"AMeterUnit": "ameter",
4651
}
4752

4853

0 commit comments

Comments
 (0)