Skip to content

Commit 65cbd83

Browse files
authored
Merge pull request #18 from PayalLakra/bio_amptool
Timestamp in CSV & Raw EMG and EMG Envelope in different plots.
2 parents 5da009c + 591288b commit 65cbd83

File tree

3 files changed

+32
-18
lines changed

3 files changed

+32
-18
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Chords Python script is designed to interface with an Arduino-based bioamplifier
1717

1818
## Requirements
1919

20-
- Python 3.x
20+
- Python 3.10
2121
- `pyserial` library (for serial communication)
2222
- `pylsl` library (for LSL streaming)
2323
- `argparse`, `time`, `csv`, `datetime` (standard libraries)
@@ -27,12 +27,12 @@ Chords Python script is designed to interface with an Arduino-based bioamplifier
2727

2828
## Installation
2929

30-
1. Ensure you have Python 3.x installed.
30+
1. Ensure you have Python 3.10 installed.
3131
2. Create Virtual Environment
3232
```bash
3333
python -m venv venv
3434
```
35-
35+
3636
```bash
3737
.\venv\Scripts\activate
3838
```

applications/emgenvelope.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,25 @@ def __init__(self):
1313
self.setWindowTitle("Real-Time EMG Monitor with EMG Envelope")
1414
self.setGeometry(100, 100, 800, 600)
1515

16-
self.plot_widget = PlotWidget(self)
17-
self.plot_widget.setBackground('w')
18-
self.plot_widget.showGrid(x=True, y=True)
19-
16+
# Create layout
2017
layout = QVBoxLayout()
21-
layout.addWidget(self.plot_widget)
2218

19+
# Create plot widgets for raw EMG and EMG envelope
20+
self.raw_emg_plot = PlotWidget(self)
21+
self.raw_emg_plot.setBackground('w')
22+
self.raw_emg_plot.showGrid(x=True, y=True)
23+
self.raw_emg_plot.setTitle("Raw EMG Signal")
24+
25+
self.envelope_plot = PlotWidget(self)
26+
self.envelope_plot.setBackground('w')
27+
self.envelope_plot.showGrid(x=True, y=True)
28+
self.envelope_plot.setTitle("EMG Envelope")
29+
30+
# Add plots to layout
31+
layout.addWidget(self.raw_emg_plot)
32+
layout.addWidget(self.envelope_plot)
33+
34+
# Central widget
2335
central_widget = QWidget()
2436
central_widget.setLayout(layout)
2537
self.setCentralWidget(central_widget)
@@ -47,17 +59,20 @@ def __init__(self):
4759
self.rms_window_size = int(0.1 * self.sampling_rate)
4860

4961
# Set fixed axis ranges
50-
self.plot_widget.setXRange(0, 10, padding=0)
62+
self.raw_emg_plot.setXRange(0, 10, padding=0)
63+
self.envelope_plot.setXRange(0, 10, padding=0)
5164

52-
# Set y-axis limits based on sampling rate
65+
# Set y-axis limits based on sampling rate for raw EMG
5366
if self.sampling_rate == 250:
54-
self.plot_widget.setYRange(400,600 ,padding=0) # for R3 & ensuring no extra spaces at end
67+
self.raw_emg_plot.setYRange(-((2**10)/2), ((2**10)/2), padding=0) # for R3
68+
self.envelope_plot.setYRange(0, ((2**10)/2), padding=0) # for R3
5569
elif self.sampling_rate == 500:
56-
self.plot_widget.setYRange(400, 10000,padding=0) # for R4 & ensuring no extra spaces at end
70+
self.raw_emg_plot.setYRange(-((2**14)/2), ((2**14)/2), padding=0) # for R4
71+
self.envelope_plot.setYRange(0, ((2**14)/2), padding=0) # for R4
5772

5873
# Plot curves for EMG data and envelope
59-
self.emg_curve = self.plot_widget.plot(self.time_data, self.emg_data, pen=pg.mkPen('b', width=1))
60-
self.envelope_curve = self.plot_widget.plot(self.time_data, self.emg_data, pen=pg.mkPen('r', width=2))
74+
self.emg_curve = self.raw_emg_plot.plot(self.time_data, self.emg_data, pen=pg.mkPen('b', width=1))
75+
self.envelope_curve = self.envelope_plot.plot(self.time_data, self.emg_data, pen=pg.mkPen('r', width=2))
6176

6277
# Timer for plot update
6378
self.timer = pg.QtCore.QTimer()
@@ -79,11 +94,9 @@ def update_plot(self):
7994

8095
# Filter the EMG data
8196
filtered_emg = filtfilt(self.b, self.a, self.emg_data)
82-
# print(filtered_emg)
8397

8498
# Take absolute value before calculating RMS envelope
8599
abs_filtered_emg = np.abs(filtered_emg)
86-
# print(abs_filtered_emg)
87100

88101
# Calculate the RMS envelope
89102
rms_envelope = self.calculate_moving_rms(abs_filtered_emg, self.rms_window_size)

chords.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ def read_arduino_data(ser, csv_writer=None, inverted=False):
166166
channel_data.append(float(value)) # Convert to float and add to channel data
167167

168168
if csv_writer: # If CSV logging is enabled, write the data to the CSV file
169-
csv_writer.writerow([counter] + channel_data)
169+
current_timestamp = datetime.now().strftime('%H:%M:%S:%f') # Get the current timestamp
170+
csv_writer.writerow([current_timestamp, counter] + channel_data)
170171
if lsl_outlet: # If LSL streaming is enabled, send the data to the LSL stream
171172
lsl_outlet.push_sample(channel_data)
172173

@@ -229,7 +230,7 @@ def parse_data(ser, lsl_flag=False, csv_flag=False, verbose=False, run_time=None
229230
csv_file = open(csv_filename, mode='w', newline='') if csv_flag else None # Open CSV file if logging is
230231
if csv_file:
231232
csv_writer = csv.writer(csv_file) # Create CSV writer
232-
csv_writer.writerow(['Counter', 'Channel1', 'Channel2', 'Channel3', 'Channel4', 'Channel5', 'Channel6']) # Write header
233+
csv_writer.writerow(['Timestamp', 'Counter', 'Channel1', 'Channel2', 'Channel3', 'Channel4', 'Channel5', 'Channel6']) # Write header
233234

234235
end_time = time.time() + run_time if run_time else None
235236
send_command(ser, 'START')

0 commit comments

Comments
 (0)