Skip to content

Commit d8aa273

Browse files
committed
Adding 2 more boards support for chords
1 parent 14dfcf8 commit d8aa273

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

chords.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,22 @@
4747
previous_sample_number = None # Store the previous sample number for detecting missing samples
4848
missing_samples = 0 # Count of missing samples due to packet loss
4949
buffer = bytearray() # Buffer for storing incoming raw data from Arduino
50-
data = np.zeros((6, 2000)) # 2D array to store data for real-time plotting (6 channels, 2000 data points)
5150
samples_per_second = 0 # Number of samples received per second
5251
retry_limit = 4
5352

5453
# Initialize gloabal variables for Arduino Board
5554
board = "" # Variable for Connected Arduino Board
56-
supported_boards = {"UNO-R3":250, "UNO-R4":500} #Supported boards and their sampling rate
55+
supported_boards = {
56+
"UNO-R3": {"sampling_rate": 250, "Num_channels": 6},
57+
"UNO-CLONE": {"sampling_rate": 250, "Num_channels": 6},
58+
"UNO-R4": {"sampling_rate": 500, "Num_channels": 6},
59+
"RPI-PICO-RP2040": {"sampling_rate": 500, "Num_channels": 3},
60+
}
5761

5862
# Initialize gloabal variables for Incoming Data
59-
PACKET_LENGTH = 16 # Expected length of each data packet
6063
SYNC_BYTE1 = 0xc7 # First byte of sync marker
6164
SYNC_BYTE2 = 0x7c # Second byte of sync marker
6265
END_BYTE = 0x01 # End byte marker
63-
NUM_CHANNELS = 6 #Number of Channels being received
6466
HEADER_LENGTH = 3 #Length of the Packet Header
6567

6668
## Initialize gloabal variables for Output
@@ -69,6 +71,8 @@
6971
csv_filename = None # Store CSV filename
7072
csv_file = None
7173
ser = None
74+
packet_length = None
75+
num_channels = None
7276

7377
def connect_hardware(port, baudrate, timeout=1):
7478
try:
@@ -80,9 +84,13 @@ def connect_hardware(port, baudrate, timeout=1):
8084
response = ser.readline().strip().decode() # Try reading from the port
8185
retry_counter += 1
8286
if response in supported_boards: # If response is received, assume it's the Arduino
83-
global board
87+
global board, sampling_rate, data, num_channels, packet_length
8488
board = response # Set board type
8589
print(f"{response} detected at {port}") # Notify the user
90+
sampling_rate = supported_boards[board]["sampling_rate"]
91+
num_channels = supported_boards[board]["Num_channels"]
92+
packet_length = (2 * num_channels) + HEADER_LENGTH + 1
93+
data = np.zeros((num_channels, 2000)) # 2D array to store data for real-time plotting (num_channels, 2000 data points)
8694
if ser is not None:
8795
return ser # Return the port name
8896
ser.close() # Close the port if no response
@@ -114,24 +122,24 @@ def send_command(ser, command):
114122
def read_arduino_data(ser, csv_writer=None, inverted=False):
115123
global total_packet_count, cumulative_packet_count, previous_sample_number, missing_samples, buffer, data
116124

117-
max_value = 2**14 if board == "UNO-R4" else 2**10
125+
max_value = 2*10 if board == "UNO-R3" else 2*14
118126
min_value = 0
119127
mid_value = (max_value - 1) / 2
120128

121129
raw_data = ser.read(ser.in_waiting or 1) # Read available data from the serial port
122130
if raw_data == b'':
123131
send_command(ser, 'START')
124132
buffer.extend(raw_data) # Add received data to the buffer
125-
while len(buffer) >= PACKET_LENGTH: # Continue processing if the buffer contains at least one full packet
133+
while len(buffer) >= packet_length: # Continue processing if the buffer contains at least one full packet
126134
sync_index = buffer.find(bytes([SYNC_BYTE1, SYNC_BYTE2])) # Search for the sync marker
127135

128136
if sync_index == -1: # If sync marker not found, clear the buffer
129137
buffer.clear()
130138
continue
131139

