|
8 | 8 | import asyncio
|
9 | 9 | import csv
|
10 | 10 | from datetime import datetime
|
| 11 | +import threading |
11 | 12 |
|
12 | 13 | class Connection:
|
13 | 14 | def __init__(self):
|
14 | 15 | self.ble_connection = None
|
15 | 16 | self.wifi_connection = None
|
| 17 | + self.usb_connection = None |
16 | 18 | self.lsl_connection = None
|
17 | 19 | self.stream_name = "BioAmpDataStream"
|
18 | 20 | self.stream_type = "EXG"
|
@@ -153,24 +155,28 @@ def notification_handler(sender, data):
|
153 | 155 | return False
|
154 | 156 |
|
155 | 157 | def connect_usb(self):
|
156 |
| - serial_connection = Chords_USB() |
157 |
| - if serial_connection.detect_hardware(): |
158 |
| - self.num_channels = serial_connection.num_channels |
159 |
| - sampling_rate = serial_connection.supported_boards[serial_connection.board]["sampling_rate"] |
| 158 | + self.usb_connection = Chords_USB() |
| 159 | + if self.usb_connection.detect_hardware(): |
| 160 | + self.num_channels = self.usb_connection.num_channels |
| 161 | + sampling_rate = self.usb_connection.supported_boards[self.usb_connection.board]["sampling_rate"] |
160 | 162 |
|
161 | 163 | self.setup_lsl(self.num_channels, sampling_rate)
|
162 | 164 |
|
163 |
| - original_read_data = serial_connection.read_data |
| 165 | + original_read_data = self.usb_connection.read_data |
164 | 166 | def wrapped_read_data():
|
165 | 167 | original_read_data()
|
166 |
| - if hasattr(serial_connection, 'data') and self.lsl_connection: |
167 |
| - sample = serial_connection.data[:, -1] |
| 168 | + if hasattr(self.usb_connection, 'data') and self.lsl_connection: |
| 169 | + sample = self.usb_connection.data[:, -1] |
168 | 170 | self.lsl_connection.push_sample(sample)
|
169 | 171 | if self.recording_active:
|
170 | 172 | self.log_to_csv(sample.tolist())
|
171 | 173 |
|
172 |
| - serial_connection.read_data = wrapped_read_data |
173 |
| - serial_connection.start_streaming() |
| 174 | + self.usb_connection.read_data = wrapped_read_data |
| 175 | + |
| 176 | + # Start streaming in a separate thread |
| 177 | + self.usb_thread = threading.Thread(target=self.usb_connection.start_streaming) |
| 178 | + self.usb_thread.daemon = True |
| 179 | + self.usb_thread.start() |
174 | 180 | return True
|
175 | 181 | return False
|
176 | 182 |
|
@@ -214,13 +220,42 @@ def connect_wifi(self):
|
214 | 220 |
|
215 | 221 | def cleanup(self):
|
216 | 222 | self.stop_csv_recording()
|
217 |
| - self.stream_active = False |
218 |
| - if self.ble_connection: |
219 |
| - self.ble_connection.disconnect() |
220 |
| - if self.wifi_connection: |
221 |
| - self.wifi_connection.disconnect() |
| 223 | + |
222 | 224 | if self.lsl_connection:
|
223 | 225 | self.lsl_connection = None
|
| 226 | + print("LSL stream stopped") |
| 227 | + |
| 228 | + if self.usb_connection: |
| 229 | + try: |
| 230 | + self.usb_connection.cleanup() |
| 231 | + print("USB connection closed") |
| 232 | + if hasattr(self, 'usb_thread') and self.usb_thread.is_alive(): |
| 233 | + self.usb_thread.join(timeout=1) # Wait for thread to finish |
| 234 | + except Exception as e: |
| 235 | + print(f"Error closing USB connection: {str(e)}") |
| 236 | + finally: |
| 237 | + self.usb_connection = None |
| 238 | + |
| 239 | + if self.ble_connection: |
| 240 | + try: |
| 241 | + self.ble_connection.disconnect() |
| 242 | + print("BLE connection closed") |
| 243 | + except Exception as e: |
| 244 | + print(f"Error closing BLE connection: {str(e)}") |
| 245 | + finally: |
| 246 | + self.ble_connection = None |
| 247 | + |
| 248 | + if self.wifi_connection: |
| 249 | + try: |
| 250 | + self.wifi_connection.disconnect() |
| 251 | + print("WiFi connection closed") |
| 252 | + except Exception as e: |
| 253 | + print(f"Error closing WiFi connection: {str(e)}") |
| 254 | + finally: |
| 255 | + self.wifi_connection = None |
| 256 | + |
| 257 | + self.stream_active = False |
| 258 | + self.recording_active = False |
224 | 259 |
|
225 | 260 | def __del__(self):
|
226 | 261 | self.cleanup()
|
|
0 commit comments