Skip to content

Commit 54e8246

Browse files
TinyuZhaolbuque
authored andcommitted
libs/module: Add Module ASR support.
Signed-off-by: tinyu <tinyu.zhao@gmail.com>
1 parent f3490bc commit 54e8246

4 files changed

Lines changed: 82 additions & 13 deletions

File tree

m5stack/libs/module/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
_attrs = {
88
"AIN4Module": "ain4",
9+
"ASRModule": "asr",
910
"AudioModule": "audio",
1011
"Bala2Module": "bala2",
1112
"CC1101Module": "cc1101",

m5stack/libs/module/asr.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
2+
#
3+
# SPDX-License-Identifier: MIT
4+
from unit.asr import ASRUnit
5+
6+
7+
class ASRModule(ASRUnit):
8+
"""Voice recognition hardware module.
9+
10+
:param int id: UART port ID for communication. Default is 1.
11+
:param list|tuple port: Tuple containing TX and RX pin numbers.
12+
13+
UiFlow2 Code Block:
14+
15+
|init.png|
16+
17+
MicroPython Code Block:
18+
19+
.. code-block:: python
20+
21+
from unit import ASRUnit
22+
23+
# Initialize with UART1, TX on pin 2, RX on pin 1
24+
asr = ASRUnit(id=1, port=(1, 2))
25+
"""
26+
27+
def __init__(self, id: Literal[0, 1, 2] = 1, tx=-1, rx=-1, verbose: bool = False):
28+
super().__init__(id, port=(rx, tx), verbose=verbose)

m5stack/libs/module/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
(
88
"__init__.py",
99
"ain4.py",
10+
"asr.py",
1011
"audio.py",
1112
"bala2.py",
1213
"cc1101.py",

m5stack/libs/unit/asr.py

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ class ASRUnit:
7171
0x43: ["medium volume", None],
7272
0x44: ["minimum volume", None],
7373
0x45: ["check firmware version", None],
74+
0x50: ["PA2 high level", None],
75+
0x51: ["PA2 low level", None],
76+
0x52: ["PA3 high level", None],
77+
0x53: ["PA3 low level", None],
78+
0x54: ["PA4 high level", None],
79+
0x55: ["PA4 low level", None],
80+
0x56: ["PA5 high level", None],
81+
0x57: ["PA5 low level", None],
82+
0x58: ["PC4 high level", None],
83+
0x59: ["PC4 low level", None],
84+
0x5A: ["inversion level", None],
7485
0xFE: ["Announce", None],
7586
0xFF: ["Hi,M Five", None],
7687
}
@@ -90,20 +101,48 @@ def _debug_print(self, *args, **kwargs):
90101
print(*args, **kwargs)
91102

92103
def _handler(self, uart) -> None:
104+
if uart.any() < 5:
105+
return
106+
93107
data = uart.read()
94-
if data is not None and len(data) >= 5:
95-
self._debug_print(("Received data: ", data))
96-
97-
if data[0] == 0xAA and data[1] == 0x55 and data[-2] == 0x55 and data[-1] == 0xAA:
98-
self.is_recieved = True
99-
self.raw_message = " ".join(f"0x{byte:02X}" for byte in data)
100-
self._debug_print(("Parsed message:", self.raw_message.split()))
101-
102-
self.command_num = data[2]
103-
self.check_tick_callback()
104-
else:
105-
self._debug_print("Invalid frame received: header/footer mismatch")
106-
uart.read()
108+
if data is None or len(data) < 5:
109+
return
110+
111+
self._debug_print(("Received data: ", data))
112+
113+
# 检查5字节格式: AA 55 CMD 55 AA
114+
if (
115+
len(data) >= 5
116+
and data[0] == 0xAA
117+
and data[1] == 0x55
118+
and data[3] == 0x55
119+
and data[4] == 0xAA
120+
):
121+
self.is_recieved = True
122+
self.command_num = data[2]
123+
self.msg = 0 # 5字节格式没有msg字段
124+
self.raw_message = " ".join(f"0x{byte:02X}" for byte in data[:5])
125+
self._debug_print(("Parsed 5-byte message:", self.raw_message))
126+
self.check_tick_callback()
127+
128+
# 检查6字节格式: AA 55 CMD MSG 55 AA
129+
elif (
130+
len(data) >= 6
131+
and data[0] == 0xAA
132+
and data[1] == 0x55
133+
and data[4] == 0x55
134+
and data[5] == 0xAA
135+
):
136+
self.is_recieved = True
137+
self.command_num = data[2]
138+
self.msg = data[3] # 6字节格式包含msg字段
139+
self.raw_message = " ".join(f"0x{byte:02X}" for byte in data[:6])
140+
self._debug_print(("Parsed 6-byte message:", self.raw_message))
141+
self.check_tick_callback()
142+
143+
else:
144+
self._debug_print("Invalid frame received: header/footer mismatch")
145+
uart.read()
107146

108147
def get_received_status(self) -> bool:
109148
"""Get message reception status.

0 commit comments

Comments
 (0)