132-
if len(buffer) >= sync_index + PACKET_LENGTH: # Check if a full packet is available
133-
packet = buffer[sync_index:sync_index + PACKET_LENGTH] # Extract the packet
134-
if len(packet) == PACKET_LENGTH and packet[0] == SYNC_BYTE1 and packet[1] == SYNC_BYTE2 and packet[-1] == END_BYTE:
140+
if len(buffer) >= sync_index + packet_length: # Check if a full packet is available
141+
packet = buffer[sync_index:sync_index + packet_length] # Extract the packet
142+
if len(packet) == packet_length and packet[0] == SYNC_BYTE1 and packet[1] == SYNC_BYTE2 and packet[-1] == END_BYTE:
135143
if(start_time is None):
136144
start_timer() # Start timers for logging
137145

@@ -150,7 +158,7 @@ def read_arduino_data(ser, csv_writer=None, inverted=False):
150158

151159
# Extract channel data (6 channels, 2 bytes per channel)
152160
channel_data = []
153-
for channel in range(NUM_CHANNELS): # Loop through channel data bytes
161+
for channel in range(num_channels): # Loop through channel data bytes
154162
high_byte = packet[2*channel + HEADER_LENGTH]
155163
low_byte = packet[2*channel + HEADER_LENGTH + 1]
156164
value = (high_byte << 8) | low_byte # Combine high and low bytes
@@ -174,7 +182,7 @@ def read_arduino_data(ser, csv_writer=None, inverted=False):
174182
data = np.roll(data, -1, axis=1) # Shift data to the left
175183
data[:, -1] = channel_data # Add new channel data to the right end of the array
176184

177-
del buffer[:sync_index + PACKET_LENGTH] # Remove the processed packet from the buffer
185+
del buffer[:sync_index + packet_length] # Remove the processed packet from the buffer
178186
else:
179187
del buffer[:sync_index + 1] # If the packet is invalid, remove only the sync marker
180188

@@ -202,7 +210,7 @@ def log_ten_minute_data(verbose=False):
202210
print(f"Total data count after 10 minutes: {cumulative_packet_count}") # Print cumulative data count
203211
sampling_rate = cumulative_packet_count / (10 * 60) # Calculate sampling rate
204212
print(f"Sampling rate: {sampling_rate:.2f} samples/second") # Print sampling rate
205-
expected_sampling_rate = supported_boards[board] # Expected sampling rate
213+
expected_sampling_rate = supported_boards[board]["sampling_rate"] # Expected sampling rate
206214
drift = ((sampling_rate - expected_sampling_rate) / expected_sampling_rate) * 3600 # Calculate drift
207215
print(f"Drift: {drift:.2f} seconds/hour") # Print drift
208216
cumulative_packet_count = 0 # Reset cumulative packet count
@@ -217,7 +225,7 @@ def parse_data(ser, lsl_flag=False, csv_flag=False, verbose=False, run_time=None
217225

218226
# Start LSL streaming if requested
219227
if lsl_flag:
220-
lsl_stream_info = StreamInfo('BioAmpDataStream', 'EXG', 6, supported_boards[board], 'float32', 'UpsideDownLabs') # Define LSL stream info
228+
lsl_stream_info = StreamInfo('BioAmpDataStream', 'EXG', num_channels, supported_boards[board]["sampling_rate"], 'float32', 'UpsideDownLabs') # Define LSL stream info
221229
lsl_outlet = StreamOutlet(lsl_stream_info) # Create LSL outlet
222230
print("LSL stream started") # Notify user
223231

@@ -230,7 +238,7 @@ def parse_data(ser, lsl_flag=False, csv_flag=False, verbose=False, run_time=None
230238
if csv_file:
231239
csv_writer = csv.writer(csv_file) # Create CSV writer
232240
csv_writer.writerow([f"Arduino Board: {board}"])
233-
csv_writer.writerow([f"Sampling Rate (samples per second): {supported_boards[board]}"])
241+
csv_writer.writerow([f"Sampling Rate (samples per second): {supported_boards[board]["sampling_rate"]}"])
234242
csv_writer.writerow([]) # Blank row for separation
235243
csv_writer.writerow(['Counter', 'Channel1', 'Channel2', 'Channel3', 'Channel4', 'Channel5', 'Channel6']) # Write header
236244

0 commit comments

Comments
 (0)