smartpi 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
smartpi/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from smartpi import module
2
+
3
+ __version__ = "0.1.0"
4
+
smartpi/app_module.py ADDED
@@ -0,0 +1,119 @@
1
+ # coding=utf-8
2
+ import time
3
+ from typing import List, Optional
4
+ from smartpi.module import Uart3_funtions,base_driver
5
+
6
+
7
+ class app_funtion:
8
+ #马达编码读取 port:连接M端口;
9
+ def read_motor_code(port:bytes) -> Optional[bytes]:
10
+ motor_str=[0xA0, 0x01, 0x01, 0xBE]
11
+ motor_str[0]=0XA0+port
12
+ response = Uart3_funtions.single_operate_sensor(motor_str)
13
+ if response:
14
+ return 0
15
+ else:
16
+ return -1
17
+
18
+ #马达速度控制 port:连接M端口;speed:0~100
19
+ def write_motor_speed(port:bytes,speed:bytes) -> Optional[bytes]:
20
+ motor_str=[0xA0, 0x01, 0x02, 0x71, 0x00, 0xBE]
21
+ motor_str[0]=0XA0+port
22
+ motor_str[4]=speed
23
+ response = Uart3_funtions.single_operate_sensor(motor_str)
24
+ if response:
25
+ return 0
26
+ else:
27
+ return -1
28
+
29
+ #马达速度编码控制 port:连接M端口;speed:0~100;code:0~65535
30
+ def motor_servoctl(port:bytes,speed:bytes,code:int) -> Optional[bytes]:
31
+ motor_str=[0xA0, 0x01, 0x04, 0x81, 0x00, 0x81, 0x00, 0x00, 0xBE]
32
+ motor_str[0]=0XA0+port
33
+ motor_str[4]=speed
34
+ motor_str[6]=code//256
35
+ motor_str[7]=code%256
36
+ response = Uart3_funtions.single_operate_sensor(motor_str)
37
+ if response:
38
+ return 0
39
+ else:
40
+ return -1
41
+
42
+ #马达方向控制 port:连接M端口;dir:
43
+ def write_motor_dir(port:bytes,direc:bytes) -> Optional[bytes]:
44
+ motor_str=[0xA0, 0x01, 0x06, 0x71, 0x00, 0xBE]
45
+ motor_str[0]=0XA0+port
46
+ motor_str[4]=direc
47
+ response = Uart3_funtions.single_operate_sensor(motor_str)
48
+ if response:
49
+ return 0
50
+ else:
51
+ return -1
52
+
53
+ #彩灯控制 port:连接P端口;command:0:关灯;1:红;2:绿;3:蓝;4:黄;5:紫;6:青;7:白
54
+ def color_lamp_operate(port:bytes,command:bytes) -> Optional[bytes]:
55
+ color_lamp_str=[0xA0, 0x05, 0x00, 0xBE]
56
+ color_lamp_str[0]=0XA0+port
57
+ color_lamp_str[2]=command
58
+ response = Uart3_funtions.single_operate_sensor(color_lamp_str)
59
+ if response:
60
+ return 0
61
+ else:
62
+ return -1
63
+
64
+ #触碰传感器 port:连接P端口
65
+ def read_switch(port:bytes) -> Optional[bytes]:
66
+ read_sw_str=[0xA0, 0x03, 0x01, 0xBE]
67
+ read_sw_str[0]=0XA0+port
68
+ response = Uart3_funtions.single_operate_sensor(read_sw_str)
69
+ if response:
70
+ return 0
71
+ else:
72
+ return -1
73
+
74
+ #光电读取 port:连接P端口;command:1:读取;2:开灯;3:关灯;
75
+ def light_operate(port:bytes,command:bytes) -> Optional[bytes]:
76
+ light_str=[0xA0, 0x02, 0x00, 0xBE]
77
+ light_str[0]=0XA0+port
78
+ light_str[2]=command
79
+ response = Uart3_funtions.single_operate_sensor(light_str)
80
+ if response:
81
+ return 0
82
+ else:
83
+ return -1
84
+
85
+ #温湿度读取 port:连接P端口;command:0:读取湿度;1:读取温度;
86
+ def humiture_operate(port:bytes,command:bytes) -> Optional[bytes]:
87
+ humiture_str=[0xA0, 0x0C, 0x01, 0x71, 0x00, 0xBE]
88
+ humiture_str[0]=0XA0+port
89
+ humiture_str[2]=command
90
+ response = Uart3_funtions.single_operate_sensor(humiture_str)
91
+ if response:
92
+ return 0
93
+ else:
94
+ return -1
95
+
96
+ #超声波读取 port:连接P端口;command:1:读取;
97
+ def ultrasonic_operate(port:bytes,command:bytes) -> Optional[bytes]:
98
+ ultrasonic_str=[0xA0, 0x06, 0x00, 0xBE]
99
+ ultrasonic_str[0]=0XA0+port
100
+ ultrasonic_str[2]=command
101
+ response = Uart3_funtions.single_operate_sensor(ultrasonic_str)
102
+ if response:
103
+ return 0
104
+ else:
105
+ return -1
106
+
107
+ #舵机控制 port:连接P端口;command:
108
+ def servo_operate(port:bytes,command:bytes,angle:bytes) -> Optional[bytes]:
109
+ servo_str=[0xA0, 0x0E, 0x01, 0x71, 0x00, 0xBE]
110
+ servo_str[0]=0XA0+port
111
+ servo_str[2]=command
112
+ servo_str[4]=angle
113
+ response = Uart3_funtions.single_operate_sensor(servo_str)
114
+ if response:
115
+ return 0
116
+ else:
117
+ return -1
118
+
119
+
smartpi/module.py ADDED
@@ -0,0 +1,503 @@
1
+ # coding=utf-8
2
+ import serial,time,struct
3
+ from typing import List, Optional
4
+ from collections import deque
5
+
6
+
7
+ # 命令常量
8
+ BOOT_UPDATE_H = 0XFF
9
+ BOOT_UPDATE_L = 0XFF
10
+ READ_MODEL_H = 0XFF
11
+ READ_MODEL_L = 0X01
12
+ READ_VERSION_H = 0XFF
13
+ READ_VERSION_L = 0X02
14
+ READ_FACTORY_H = 0XFF
15
+ READ_FACTORY_L = 0X03
16
+ READ_HW_ID_H = 0XFF
17
+ READ_HW_ID_L = 0X04
18
+ READ_NAME_H = 0XFF
19
+ READ_NAME_L = 0X05
20
+ WRITE_NAME_H = 0XFF
21
+ WRITE_NAME_L = 0X06
22
+ READ_CONNECT_H = 0XFF
23
+ READ_CONNECT_L = 0X07
24
+ READ_BAT_H = 0XFF
25
+ READ_BAT_L = 0X0C
26
+
27
+ UPDATE_REQUEST_H = 0XFF
28
+ UPDATE_REQUEST_L = 0X10
29
+ MAX_COM_LEN_H = 0XFF
30
+ MAX_COM_LEN_L = 0X11
31
+ DL_MESSAGE_H = 0XFF
32
+ DL_MESSAGE_L = 0X12
33
+ READ_STATUS_H = 0XFF
34
+ READ_STATUS_L = 0X13
35
+ PAGE_CHECK_H = 0XFF
36
+ PAGE_CHECK_L = 0X14
37
+ PAGE_SEND_H = 0XFF
38
+ PAGE_SEND_L = 0X15
39
+
40
+ READ_PERIPH_H = 0X01
41
+ READ_PERIPH_L = 0X01
42
+ SINGLE_OP_H = 0X01
43
+ SINGLE_OP_L = 0X02
44
+ MODE_CHANGE_H = 0X01
45
+ MODE_CHANGE_L = 0X03
46
+ SEND_CYCLE_H = 0X01
47
+ SEND_CYCLE_L = 0X04
48
+
49
+ frames_queue = deque()
50
+ buffer = bytearray()
51
+ HEADER = bytes.fromhex('86 AB') # 帧头
52
+ FOOTER = bytes.fromhex('CF') # 帧尾
53
+ MIN_FRAME_LEN = 9 # 最小帧长度
54
+
55
+ # 串口配置参数
56
+ SERIAL_PORT = "/dev/ttyS3" # 串口设备路径
57
+ BAUD_RATE = 115200 # 波特率
58
+ TIMEOUT = 0.1 # 读取超时时间(秒)
59
+
60
+ ser = serial.Serial(
61
+ port=SERIAL_PORT,
62
+ baudrate=BAUD_RATE,
63
+ bytesize=serial.EIGHTBITS, # 8位数据位
64
+ parity=serial.PARITY_NONE, # 无校验位
65
+ stopbits=serial.STOPBITS_ONE, # 1位停止位
66
+ timeout=TIMEOUT,
67
+ xonxoff=False, # 关闭软件流控
68
+ rtscts=False, # 关闭硬件流控
69
+
70
+ )
71
+
72
+ class base_driver:
73
+ def uart3_init() -> Optional[serial.Serial]:
74
+ """初始化串口"""
75
+ try:
76
+ if ser.is_open:
77
+ print("UART3初始化成功")
78
+ return ser
79
+ else:
80
+ print("Error opening UART3")
81
+ return None
82
+ except Exception as e:
83
+ print(f"Error opening UART3: {e}")
84
+ return None
85
+
86
+ def calculate_pro_check(command_h: int, command_l: int, data: List[bytes] = None) -> int:
87
+ if data:
88
+ len_data = len(data)
89
+ base_sum = 0x86 + 0xAB + 0x00 + 0x09 + len_data + command_h + command_l + 0x01 + 0xCF
90
+ base_sum += sum(data)
91
+ else:
92
+ base_sum = 0x86 + 0xAB + 0x00 + 0x09 + command_h + command_l + 0x01 + 0xCF
93
+
94
+ return base_sum % 256 # 确保结果为单字节(原C代码未取模,需根据实际协议调整)
95
+
96
+ def write_data(command_h: int, command_l: int, send_data: bytes= None) -> Optional[bytes]:
97
+ buffer = bytearray()
98
+ HEADER = bytes.fromhex('86 AB') # 帧头
99
+ FOOTER = bytes.fromhex('CF') # 帧尾
100
+ MIN_FRAME_LEN = 9 # 最小帧长度
101
+ if send_data:
102
+ pro_check = base_driver.calculate_pro_check(command_h, command_l, list(send_data))
103
+ send_packet = [0x86, 0xAB, (0x09+len(send_data))//256, (0x09+len(send_data))%256, command_h, command_l, *send_data, 0x01, pro_check, 0xCF]
104
+ else:
105
+ pro_check = base_driver.calculate_pro_check(command_h, command_l)
106
+ send_packet = [0x86, 0xAB, 0x00, 0x09, command_h, command_l, 0x01, pro_check, 0xCF]
107
+ send_bytes = bytes(send_packet)
108
+
109
+ ser.write(send_bytes)
110
+
111
+
112
+ def check_frame(frame: bytes) -> bool:
113
+ # 简化版校验,实际应根据协议实现
114
+ if len(frame) < 9:
115
+ return False
116
+
117
+ # 计算校验和
118
+ calculated_checksum = (sum(frame[:-2])+frame[-1])%256
119
+ frame_checksum = frame[-2] # 倒数第二个字节是校验和
120
+
121
+ return calculated_checksum == frame_checksum
122
+
123
+ def process_received_data():
124
+ global buffer
125
+ # 读取所有可用数据
126
+ data = ser.read(ser.in_waiting or 1)
127
+ if data:
128
+ buffer.extend(data)
129
+ while len(buffer)>=2:
130
+ # for x in buffer:
131
+ # print(f"{x:02X}", end=' ')
132
+ # print("\n")
133
+ # 1. 查找帧头
134
+ start_idx = buffer.find(HEADER)
135
+ if start_idx == -1:
136
+ # 没有找到帧头,清空无效数据(保留最后可能的部分帧头)
137
+ #print("Header no found")
138
+ if len(buffer) > len(HEADER) - 1:
139
+ buffer = buffer[-len(HEADER) + 1:]
140
+ return
141
+ # 2. 检查帧头后的长度字段是否足够
142
+ if start_idx + 4 > len(buffer):
143
+ # 长度字段不完整,等待更多数据
144
+ return
145
+ # 3. 解析帧长度
146
+ frame_length = (buffer[start_idx + 2] << 8) + buffer[start_idx + 3]
147
+ # 4. 检查完整帧是否已到达
148
+ end_idx = start_idx + frame_length - 1
149
+ if end_idx >= len(buffer):
150
+ # 完整帧尚未完全到达
151
+ return
152
+ # 5. 检查帧尾
153
+ if buffer[end_idx] != ord(FOOTER):
154
+ # 跳过当前帧头,继续查找
155
+ print("End no found")
156
+ buffer = buffer[start_idx + 1:]
157
+ continue
158
+ # 6. 提取完整帧
159
+ frame = buffer[start_idx:end_idx + 1]
160
+ frames_queue.append(frame)
161
+ # 7. 从缓冲区移除已处理帧
162
+ buffer = buffer[end_idx + 1:]
163
+ # 处理所有完整帧
164
+ if len(frames_queue) > 0:
165
+ frame = frames_queue.popleft()
166
+ if base_driver.check_frame(frame):
167
+ return frame
168
+ else:
169
+ print("Check byte error")
170
+
171
+ # 功能函数类
172
+ class Uart3_funtions:
173
+
174
+ ##############################################################################读取设备信息
175
+ """固件升级模式"""
176
+ def boot_update() -> None:
177
+ base_driver.write_data(BOOT_UPDATE_H, BOOT_UPDATE_L)
178
+ while True:
179
+ response =base_driver.process_received_data()
180
+ if response:
181
+ display_data = response[6:-3]
182
+ if display_data[0]==0X03:
183
+ print("固件更新启动\n")
184
+ elif display_data[0]==0X01:
185
+ print("擦除中......",f"{10*display_data[1]}","%\n")
186
+ elif display_data[0]==0X02:
187
+ print("升级中......",f"{10*display_data[1]}","%\n")
188
+ elif display_data[0]==0X05:
189
+ print("更新成功!\n")
190
+ elif display_data[0]==0X06:
191
+ print("更新失败!\n")
192
+ else:
193
+ for x in display_data:
194
+ print(f"{x:02X}", end=' ')
195
+ print("\n")
196
+
197
+
198
+ """读取设备型号"""
199
+ def read_device_model() -> Optional[bytes]:
200
+ base_driver.write_data(READ_MODEL_H, READ_MODEL_L)
201
+ start_time = time.time()
202
+ while True:
203
+ response =base_driver.process_received_data()
204
+ if response:
205
+ display_data = response[6:-3].decode(errors="ignore")
206
+ print(f"设备型号: {display_data}")
207
+ return display_data
208
+ else:
209
+ if time.time() - start_time > 3:
210
+ print("读取超时")
211
+ buffer.clear()
212
+ return -1
213
+
214
+ """读取版本号"""
215
+ def read_version() -> Optional[bytes]:
216
+ base_driver.write_data(READ_VERSION_H, READ_VERSION_L)
217
+ start_time = time.time()
218
+ while True:
219
+ response =base_driver.process_received_data()
220
+ if response:
221
+ display_data = response[6:-3].decode(errors="ignore")
222
+ print(f"版本号: {display_data}")
223
+ return display_data
224
+ else:
225
+ if time.time() - start_time > 3:
226
+ print("读取超时")
227
+ buffer.clear()
228
+ return -1
229
+
230
+ """读取工厂信息"""
231
+ def read_factory_data() -> Optional[bytes]:
232
+ base_driver.write_data(READ_FACTORY_H, READ_FACTORY_L)
233
+ start_time = time.time()
234
+ while True:
235
+ response =base_driver.process_received_data()
236
+ if response:
237
+ display_data = response[6:-3].decode(errors="ignore")
238
+ print(f"厂家信息: {display_data}")
239
+ return display_data
240
+ else:
241
+ if time.time() - start_time > 3:
242
+ print("读取超时")
243
+ buffer.clear()
244
+ return -1
245
+
246
+ """读取硬件ID"""
247
+ def read_hardware_ID() -> Optional[bytes]:
248
+ base_driver.write_data(READ_HW_ID_H, READ_HW_ID_L)
249
+ start_time = time.time()
250
+ while True:
251
+ response =base_driver.process_received_data()
252
+ if response:
253
+ display_data = response[6:-3].decode(errors="ignore")
254
+ print(f"硬件ID: {display_data}")
255
+ return display_data
256
+ else:
257
+ if time.time() - start_time > 3:
258
+ print("读取超时")
259
+ buffer.clear()
260
+ return -1
261
+
262
+ """读取设备名称"""
263
+ def read_device_name() -> Optional[bytes]:
264
+ base_driver.write_data(READ_NAME_H, READ_NAME_L)
265
+ start_time = time.time()
266
+ while True:
267
+ response =base_driver.process_received_data()
268
+ if response:
269
+ display_data = response[6:-3].decode(errors="ignore")
270
+ print(f"设备名称: {display_data}")
271
+ return display_data
272
+ else:
273
+ if time.time() - start_time > 3:
274
+ print("读取超时")
275
+ buffer.clear()
276
+ return -1
277
+
278
+ """设置设备名称"""
279
+ def write_device_name(send_data: str) -> Optional[bytes]:
280
+ data_bytes = send_data.encode('utf-8')
281
+ base_driver.write_data(WRITE_NAME_H, WRITE_NAME_L, data_bytes)
282
+ start_time = time.time()
283
+ while True:
284
+ response =base_driver.process_received_data()
285
+ if response:
286
+ display_data = response[6:-3].decode(errors="ignore")
287
+ print(f"设置状态: {display_data}")
288
+ return display_data
289
+ else:
290
+ if time.time() - start_time > 3:
291
+ print("读取超时")
292
+ buffer.clear()
293
+ return -1
294
+
295
+ """读取连接方式"""#长度位少了1
296
+ def read_connected() -> Optional[bytes]:
297
+ base_driver.write_data(READ_CONNECT_H, READ_CONNECT_L)
298
+ start_time = time.time()
299
+ while True:
300
+ response =base_driver.process_received_data()
301
+ if response:
302
+ display_data = response[6:-3].decode(errors="ignore")
303
+ print(f"连接方式: {display_data}")
304
+ return display_data
305
+ else:
306
+ if time.time() - start_time > 3:
307
+ print("读取超时")
308
+ buffer.clear()
309
+ return -1
310
+
311
+ """读取电池电量"""
312
+ def read_battery() -> Optional[bytes]:
313
+ base_driver.write_data(READ_BAT_H, READ_BAT_L)
314
+ start_time = time.time()
315
+ while True:
316
+ response =base_driver.process_received_data()
317
+ if response:
318
+ display_data = response[6:-3]
319
+ # for x in display_data:
320
+ # print(f"{x:02X}", end=' ')
321
+ print(f"电池电量: {display_data}")
322
+ return display_data
323
+ else:
324
+ if time.time() - start_time > 3:
325
+ print("读取超时")
326
+ buffer.clear()
327
+ return -1
328
+
329
+ ###############################################################################固件升级
330
+
331
+ """下载更新请求"""
332
+ def update_request() -> Optional[bytes]:
333
+ base_driver.write_data(UPDATE_REQUEST_H, UPDATE_REQUEST_L)
334
+ start_time = time.time()
335
+ while True:
336
+ response =base_driver.process_received_data()
337
+ if response:
338
+ display_data = response[6:-3].decode(errors="ignore")
339
+ print(f"从机响应: {display_data}")
340
+ return display_data
341
+ else:
342
+ if time.time() - start_time > 3:
343
+ print("读取超时")
344
+ buffer.clear()
345
+ return -1
346
+
347
+ """查询最大通讯长度"""
348
+ def read_max_com_len() -> Optional[bytes]:
349
+ base_driver.write_data(MAX_COM_LEN_H, MAX_COM_LEN_L)
350
+ start_time = time.time()
351
+ while True:
352
+ response =base_driver.process_received_data()
353
+ if response:
354
+ display_data = response[6:-3].decode(errors="ignore")
355
+ print(f"从机响应: {display_data}")
356
+ return display_data
357
+ else:
358
+ if time.time() - start_time > 3:
359
+ print("读取超时")
360
+ buffer.clear()
361
+ return -1
362
+
363
+ """下载文件的信息"""
364
+ def download_massage() -> Optional[bytes]:
365
+ base_driver.write_data(DL_MESSAGE_H, DL_MESSAGE_L, file_data)#文件信息来源从哪获取?
366
+ start_time = time.time()
367
+ while True:
368
+ response =base_driver.process_received_data()
369
+ if response:
370
+ display_data = response[6:-3].decode(errors="ignore")
371
+ print(f"从机响应: {display_data}")
372
+ return display_data
373
+ else:
374
+ if time.time() - start_time > 3:
375
+ print("读取超时")
376
+ buffer.clear()
377
+ return -1
378
+
379
+ """查询设备状态"""
380
+ def read_device_status() -> Optional[bytes]:
381
+ base_driver.write_data(READ_STATUS_H, READ_STATUS_L)
382
+ start_time = time.time()
383
+ while True:
384
+ response =base_driver.process_received_data()
385
+ if response:
386
+ display_data = response[6:-3].decode(errors="ignore")
387
+ print(f"从机响应: {display_data}")
388
+ return display_data
389
+ else:
390
+ if time.time() - start_time > 3:
391
+ print("读取超时")
392
+ buffer.clear()
393
+ return -1
394
+
395
+ """发送页校验码"""
396
+ def write_page_check() -> Optional[bytes]:
397
+ base_driver.write_data(PAGE_CHECK_H, PAGE_CHECK_L, page_check_data)
398
+ start_time = time.time()
399
+ while True:
400
+ response =base_driver.process_received_data()
401
+ if response:
402
+ display_data = response[6:-3].decode(errors="ignore")
403
+ print(f"从机响应: {display_data}")
404
+ return display_data
405
+ else:
406
+ if time.time() - start_time > 3:
407
+ print("读取超时")
408
+ buffer.clear()
409
+ return -1
410
+
411
+ """发送页数据"""
412
+ def write_page_check() -> Optional[bytes]:
413
+ base_driver.write_data(PAGE_SEND_H, PAGE_SEND_L, page_send_data)
414
+ start_time = time.time()
415
+ while True:
416
+ response =base_driver.process_received_data()
417
+ if response:
418
+ display_data = response[6:-3].decode(errors="ignore")
419
+ print(f"从机响应: {display_data}")
420
+ return display_data
421
+ else:
422
+ if time.time() - start_time > 3:
423
+ print("读取超时")
424
+ buffer.clear()
425
+ return -1
426
+
427
+ ###############################################################################读取传感器信息
428
+
429
+ """读取外设连接情况"""
430
+ def read_peripheral() -> Optional[bytes]:
431
+ base_driver.write_data(READ_PERIPH_H, READ_PERIPH_L)
432
+ start_time = time.time()
433
+ while True:
434
+ response =base_driver.process_received_data()
435
+ if response:
436
+ display_data = response[6:-3]
437
+ for x in display_data:
438
+ print(f"{x:02X}", end=' ')
439
+ print("\n")
440
+ return display_data
441
+ else:
442
+ if time.time() - start_time > 3:
443
+ print("读取超时")
444
+ buffer.clear()
445
+ return -1
446
+
447
+ """单次操作外设"""
448
+ def single_operate_sensor(op_struct: bytes) -> Optional[bytes]:
449
+ base_driver.write_data(SINGLE_OP_H, SINGLE_OP_L, op_struct)
450
+ start_time = time.time()
451
+ while True:
452
+ response =base_driver.process_received_data()
453
+ if response:
454
+ display_data = response[6:-3]
455
+ for x in display_data:
456
+ print(f"{x:02X}", end=' ')
457
+ print("\n")
458
+ return display_data
459
+ else:
460
+ if time.time() - start_time > 3:
461
+ print("读取超时")
462
+ buffer.clear()
463
+ return -1
464
+
465
+ """从机模式转换"""
466
+ def mode_change(send_data: str) -> Optional[bytes]:
467
+ base_driver.write_data(MODE_CHANGE_H, MODE_CHANGE_L, send_data)
468
+ start_time = time.time()
469
+ while True:
470
+ response =base_driver.process_received_data()
471
+ if response:
472
+ display_data = response[6:-3]
473
+ for x in display_data:
474
+ print(f"{x:02X}", end=' ')
475
+ print("\n")
476
+ return display_data
477
+ else:
478
+ if time.time() - start_time > 3:
479
+ print("读取超时")
480
+ buffer.clear()
481
+ return -1
482
+
483
+ """智能模式发送周期"""
484
+ def mode_change(send_data: str) -> Optional[bytes]:
485
+ base_driver.write_data(SEND_CYCLE_H, SEND_CYCLE_L, send_data)
486
+ start_time = time.time()
487
+ while True:
488
+ response =base_driver.process_received_data()
489
+ if response:
490
+ display_data = response[6:-3]
491
+ for x in display_data:
492
+ print(f"{x:02X}", end=' ')
493
+ print("\n")
494
+ return display_data
495
+ else:
496
+ if time.time() - start_time > 3:
497
+ print("读取超时")
498
+ buffer.clear()
499
+ return -1
500
+
501
+
502
+
503
+
smartpi/mpu6500.py ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env python3
2
+ import time
3
+ import math
4
+ from smbus import SMBus
5
+
6
+ MPU_ADDR = 0x68 # 根据AD0引脚调整
7
+ I2C_BUS = 3 # I2C-3接口
8
+ ACCEL_RANGE = 0x00 # ±2g
9
+ GYRO_RANGE = 0x18 # ±2000°/s
10
+ SAMPLING_RATE = 100 # 100Hz
11
+
12
+ # DMP固件数据(示例数据,需根据传感器型号调整)
13
+ DMP_FIRMWARE = [
14
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15
+ # 此处省略实际固件数据(需从官方获取)
16
+ ]
17
+
18
+ class MPU6500:
19
+ def __init__(self):
20
+ self.bus = SMBus(I2C_BUS)
21
+ self.registers = {
22
+ 'PWR_MGMT_1': 0x6B,
23
+ 'GYRO_CFG': 0x1B,
24
+ 'ACCEL_CFG': 0x1C,
25
+ 'SMPLRT_DIV': 0x19,
26
+ 'USER_CTRL': 0x6A,
27
+ 'FIFO_EN': 0x23,
28
+ 'FIFO_COUNT_H': 0x72,
29
+ 'FIFO_R_W': 0x74,
30
+ 'DMP_CFG_1': 0x70,
31
+ 'DMP_CFG_2': 0x71,
32
+ 'WHO_AM_I': 0x75
33
+ }
34
+
35
+ self.gyro_scale = self._get_gyro_scale(GYRO_RANGE)
36
+ self.accel_scale = self._get_accel_scale(ACCEL_RANGE)
37
+ self._initialize_hardware()
38
+ # self._load_dmp_firmware()
39
+ self._configure_dmp()
40
+
41
+ def _initialize_hardware(self):
42
+ """初始化硬件寄存器"""
43
+ self._write_reg('PWR_MGMT_1', 0x80) # 软复位
44
+ time.sleep(0.1)
45
+ self._write_reg('PWR_MGMT_1', 0x01) # 唤醒,选择陀螺仪X轴时钟
46
+ time.sleep(0.1)
47
+
48
+ self._write_reg('GYRO_CFG', GYRO_RANGE)
49
+ self._write_reg('ACCEL_CFG', ACCEL_RANGE)
50
+ self._write_reg('SMPLRT_DIV', (1000 // SAMPLING_RATE) - 1)
51
+
52
+ def _load_dmp_firmware(self):
53
+ """加载DMP固件(示例,需替换为实际固件)"""
54
+ print("加载DMP固件...")
55
+ for addr, data in enumerate(DMP_FIRMWARE):
56
+ self._write_reg(0x40 + addr, data) # 固件从0x40地址开始写入
57
+ time.sleep(0.001)
58
+ print("固件加载完成")
59
+
60
+ def _configure_dmp(self):
61
+ """配置DMP参数"""
62
+ self._write_reg('USER_CTRL', 0x00) # 禁用DMP
63
+ self._write_reg('FIFO_EN', 0x00) # 禁用FIFO
64
+ self._write_reg('DMP_CFG_1', 0x03) # 设置DMP采样率
65
+ self._write_reg('DMP_CFG_2', 0x00) # 禁用低功耗模式
66
+
67
+ self._write_reg('USER_CTRL', 0x10) # 复位FIFO
68
+ time.sleep(0.01)
69
+ self._write_reg('USER_CTRL', 0x80) # 启用DMP
70
+ time.sleep(0.1)
71
+ self._write_reg('FIFO_EN', 0x40) # 启用四元数FIFO
72
+
73
+ def _write_reg(self, reg, value):
74
+ """安全写入寄存器(支持寄存器名称字符串或数值地址)"""
75
+ if isinstance(reg, str):
76
+ reg_addr = self.registers[reg]
77
+ else:
78
+ reg_addr = reg
79
+
80
+ try:
81
+ self.bus.write_byte_data(MPU_ADDR, reg_addr, value)
82
+ except Exception as e:
83
+ print(f"写入寄存器0x{reg_addr:02X}失败: {e}")
84
+
85
+ def read_dmp_quaternion(self):
86
+ """读取DMP生成的四元数"""
87
+ high = self.bus.read_byte_data(MPU_ADDR, self.registers['FIFO_COUNT_H'])
88
+ low = self.bus.read_byte_data(MPU_ADDR, self.registers['FIFO_COUNT_H'] + 1)
89
+ fifo_len = (high << 8) | low
90
+
91
+ if fifo_len < 8:
92
+ return None
93
+
94
+ data = self.bus.read_i2c_block_data(MPU_ADDR, self.registers['FIFO_R_W'], 8)
95
+ return self._parse_quaternion(data)
96
+
97
+ def _parse_quaternion(self, bytes):
98
+ """解析四元数(小端模式)"""
99
+ q1 = self._bytes_to_sint16(bytes[0:2]) / 32768.0
100
+ q2 = self._bytes_to_sint16(bytes[2:4]) / 32768.0
101
+ q3 = self._bytes_to_sint16(bytes[4:6]) / 32768.0
102
+ q4 = self._bytes_to_sint16(bytes[6:8]) / 32768.0
103
+ return (q1, q2, q3, q4)
104
+
105
+ def _bytes_to_sint16(self, bytes):
106
+ val = (bytes[1] << 8) | bytes[0]
107
+ return val if val < 32768 else val - 65536
108
+
109
+ def _get_gyro_scale(self, range_bits):
110
+ return {0x18: 16.4}[range_bits]
111
+
112
+ def _get_accel_scale(self, range_bits):
113
+ return {0x00: 16384.0}[range_bits]
114
+
115
+ if __name__ == "__main__":
116
+ mpu = MPU6500()
117
+ print("开始读取DMP数据...")
118
+
119
+ try:
120
+ while True:
121
+ q = mpu.read_dmp_quaternion()
122
+ if q:
123
+ norm = math.sqrt(sum(x**2 for x in q))
124
+ if norm > 0.5: # 仅输出有效四元数
125
+ print(f"四元数: {q}, 模长: {norm}")
126
+ else:
127
+ print("警告:四元数无效,模长过低")
128
+ time.sleep(0.1)
129
+ except KeyboardInterrupt:
130
+ print("程序停止")
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.1
2
+ Name: smartpi
3
+ Version: 0.1.0
4
+ Summary: A library use for H2-RCU
5
+ Author-email: Driver_cai <1547363120@qq.com>
6
+ Project-URL: Homepage, https://github.com/Drvier_cai/smartpi
7
+ Project-URL: Bug Tracker, https://github.com/Driver/smartpi/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+
@@ -0,0 +1,8 @@
1
+ smartpi/__init__.py,sha256=_xzkH8V5GZzuj5JxMhfOT0D3mnDrxPJeshfHYyOxSqU,55
2
+ smartpi/app_module.py,sha256=g0YoZV1EKj4U3KIcqF5Gs3xhxPo8hHnZxKns7vmv3OY,4377
3
+ smartpi/module.py,sha256=499JtkF4Rb_syg9xlSjGWbSWw4-2JovOhLg8GJawCKw,19318
4
+ smartpi/mpu6500.py,sha256=UzlRg-n228ZKWO08nh1Mmmk3Y2JJR59fPWABciF7Fck,4723
5
+ smartpi-0.1.0.dist-info/METADATA,sha256=pUCer6guyr5lSW6uonMAOA327Z-yNood_XdsTl0pBBA,468
6
+ smartpi-0.1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
7
+ smartpi-0.1.0.dist-info/top_level.txt,sha256=PoLhUCmWAiQUg5UeN2fS-Y1iQyBbF2rdUlizXtpHGRQ,8
8
+ smartpi-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.42.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ smartpi