Skip to content

FFT Visualizer-Multiple EEG & FFT Visualization #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jun 20, 2025
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9c7d6a7
Connection timeout increase to 15 as wifi takes time to connect
PayalLakra May 10, 2025
f44cbb7
Serial Connection Disconnection issue resolved
PayalLakra May 10, 2025
8a1730b
Serial Connection Disconnection issue resolved
PayalLakra May 10, 2025
053fd6a
Merge branch 'new' of https://github.com/PayalLakra/Chords-Python int…
PayalLakra May 10, 2025
f269693
Updated UI for fft visualizer(Multi channels)
PayalLakra May 10, 2025
2d70312
UI is done
PayalLakra May 12, 2025
0388aaa
Remove not required things
PayalLakra May 12, 2025
9776489
Adding functionality- When an app is running then a green tick is sho…
PayalLakra May 12, 2025
00ba008
Opacity reduces when an app is running
PayalLakra May 12, 2025
ebbba0e
CSV Filename can't be editable when recording is On.
PayalLakra May 12, 2025
cde94b3
Toast for Recording started, Recording stopped added(also timeout inc…
PayalLakra May 12, 2025
409ea22
CSV Filename timer update regularly
PayalLakra May 12, 2025
44fb655
Disconnect toast added with colour green(white text)
PayalLakra May 12, 2025
5e98400
logging.txt file is created that logs all the errors with timestamp
PayalLakra May 13, 2025
b818ce2
Merge branch 'upsidedownlabs:main' into new
PayalLakra May 13, 2025
325362a
Updated Readme
PayalLakra May 13, 2025
090a55c
Merge branch 'new' of https://github.com/PayalLakra/Chords-Python int…
PayalLakra May 13, 2025
15dc4c2
Updated Readme
PayalLakra May 13, 2025
f4e16c1
Updated Readme
PayalLakra May 13, 2025
8ae4832
Worked but issue is(On 10 hz it shoes peak at 8 hz)
PayalLakra Jun 14, 2025
eddadf0
for testing only
PayalLakra Jun 17, 2025
ef34cee
Removed unnecessary files
PayalLakra Jun 18, 2025
e0604b5
Timestamp based approach for lsl
PayalLakra Jun 18, 2025
720c5e1
Update chords_ble in standard form
PayalLakra Jun 18, 2025
b406ebc
Updated FFT, that works fine with all ble,serial,wifi and also now th…
PayalLakra Jun 18, 2025
4f41625
Changing the sampling rate
PayalLakra Jun 19, 2025
8cf5ee4
Worked- Smoothing is donw only once after fft is calculated then the …
PayalLakra Jun 19, 2025
0aaf8db
Skip DC Component(1st value)
PayalLakra Jun 19, 2025
ae8c37b
Corrected number of channels
PayalLakra Jun 19, 2025
a9b8b9d
Remove unnecessary files
PayalLakra Jun 19, 2025
f92d4e2
Applying Counter based lsl stream approach to ensure lsl stream sends…
PayalLakra Jun 19, 2025
75e7c8d
Adding Comments
PayalLakra Jun 19, 2025
ba9951e
Merge branch 'main' of https://github.com/upsidedownlabs/Chords-Pytho…
PayalLakra Jun 19, 2025
8a0fbd6
Updated Readme
PayalLakra Jun 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Recorded data
*.csv

/logs/
logging.txt

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
255 changes: 95 additions & 160 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,175 +1,110 @@
# Chords - Python

Chords Python script is designed to interface with an Arduino-based bio-potential amplifier, read data from it, optionally log this data to CSV or stream it via the Lab Streaming Layer (LSL), and visualize it through a graphical user interface (GUI) with live plotting.

> [!NOTE]
> Flash Arduino code to your hardware from [Chords Arduino Firmware](https://github.com/upsidedownlabs/Chords-Arduino-Firmware) to use this python tool.

## Features

- **Automatic Arduino Detection:** Automatically detects connected Arduino devices via serial ports.
- **Data Reading:** Read data packets from the Arduino's serial port.
- **CSV Logging:** Optionally logs data to a CSV file.
- **LSL Streaming:** Optionally streams data to an LSL outlet for integration with other software.
- **Verbose Output:** Provides detailed statistics and error reporting, including sampling rate and drift.
- **GUI:** Live plotting of six channels using a PyQt-based GUI.
- **Invert:** Optionally Invert the signal before streaming LSL and logging
- **Timer:** Record data for a set time period in seconds.

## Requirements

- Python
- `pyserial` library (for serial communication)
- `pylsl` library (for LSL streaming)
- `argparse`, `time`, `csv`, `datetime` (standard libraries)
- `pyqtgraph` library (for GUI)
- `PyQt5` library
- `numpy` library

## Installation

1. Ensure you have latest version of Python installed.
2. Create Virtual Environment
A Python script for interfacing with bio-potential amplifiers, supporting data logging as CSV, LSL streaming, real-time visualization, and HCI/BCI applications.

> [!NOTE]
> **Firmware Required:**
> - For Arduino: [Chords Arduino Firmware](https://github.com/upsidedownlabs/Chords-Arduino-Firmware)
> - For NPG-Lite: [NPG-Lite Firmware](https://github.com/upsidedownlabs/npg-lite-firmware)

## Features
- **Multiple Protocols**: Supports `Wi-Fi`, `Bluetooth`, and `Serial` communication.
- **LSL Data Streaming**:Once the LSL stream starts, any PC on the same Wi-Fi network can access the data using tools like BrainVision LSL Viewer.
- **CSV Logging**: Save raw data with timestamps.
- **GUI**: Live plotting for 6 channels (PyQt-based).
- **Applications**: EEG/ECG/EMG/EOG-based games and utilities (e.g., Tug of War, Keystroke Emulator).

## Installation
1. **Python**: Ensure Latest version of Python is installed.
2. **Virtual Environment**:
```bash
python -m venv venv
```

python -m venv venv
source venv/bin/activate # Linux/macOS
.\venv\Scripts\activate # Windows
```
3. **Dependencies**:
```bash
.\venv\Scripts\activate
```

> [!IMPORTANT]
> You may get an execution policy error if scripts are restricted. To fix it, run:

> ```bash
> Set-ExecutionPolicy Unrestricted -Scope Process
> ```

3. Install the required Python libraries needed to run the python script:
```bash
pip install -r chords_requirements.txt
```

4. Install the required Python libraries needed to run the applications:
```bash
pip install -r app_requirements.txt
```

## Usage

To use the script, run it from the command line with various options:
```bash
python chords.py [options]
```
### Options

- `-p`, `--port` <port>: Specify the serial port to use (e.g., COM5, /dev/ttyUSB0).
- `-b`, `--baudrate` <baudrate>: Set the baud rate for serial communication. By default the script will first attempt to use 230400, and if that fails, it will automatically fallback to 115200.
- `--csv`: Enable CSV logging. Data will be saved to a timestamped file.
- `--lsl`: Enable LSL streaming. Sends data to an LSL outlet.
- `-v`, `--verbose`: Enable verbose output with detailed statistics and error reporting.
- `-t` : Enable the timer to run program for a set time in seconds.

### Example:
```bash
python chords.py --lsl -v --csv -t 60
```
- This command executes the Python script `chords.py`, initiates the LSL stream, enables verbose output, activates CSV logging, and sets a timer for 60 seconds:

### Data Logging

- **CSV Output**: The script saves the processed data in a CSV file with a timestamped name.
- The CSV file contains the following columns:
- `Counter`: The sample counter from the Arduino.
- `Channel1` to `Channel6`: The data values from each channel.

- **Log Intervals**: The script logs data counts every second and provides a summary every 10 minutes, including the sampling rate and drift in seconds per hour.

## Applications
Open another terminal and run an application. Ensure the LSL Stream is running first.

### Installation
Before running any application, install all dependencies with the following command:

```bash
pip install -r app_requirements.txt
```

### Available Applications

#### ECG with Heart Rate

- `python heartbeat_ecg.py`:Enable a GUI with real-time ECG and heart rate.

#### EMG with Envelope

- `python emgenvelope.py`: Enable a GUI with real-time EMG & its Envelope.

#### EOG with Blinks

- `python eog.py`: Enable a GUI with real-time EOG that detects blinks and mark them with red dots.

#### EEG with FFT

- `python ffteeg.py`: Enable a GUI with real-time EEG data with its FFT and band powers.

#### EEG Tug of War Game

- `python game.py`: Enable a GUI to play tug of war game using EEG Signal.

#### EEG Beetle Game

- `python beetle.py`: Enable a GUI for Beetle Game using EEG signal.

#### GUI

- `python gui.py`: Enable the real-time data plotting GUI.

#### EOG Keystroke Emulator

- `python keystroke.py`: On running, a pop-up opens for connecting, and on pressing Start, blinks are detected to simulate spacebar key presses.

#### CSV Plotter

- `python csv_plotter.py`: On running, a pop-up window opens with option to load a file, select a channel to plot, and then plot the data.

## Running All Applications Together in a Web-Interface

To run all applications simultaneously, execute:

```bash
python app.py
```

> [!NOTE]
> Before running, make sure to install all dependencies by running the command:
pip install -r requirements.txt
```

> [!IMPORTANT]
> On Windows, if scripts are blocked, run:
> ```powershell
> Set-ExecutionPolicy Unrestricted -Scope Process
> ```
## Usage
Run the script and access the web interface:
```bash
pip install -r app_requirements.txt
```

This will launch a Web interface. Use the interface to control the applications:

1. Click the `Start LSL Stream` button to initiate the LSL stream or `Start NPG Stream` button to initiate the NPG stream.
2. Then, click on any application button to run the desired module.
Important: Keep the `python app.py` script running in the background while using any application.

### Available Applications
- `ECG with Heart Rate`: Analyze ECG data and extract heartbeat metrics.
- `EMG with Envelope`: Real-time EMG monitor with filtering and RMS envelope.
- `EOG with Blinks`: Real-time EOG monitoring with blink detection.
- `EEG with FFT`: Real-time EEG analysis with FFT and brainwave power calculation.
- `EEG Tug of War`: A 2-player game where brain activity determines the winner in a battle of focus.
- `EEG Beetle Game`: Use your concentration to control a beetle's movement in this brain-powered challenge.
- `GUI of Channels`: Launch the GUI for real time signal visualization.
- `EOG Keystroke Emulator`: GUI for EOG-based blink detection triggering a keystroke.
- `CSV Plotter`: Plot data from a CSV file.
python app.py
```
**Web Interface Preview**:
![Web Interface Screenshot](media\Interface.png)
![Web Interface Screenshot](media\Webinterface.png)

### Key Options:

- **LSL Streaming**: Choose a protocol (`Wi-Fi`, `Bluetooth`, `Serial`).
- **CSV Logging**: Data saved as `ChordsPy_{timestamp}.csv`.
- **Applications**: Launch from the Interface (e.g., `EEG Tug of War`).

## Connection Guide

#### WIFI Connection
1. Upload the NPG-Lite WIFI Code to your device.
2. Connect to the device's WIFI network.
3. Click the **WIFI** button in the interface, then select **CONNECT**.
4. Once connected, the button will change to **Disconnect**, and a pop-up will confirm: *"Connected via Wifi!"*

#### Bluetooth Connection
1. Ensure Bluetooth is turned ON on your system.
2. Upload the Bluetooth code to your device.
3. Click the **Bluetooth** button to scan for available devices.
4. Select your device from the list and click **Connect**.
5. Once connected, the button will change to **Disconnect**, and a pop-up will confirm: *"Connected via Bluetooth!"*

#### Serial Connection
1. Ensure Bluetooth is OFF and the device is connected via USB.
2. Upload the required code to your hardware.
3. Click the **Serial** button, then select **Connect**.
4. Once connected, the button will change to **Disconnect**, and a pop-up will confirm: *"Connected via Serial!"*

## CSV Logging
To save sensor data for future analysis, follow these steps:
1. **Start Data Streaming** – Begin streaming data via **WiFi, Bluetooth, or Serial**.
2. **Start Recording** – Click the **Start Recording** button (it will change to **Stop Recording**).
3. **File Saved Automatically** – The data is saved as `ChordsPy_{timestamp}.csv` in your default folder.

- Visualizing CSV Data - You can plot the recorded data using the **CSV Plotter** tool.

## Applications
|----------------------------|------------------------------------------------------------------|
| Application | Description |
|----------------------------|------------------------------------------------------------------|
| **ECG with Heart Rate** | Real-time ECG with BPM calculation. |
| **EMG with Envelope** | Real-time EMG Visualization with Envelope. |
| **EOG with Blinks** | Real-time EOG Signal visualization with Blinks marked as Red Dot.|
| **EEG with FFT** | Real-time EEG Signal visualization with FFT and Brainpower bands.|
| **EEG Tug of War Game** | 2 Player EEG Based Game |
| **EEG Beetle game** | Real-time EEG focus based game. |
| **EOG Keystroke Emulator** | Blink detection triggers spacebar. |
| **GUI** | Visualize raw data in real-time |
| **CSV Plotter** | Tool to plot the recorded CSV Files |
|----------------------------|------------------------------------------------------------------|

## Troubleshooting

- **Arduino Not Detected:** Ensure the Arduino is properly connected and powered. Check the serial port and baud rate settings.
- **CSV File Not Created:** Ensure you have write permissions in the directory where the script is run.
- **LSL Stream Issues:** Ensure that the `pylsl` library is properly installed and configured. Additionally, confirm that Bluetooth is turned off.

## How to Contribute

You can add your project to this repo:

- Add a button in apps.yaml to link your application.
- Include your script as a .py file with LSL Data Reception code.
(Pull requests welcome!)

## Contributors

We are thankful to our awesome contributors, the list below is alphabetically sorted.
Expand Down
22 changes: 19 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import queue
import yaml
from pathlib import Path
import os

console_queue = queue.Queue()
app = Flask(__name__)
Expand All @@ -20,6 +21,22 @@
stream_active = False
running_apps = {} # Dictionary to track running apps

@app.route('/log_error', methods=['POST'])
def log_error():
try:
error_data = request.get_json()
if not error_data or 'error' not in error_data or 'log_error' in str(error_data):
return jsonify({'status': 'error', 'message': 'Invalid data'}), 400

os.makedirs('logs', exist_ok=True)

with open('logs/logging.txt', 'a') as f:
f.write(error_data['error'])

return jsonify({'status': 'success'})
except Exception as e:
return jsonify({'status': 'error', 'message': 'Logging failed'}), 500

def run_async(coro):
def wrapper(*args, **kwargs):
loop = asyncio.new_event_loop()
Expand Down Expand Up @@ -63,9 +80,8 @@ async def scan_ble_devices():

@app.route('/check_stream')
def check_stream():
if connection_manager and connection_manager.stream_active:
return jsonify({'connected': True})
return jsonify({'connected': False})
is_connected = connection_manager.stream_active if hasattr(connection_manager, 'stream_active') else False
return jsonify({'connected': is_connected})

@app.route('/check_connection')
def check_connection():
Expand Down
Loading