Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d4e3880
chore: gitignore stray lsl-dummy-stream binary
RaulSimpetru Jun 3, 2026
e3cb620
docs(spec): design for native OTB device sources (Muovi/Quattrocento)
RaulSimpetru Jun 3, 2026
396449f
docs(spec): correct Muovi gain mapping + add GUI device-config panel
RaulSimpetru Jun 3, 2026
d9dd678
docs(spec): verify Muovi protocol against manufacturer PDFs
RaulSimpetru Jun 3, 2026
e5d41a6
docs(spec): confirm Muovi byte order + channel map from MuoviLite manual
RaulSimpetru Jun 3, 2026
f14b102
docs(spec): confirm Muovi command + decode against OTB MATLAB reference
RaulSimpetru Jun 3, 2026
f37b209
docs(reference): vendor OTB MATLAB decode references for OTB sources
RaulSimpetru Jun 3, 2026
49f51e1
docs(spec): verify Quattrocento protocol against manufacturer docs
RaulSimpetru Jun 3, 2026
aab32ea
docs(plan): implementation plan for OTB Muovi + Quattrocento sources
RaulSimpetru Jun 3, 2026
3024abb
feat(otb): add CRC-8 for OTB framed commands
RaulSimpetru Jun 3, 2026
fcd3134
feat(otb): add big-endian Muovi frame decoders
RaulSimpetru Jun 3, 2026
9d5962d
feat(otb): add Muovi geometry + control-byte constants
RaulSimpetru Jun 3, 2026
ec70f41
feat(otb): add _OTBSource base (buffering, framing, timestamps)
RaulSimpetru Jun 3, 2026
baf4e35
feat(otb): add MuoviSource (TCP server, big-endian decode)
RaulSimpetru Jun 3, 2026
bf61ca0
feat(otb): export MuoviSource from package
RaulSimpetru Jun 3, 2026
bf08734
test(otb): silence post-teardown socket noise in Muovi loopback test
RaulSimpetru Jun 3, 2026
8aa400c
feat(otb): add little-endian Quattrocento decoder
RaulSimpetru Jun 3, 2026
3c93516
feat(otb): add Quattrocento 40-byte config builder
RaulSimpetru Jun 3, 2026
75d205f
feat(otb): add QuattrocentoSource (TCP client, little-endian decode)
RaulSimpetru Jun 3, 2026
e621bc7
feat(otb): export QuattrocentoSource from package
RaulSimpetru Jun 3, 2026
66768ac
refactor(otb): move crc8 import to top of _constants (drop E402 noqa)
RaulSimpetru Jun 3, 2026
588f98a
docs(otb): add Muovi example + connect-OTB-devices how-to
RaulSimpetru Jun 3, 2026
1f642d0
fix(otb): address final-review findings (disconnect, leaks, channel n…
RaulSimpetru Jun 3, 2026
f3a251d
fix(otb): correct Quattrocento AUX/bio partition + recv error handlin…
RaulSimpetru Jun 3, 2026
b15baa9
docs(spec): confirm Muovi+ direct geometry = 64 bio + 6 aux = 70
RaulSimpetru Jun 4, 2026
2860e09
Merge remote-tracking branch 'origin/main' into feat/otb-device-sources
RaulSimpetru Jun 7, 2026
cfa65cf
chore(otb): adapt to merged main (reorg + standardized API)
RaulSimpetru Jun 7, 2026
15504b4
Merge remote-tracking branch 'origin/main' into feat/otb-device-sources
RaulSimpetru Jun 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ site/
# virtual_hand() defaults to this path; override with $VHI_PATH.
tools/MyoGestic-VHI

# Stray LSL recording-toolbox binaries (separate Rust repo; not a MyoGestic
# dep — MyoGestic's EMG simulator is the Python myogestic.tools.emg_generator).
tools/lsl-dummy-stream

# Browser playground - locally built MyoGestic wheel + manifest.
# CI generates both fresh each deploy; committing would just bitrot.
docs/playground/wheels/*.whl
Expand Down
42 changes: 42 additions & 0 deletions docs/how-to/connect-otb-devices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Connect OT Bioelettronica devices

MyoGestic talks to OTB Muovi/Muovi+ and Quattrocento natively — no Qt, no
external bridge. Each device is a `Source` you drop into a `Stream`.

## Muovi / Muovi+ (Wi-Fi)

The PC is the TCP **server**; the probe connects to it.

1. Hold the probe button ~5 s → it becomes a Wi-Fi access point `MVxxx-ID`.
2. Join that network from the PC.
3. ```python
from myogestic import Stream
from myogestic.sources.otb import MuoviSource
stream = Stream("emg", source=MuoviSource(plus=False, emg=True, mode=0),
window_ms=1000)
stream.start()
```

Defaults: 32-ch (Muovi) monopolar gain-8 EMG @ 2000 Hz, biosignal-only
(286.1 nV/LSB → mV). Pass `plus=True` for 64-ch Muovi+, `emg=False` for EEG
(500 Hz, 24-bit), `include_aux=True` to also stream IMU/buffer/counter.

## Quattrocento (Ethernet)

The PC is the TCP **client** to the amplifier (default `169.254.1.10:23456`).
Give the PC NIC a `169.254.x.x` address on that segment.

```python
from myogestic.sources.otb import QuattrocentoSource
stream = Stream("emg", source=QuattrocentoSource(fs_mode=1, nch_mode=1),
window_ms=1000) # 2048 Hz, 216 streamed ch
stream.start()
```

`nch_mode` 0..3 → 120/216/312/408 streamed channels; `fs_mode` 0..3 →
512/2048/5120/10240 Hz. Biosignal-only by default exposes the grid channels
(96/192/288/384 for nch_mode 0..3) scaled to mV; `include_aux=True` also appends
the 16 AUX IN (analog, scaled to V) and the 8 accessory channels (counter /
trigger / buffer, raw). Always stop the stream before reconnecting.

> Protocol references: `docs/reference/otb/`.
30 changes: 30 additions & 0 deletions docs/reference/otb/CRC8.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
function crc = CRC8(Vector, Len)

crc = 0;
j = 1;

while(Len > 0)
Extract = Vector(j);
for i = 8:-1:1

Sum = xor(mod(crc,2), mod(Extract,2));
crc = floor(crc/2);

if(Sum > 0)
str = zeros(1,8);
a = dec2bin(crc,8);
b = dec2bin(140,8);
for k = 1 : 8
str(k) = ~((a(k) == b(k)));
end

crc = bin2dec(strrep(num2str(str),' ',''));
end

Extract = floor(Extract/2);
end

Len = Len - 1;

j=j+1;
end
Loading
Loading