1
+ import sys
2
+ from pylsl import StreamInlet , resolve_stream
3
+ import pyqtgraph as pg # For real-time plotting
4
+ from pyqtgraph .Qt import QtWidgets , QtCore # PyQt components for GUI
5
+ import numpy as np
6
+
7
+ # Initialize global variables
8
+ inlet = None
9
+ data = np .zeros ((6 , 2000 )) # Buffer to hold the last 2000 samples for each channel
10
+
11
+ def update_plots ():
12
+ global data
13
+ if inlet is not None :
14
+ # Pull multiple samples at once
15
+ samples , timestamps = inlet .pull_chunk (timeout = 0.0 , max_samples = 10 ) # Pull up to 10 samples
16
+
17
+ # Update data buffer
18
+ for sample in samples :
19
+ data = np .roll (data , - 1 , axis = 1 ) # Shift data left
20
+ data [:, - 1 ] = sample # Add new channel data to the right end of the array
21
+
22
+ # Update the curves with the new data
23
+ for i in range (6 ):
24
+ curves [i ].setData (data [i ])
25
+
26
+ def plot_lsl_data ():
27
+ global inlet
28
+ print ("Looking for LSL Stream." )
29
+ streams = resolve_stream ('name' , 'BioAmpDataStream' )
30
+
31
+ if not streams :
32
+ print ("No LSL Stream found." )
33
+ return
34
+
35
+ inlet = StreamInlet (streams [0 ])
36
+ init_gui ()
37
+
38
+ def init_gui ():
39
+ global plots , curves , app , win , timer , status_bar , lsl_label
40
+
41
+ app = QtWidgets .QApplication (sys .argv ) # Create the Qt application
42
+ win = QtWidgets .QWidget () # Create the main window
43
+ layout = QtWidgets .QVBoxLayout () # Create a vertical layout for the window
44
+ win .setLayout (layout ) # Set the layout to the window
45
+ win .setWindowTitle ("Real-Time Arduino Data" ) # Set the window title
46
+
47
+ pg .setConfigOption ('background' , 'w' ) # Background color
48
+ pg .setConfigOption ('foreground' , 'k' ) # Foreground color
49
+
50
+ # Create plots for each channel (6 in total)
51
+ global plots , curves
52
+ plots = []
53
+ curves = []
54
+ colors = ['#FF3B3B' , '#00FF66' , '#FF1493' , '#007BFF' , '#FFA500' , '#FF00FF' ] # Different colors for each channel
55
+ for i in range (6 ):
56
+ plot = pg .PlotWidget (title = f"Channel { i + 1 } " ) # Create a plot widget for each channel
57
+ layout .addWidget (plot ) # Add the plot to the layout
58
+ curve = plot .plot (pen = colors [i ]) # Create a curve (line) for plotting data
59
+ curve .setDownsampling (auto = True ) # Automatically downsample if needed
60
+ curve .setClipToView (True ) # Clip the data to the view
61
+ plots .append (plot ) # Store the plot
62
+ curves .append (curve ) # Store the curve
63
+
64
+ # Create a status bar at the bottom for displaying information
65
+ status_bar = QtWidgets .QHBoxLayout ()
66
+
67
+ # LSL status label
68
+ lsl_label = QtWidgets .QLabel ("LSL Status: Connected" )
69
+ status_bar .addWidget (lsl_label )
70
+
71
+ layout .addLayout (status_bar ) # Add the status bar to the layout
72
+
73
+ win .show () # Show the window
74
+
75
+ # Create a timer to update the plots every 1ms
76
+ timer = QtCore .QTimer ()
77
+ timer .timeout .connect (update_plots ) # Connect the update function to the timer
78
+ timer .start (10 ) # Start the timer with a 10ms interval
79
+
80
+ QtWidgets .QApplication .processEvents () # Process any pending events
81
+
82
+ if __name__ == "__main__" :
83
+ plot_lsl_data ()
84
+ sys .exit (app .exec_ ()) # Start the Qt application
0 commit comments