1
- from chords_serial import Serial_USB
2
- from chords_wifi import NPG_Wifi
3
- from chords_ble import NPG_Ble
1
+ from chords_serial import Chords_USB
2
+ from chords_wifi import Chords_WIFI
3
+ from chords_ble import Chords_BLE
4
4
from pylsl import StreamInfo , StreamOutlet
5
5
import argparse
6
6
import time
@@ -13,7 +13,7 @@ class Connection:
13
13
def __init__ (self , csv_logging = False ):
14
14
self .ble_connection = None
15
15
self .wifi_connection = None
16
- self .lsl_outlet = None
16
+ self .lsl_connection = None
17
17
self .stream_name = "BioAmpDataStream"
18
18
self .stream_type = "EXG"
19
19
self .stream_format = "float32"
@@ -28,7 +28,7 @@ def __init__(self, csv_logging=False):
28
28
self .num_channels = 0
29
29
30
30
async def get_ble_device (self ):
31
- devices = await NPG_Ble .scan_devices ()
31
+ devices = await Chords_BLE .scan_devices ()
32
32
if not devices :
33
33
print ("No NPG devices found!" )
34
34
return None
@@ -49,40 +49,47 @@ async def get_ble_device(self):
49
49
50
50
def setup_lsl (self , num_channels , sampling_rate ):
51
51
info = StreamInfo (self .stream_name , self .stream_type , num_channels , sampling_rate , self .stream_format , self .stream_id )
52
- self .lsl_outlet = StreamOutlet (info )
52
+ self .lsl_connection = StreamOutlet (info )
53
53
print (f"LSL stream started: { num_channels } channels at { sampling_rate } Hz" )
54
54
self .num_channels = num_channels
55
55
56
56
def setup_csv (self ):
57
- if not self .csv_logging :
58
- return
57
+ if not self .csv_logging or self . csv_file :
58
+ return # Already set up or logging disabled
59
59
60
- timestamp = datetime .now ().strftime ("%Y%m%d_%H%M%S" )
61
- filename = f"ChordsPy{ timestamp } .csv"
62
- self .csv_file = open (filename , 'w' , newline = '' )
63
- headers = ['Counter' ] + [f'Channel{ i + 1 } ' for i in range (self .num_channels )]
64
- self .csv_writer = csv .writer (self .csv_file )
65
- self .csv_writer .writerow (headers )
66
- print (f"CSV logging started: { filename } " )
60
+ try :
61
+ timestamp = datetime .now ().strftime ("%Y%m%d_%H%M%S" )
62
+ filename = f"ChordsPy_{ timestamp } .csv"
63
+ self .csv_file = open (filename , 'w' , newline = '' )
64
+ headers = ['Counter' ] + [f'Channel{ i + 1 } ' for i in range (self .num_channels )]
65
+ self .csv_writer = csv .writer (self .csv_file )
66
+ self .csv_writer .writerow (headers )
67
+ print (f"CSV logging started: { filename } " )
68
+ except Exception as e :
69
+ print (f"Error setting up CSV logging: { str (e )} " )
70
+ self .csv_logging = False
67
71
68
72
def log_to_csv (self , sample_data ):
69
73
if not self .csv_logging or not self .csv_writer :
70
74
return
71
75
72
- self .sample_counter += 1
73
- row = [self .sample_counter ] + sample_data
74
- self .csv_writer .writerow (row )
76
+ try :
77
+ self .sample_counter += 1
78
+ row = [self .sample_counter ] + sample_data
79
+ self .csv_writer .writerow (row )
80
+ except Exception as e :
81
+ print (f"Error writing to CSV: { str (e )} " )
82
+ self .csv_logging = False
75
83
76
84
def connect_ble (self , device_address = None ):
77
- self .ble_connection = NPG_Ble ()
85
+ self .ble_connection = Chords_BLE ()
78
86
original_notification_handler = self .ble_connection .notification_handler
79
-
80
- def wrapped_notification_handler (sender , data ):
87
+
88
+ def notification_handler (sender , data ):
81
89
if len (data ) == self .ble_connection .NEW_PACKET_LEN :
82
- if not self .lsl_outlet :
90
+ if not self .lsl_connection :
83
91
self .setup_lsl (num_channels = 3 , sampling_rate = 500 )
84
92
self .setup_csv ()
85
- print ("BLE LSL stream started" )
86
93
87
94
original_notification_handler (sender , data )
88
95
@@ -96,25 +103,30 @@ def wrapped_notification_handler(sender, data):
96
103
]
97
104
self .last_sample = channels
98
105
self .ble_samples_received += 1
106
+
107
+ if self .lsl_connection : # Push to LSL
108
+ self .lsl_connection .push_sample (channels )
109
+ self .log_to_csv (channels ) # Log to CSV
99
110
100
- if self .lsl_outlet : # Push to LSL
101
- self .lsl_outlet .push_sample (channels )
102
- self .log_to_csv (channels ) # Log to CSV
103
-
104
- self .ble_connection .notification_handler = wrapped_notification_handler
105
-
106
- if device_address :
107
- self .ble_connection .connect (device_address )
108
- else :
109
- selected_device = asyncio .run (self .get_ble_device ())
110
- if not selected_device :
111
- return
112
- self .ble_connection .connect (selected_device .address )
113
-
114
- print ("BLE connection established. Waiting for data..." )
111
+ self .ble_connection .notification_handler = notification_handler
112
+
113
+ try :
114
+ if device_address :
115
+ print (f"Connecting to BLE device: { device_address } " )
116
+ self .ble_connection .connect (device_address )
117
+ else :
118
+ selected_device = asyncio .run (self .get_ble_device ())
119
+ if not selected_device :
120
+ return
121
+ print (f"Connecting to BLE device: { selected_device .name } " )
122
+ self .ble_connection .connect (selected_device .address )
123
+
124
+ print ("BLE connection established. Waiting for data..." )
125
+ except Exception as e :
126
+ print (f"BLE connection failed: { str (e )} " )
115
127
116
128
def connect_usb (self ):
117
- serial_connection = Serial_USB ()
129
+ serial_connection = Chords_USB ()
118
130
if serial_connection .detect_hardware ():
119
131
self .num_channels = serial_connection .num_channels
120
132
sampling_rate = serial_connection .supported_boards [serial_connection .board ]["sampling_rate" ]
@@ -125,21 +137,25 @@ def connect_usb(self):
125
137
original_read_data = serial_connection .read_data
126
138
def wrapped_read_data ():
127
139
original_read_data ()
128
- if hasattr (serial_connection , 'data' ) and self .lsl_outlet :
140
+ if hasattr (serial_connection , 'data' ) and self .lsl_connection :
129
141
sample = serial_connection .data [:, - 1 ]
130
- self .lsl_outlet .push_sample (sample )
142
+ self .lsl_connection .push_sample (sample )
131
143
self .log_to_csv (sample .tolist ())
132
144
133
145
serial_connection .read_data = wrapped_read_data
134
146
serial_connection .start_streaming ()
135
147
136
148
def connect_wifi (self ):
137
- self .wifi_connection = NPG_Wifi ()
149
+ self .wifi_connection = Chords_WIFI ()
138
150
self .wifi_connection .connect ()
139
151
140
152
self .num_channels = self .wifi_connection .channels
141
- self .setup_lsl (self .num_channels , self .wifi_connection .sampling_rate )
142
- self .setup_csv ()
153
+ sampling_rate = self .wifi_connection .sampling_rate
154
+
155
+ if not self .lsl_connection :
156
+ self .setup_lsl (self .num_channels , sampling_rate )
157
+ if self .csv_logging :
158
+ self .setup_csv ()
143
159
144
160
try :
145
161
print ("\n Connected! (Press Ctrl+C to stop)" )
@@ -158,10 +174,11 @@ def connect_wifi(self):
158
174
sample = int .from_bytes (block [offset :offset + 2 ], byteorder = 'big' , signed = True )
159
175
channel_data .append (sample )
160
176
161
- if self .lsl_outlet : # Push to LSL
162
- self .lsl_outlet .push_sample (channel_data )
163
- self .log_to_csv (channel_data ) # Log to CSV
164
-
177
+ if self .lsl_connection : # Push to LSL
178
+ self .lsl_connection .push_sample (channel_data )
179
+ if self .csv_logging and self .csv_writer : # Only log if CSV is set up
180
+ self .log_to_csv (channel_data )
181
+
165
182
except KeyboardInterrupt :
166
183
self .wifi_connection .disconnect ()
167
184
print ("\n Disconnected" )
@@ -190,7 +207,7 @@ def main():
190
207
elif args .protocol == 'ble' :
191
208
manager .connect_ble (args .ble_address )
192
209
except KeyboardInterrupt :
193
- print ("\n Disconnecting.. ." )
210
+ print ("\n Cleanup Completed ." )
194
211
except Exception as e :
195
212
print (f"Error: { str (e )} " )
196
213
0 commit comments