Skip to content

Commit 959660d

Browse files
authored
Merge pull request #16 from openmv/custom_channels
cli: Support reading and previewing a custom channel.
2 parents 0ea7de6 + 7ac95ed commit 959660d

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ openmv --port /dev/ttyACM0 --quiet
3333

3434
# Debug mode (verbose logging)
3535
openmv --port /dev/ttyACM0 --debug
36+
37+
# Preview a custom data channel
38+
openmv --port /dev/ttyACM0 --channel ticks
3639
```
3740

3841
### Options
@@ -47,6 +50,7 @@ openmv --port /dev/ttyACM0 --debug
4750
| `--timeout SEC` | 1.0 | Protocol timeout in seconds |
4851
| `--baudrate N` | 921600 | Serial baudrate |
4952
| `--firmware FILE` | None | Firmware ELF file for profiler symbol resolution |
53+
| `--channel NAME` | None | Custom data channel to poll and print |
5054
| `--quiet` | False | Suppress script output text |
5155
| `--debug` | False | Enable debug logging |
5256

@@ -108,6 +112,46 @@ with Camera('/dev/ttyACM0') as camera:
108112
print(text, end='')
109113
```
110114

115+
### Custom Channels
116+
117+
Custom channels allow bidirectional data exchange between the camera and host.
118+
119+
**Camera-side script (MicroPython):**
120+
121+
```python
122+
import time
123+
import protocol
124+
125+
class TicksChannel:
126+
def size(self):
127+
return 10
128+
129+
def read(self, offset, size):
130+
return f'{time.ticks_ms():010d}'
131+
132+
def poll(self):
133+
return True
134+
135+
protocol.register(name='ticks', backend=TicksChannel())
136+
```
137+
138+
**Host-side (Python):**
139+
140+
```python
141+
from openmv import Camera
142+
143+
with Camera('/dev/ttyACM0') as camera:
144+
camera.exec(script)
145+
146+
while True:
147+
# Check if channel has data
148+
if camera.has_channel('ticks'):
149+
size = camera.channel_size('ticks')
150+
if size > 0:
151+
data = camera.channel_read('ticks', size)
152+
print(f"Ticks: {data.decode()}")
153+
```
154+
111155
## API Reference
112156

113157
Full API documentation: [docs/api.md](https://github.com/openmv/openmv-python/blob/master/docs/api.md)

src/openmv/cli.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,25 @@
3535

3636
# Default test script for csi-based cameras
3737
test_script = """
38-
import csi, image, time
38+
import time
39+
import protocol
40+
import csi
41+
import image
42+
43+
class TicksChannel:
44+
def __init__(self):
45+
pass
46+
47+
def size(self):
48+
return 10
49+
50+
def read(self, offset, size):
51+
return f'{time.ticks_ms():010d}'
52+
53+
def poll(self):
54+
return True
55+
56+
ch1 = protocol.register(name='ticks', backend=TicksChannel())
3957
4058
csi0 = csi.CSI()
4159
csi0.reset()
@@ -145,6 +163,10 @@ def main():
145163
action='store_true',
146164
help='Suppress script output text')
147165

166+
parser.add_argument('--channel',
167+
action='store', default=None,
168+
help='Custom channel to poll and read')
169+
148170
args = parser.parse_args()
149171

150172
# Register signal handlers for clean exit
@@ -249,6 +271,13 @@ def main():
249271
if text := camera.read_stdout():
250272
print(text, end='')
251273

274+
# Read custom channel
275+
if args.channel and status and status.get(args.channel):
276+
if size := camera.channel_size(args.channel):
277+
data = camera.channel_read(args.channel, size=size)
278+
preview = data[:10] if len(data) > 10 else data
279+
logging.info(f"[{args.channel}] ({size} bytes) {preview}")
280+
252281
# Read frame data
253282
if frame := camera.read_frame():
254283
fps = fps_clock.get_fps()

0 commit comments

Comments
 (0)