Upload openbci_impedance.py
Browse files- openbci_impedance.py +17 -15
openbci_impedance.py
CHANGED
|
@@ -51,7 +51,7 @@ SCALE_UV = (ADS1299_VREF / ADS1299_GAIN) / (2**23 - 1) * 1_000_000
|
|
| 51 |
# Pleine echelle ADS1299 en Β΅V (seuil railing)
|
| 52 |
ADC_MAX_UV = (2**23 - 1) * SCALE_UV # β 187 500 Β΅V
|
| 53 |
|
| 54 |
-
LEAD_OFF_FREQ = 31.
|
| 55 |
LEAD_OFF_AMPS = 6e-9 # A
|
| 56 |
SERIES_RESISTOR = 2200 # Ξ©
|
| 57 |
|
|
@@ -142,15 +142,19 @@ def parse_packet(data: bytes):
|
|
| 142 |
return None
|
| 143 |
if data[0] != START_BYTE:
|
| 144 |
return None
|
| 145 |
-
|
|
|
|
| 146 |
return None
|
| 147 |
sample_num = data[1]
|
|
|
|
|
|
|
|
|
|
| 148 |
channels_uv = []
|
| 149 |
for ch in range(8):
|
| 150 |
offset = 2 + ch * 3
|
| 151 |
raw = parse_24bit_signed(data[offset], data[offset+1], data[offset+2])
|
| 152 |
channels_uv.append(raw * SCALE_UV)
|
| 153 |
-
return sample_num, channels_uv
|
| 154 |
|
| 155 |
|
| 156 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -182,7 +186,7 @@ def _make_bandpass_sos(low_hz: float, high_hz: float, order: int = 4,
|
|
| 182 |
# Pre-calculer les filtres une seule fois
|
| 183 |
# Californie = reseau 60 Hz uniquement (pas de 50 Hz)
|
| 184 |
_NOTCH_60_SOS = _make_notch_sos(60.0)
|
| 185 |
-
_BANDPASS_SOS = _make_bandpass_sos(
|
| 186 |
|
| 187 |
|
| 188 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -253,7 +257,6 @@ class CytonDaisyBoard:
|
|
| 253 |
|
| 254 |
self._buf_size = SAMPLE_RATE * 4
|
| 255 |
self._buffers = [deque(maxlen=self._buf_size) for _ in range(N_CHANNELS)]
|
| 256 |
-
self._last_cyton_data = None
|
| 257 |
self._rx_thread = None
|
| 258 |
|
| 259 |
def connect(self):
|
|
@@ -418,18 +421,17 @@ class CytonDaisyBoard:
|
|
| 418 |
print(f"[Board] Erreur lecture : {e}")
|
| 419 |
time.sleep(0.005)
|
| 420 |
|
| 421 |
-
def _handle_sample(self, sample_num: int, ch_data_uv: list):
|
| 422 |
-
|
| 423 |
with self._lock:
|
| 424 |
-
if
|
| 425 |
-
|
|
|
|
|
|
|
| 426 |
else:
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
for i in range(8):
|
| 431 |
-
self._buffers[8 + i].append(ch_data_uv[i])
|
| 432 |
-
self._last_cyton_data = None
|
| 433 |
|
| 434 |
def get_impedances(self) -> list:
|
| 435 |
with self._lock:
|
|
|
|
| 51 |
# Pleine echelle ADS1299 en Β΅V (seuil railing)
|
| 52 |
ADC_MAX_UV = (2**23 - 1) * SCALE_UV # β 187 500 Β΅V
|
| 53 |
|
| 54 |
+
LEAD_OFF_FREQ = 31.25 # Hz β frΓ©quence exacte ADS1299 (31.25 Hz, pas 31.5)
|
| 55 |
LEAD_OFF_AMPS = 6e-9 # A
|
| 56 |
SERIES_RESISTOR = 2200 # Ξ©
|
| 57 |
|
|
|
|
| 142 |
return None
|
| 143 |
if data[0] != START_BYTE:
|
| 144 |
return None
|
| 145 |
+
stop_byte = data[32]
|
| 146 |
+
if (stop_byte & 0xF0) != 0xC0:
|
| 147 |
return None
|
| 148 |
sample_num = data[1]
|
| 149 |
+
# FIX : stop byte 0xC0 = Cyton packet, 0xC1 = Daisy packet
|
| 150 |
+
# C'est le nibble bas qui indique la source, PAS la paritΓ© du sample_num
|
| 151 |
+
is_daisy = (stop_byte & 0x0F) == 0x01
|
| 152 |
channels_uv = []
|
| 153 |
for ch in range(8):
|
| 154 |
offset = 2 + ch * 3
|
| 155 |
raw = parse_24bit_signed(data[offset], data[offset+1], data[offset+2])
|
| 156 |
channels_uv.append(raw * SCALE_UV)
|
| 157 |
+
return sample_num, channels_uv, is_daisy
|
| 158 |
|
| 159 |
|
| 160 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 186 |
# Pre-calculer les filtres une seule fois
|
| 187 |
# Californie = reseau 60 Hz uniquement (pas de 50 Hz)
|
| 188 |
_NOTCH_60_SOS = _make_notch_sos(60.0)
|
| 189 |
+
_BANDPASS_SOS = _make_bandpass_sos(30.5, 32.0) # FIX : bande Γ©troite Β±0.75 Hz autour de 31.25 Hz
|
| 190 |
|
| 191 |
|
| 192 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 257 |
|
| 258 |
self._buf_size = SAMPLE_RATE * 4
|
| 259 |
self._buffers = [deque(maxlen=self._buf_size) for _ in range(N_CHANNELS)]
|
|
|
|
| 260 |
self._rx_thread = None
|
| 261 |
|
| 262 |
def connect(self):
|
|
|
|
| 421 |
print(f"[Board] Erreur lecture : {e}")
|
| 422 |
time.sleep(0.005)
|
| 423 |
|
| 424 |
+
def _handle_sample(self, sample_num: int, ch_data_uv: list, is_daisy: bool):
|
| 425 |
+
# FIX : on utilise le flag is_daisy du stop byte, pas la paritΓ© du sample_num
|
| 426 |
with self._lock:
|
| 427 |
+
if not is_daisy:
|
| 428 |
+
# Packet Cyton β canaux 0-7, on stocke directement
|
| 429 |
+
for i in range(8):
|
| 430 |
+
self._buffers[i].append(ch_data_uv[i])
|
| 431 |
else:
|
| 432 |
+
# Packet Daisy β canaux 8-15
|
| 433 |
+
for i in range(8):
|
| 434 |
+
self._buffers[8 + i].append(ch_data_uv[i])
|
|
|
|
|
|
|
|
|
|
| 435 |
|
| 436 |
def get_impedances(self) -> list:
|
| 437 |
with self._lock:
|