In this project, we will use the Hexabitz Single-Lead EXG Monitor Module (H2BR0) to capture muscle signal data and process it using an Arduino Uno. The goal is to create an easy-to-use and visually appealing bio-signal visualization tool.
Single-Lead, EXG Monitor (H2BR0x):Hexabitz Single-Lead, EXG Monitor Module (H2BR0) is one of a kind module that can record publication-grade biopotential signals from your body be it from the heart (ECG), brain (EEG), eyes (EOG), and muscles (EMG).
What makes it different?
- Record publication-quality biopotential signals like ECG, EMG, EOG, or EEG.
- Small size allows easy integration into mobile and space-constrained projects.
- H2BR0 is based on STM32G0 MCU.
- Program advanced C code with our easy-to-use APIs.
- You can connect to external hardware or combine with other Hexabitz modules!
- Check out this article for writing code with STM32CubeIDE.
The ExG module main code:
This code is designed for interfaces with an EMG sensor, reading muscle signals and transmitting them to a Raspberry Pi via serial communication ( It initializes the sensor, reads samples, and sends them to port P3) š
- The `UserTask` function is the main user-defined task.
- It initializes the EMG (Electromyography) sensor using `EXG_Init(EMG)`.
- Inside the infinite loop, we reads EMGsamples using `PlotToTerminal`.
- Connect the Hexabitz EXG Monitor Module to the TX/RX pins (digital pins 0 and 1) on the Arduino Uno.
- Connect the LEDs to the digital output pin (e.g., pin 6) on the Arduino Uno.
- Power the Arduino Uno using a USB cable or an external power supply.
- Open the Arduino IDE and create a new sketch.
- Initialize the serial communication in the
setup()
function with a baud rate of 921600.
- Read the incoming data from the Hexabitz EXG Monitor Module.
- Control the LEDs to visualize the signal strength.
- Use the Serial Plotter in the Arduino IDE to visualize the data in a graphical format
Code
int incomingByte = 0; // For incoming serial data
char buffer[64] = {0}; // Buffer to store received data
int bufferIndex = 0; // Index for buffer
const int ledPins[] = {2, 3, 4, 5, 6}; // Pins for LEDs
const int numLEDs = sizeof(ledPins) / sizeof(ledPins[0]); // Number of LEDs
void setup() {
Serial.begin(921600); // Set baud rate for serial communication
// Initialize LED pins as OUTPUT
for (int j = 0; j < numLEDs; j++) {
pinMode(ledPins[j], OUTPUT);
}
}
void loop() {
// Check if data is available on the Serial port
if (Serial.available() > 0) {
incomingByte = Serial.read(); // Read incoming byte
// Add byte to the buffer if it fits, or reset the buffer if it doesn't
if (bufferIndex < sizeof(buffer) - 1) {
buffer[bufferIndex++] = (char)incomingByte;
}
// If end of message is detected (newline character '\n')
if (incomingByte == '\n') {
buffer[bufferIndex] = '\0'; // Null-terminate the string
bufferIndex = 0; // Reset buffer index for next message
// Debug: Print the received message
// Serial.print("Received Message: ");
//Serial.println(buffer);
// Extract the last 4 bytes (60 to 63) and convert to numeric value
if (strlen(buffer) >= 63) { // Ensure the buffer contains at least 63 bytes
char extractedValue[5] = {0}; // 4 characters + null terminator
extractedValue[0] = buffer[60];
extractedValue[1] = buffer[61];
extractedValue[2] = buffer[62];
extractedValue[3] = buffer[63];
extractedValue[4] = '\0'; // Null-terminate the string
// Convert the extracted ASCII characters to a float
float sensorValue = atof(extractedValue);
// Debug: Print the extracted value
Serial.print("Extracted Sensor Value: ");
Serial.println(sensorValue);
// Map the sensor value to the number of LEDs to light up
int ledIndex = map(sensorValue, 0, 1, 0, numLEDs - 1); // Example range: 0.0 to 1.0
ledIndex = constrain(ledIndex, 0, numLEDs - 1); // Ensure the index is within range
// Control the LEDs based on the mapped value
for (int j = 0; j < numLEDs; j++) {
if (j <= ledIndex) {
digitalWrite(ledPins[j], HIGH); // Turn on LEDs
} else {
digitalWrite(ledPins[j], LOW); // Turn off LEDs
}
}
} else {
// Debug: Not enough data in the message
Serial.println("Message too short to process bytes 60 to 63.");
}
}
}
}
Explanation:
The code processes incoming serial data from the Hexabitz EXG Monitor Module to control the brightness of LEDs, providing a visual representation of the bio-signal's strength. It begins by initializing LEDs as output and setting up high-speed serial communication. As data arrives, it is stored in a buffer until the end of a message is detected. The last four bytes of the message are extracted as ASCII-encoded numerical values, converted to a floating-point number, and mapped to determine how many LEDs should light up. This mapping reflects the signal's strength, and the LEDs act as a visual indicator of the monitored bio-signal. The code handles shorter or invalid messages gracefully, ensuring reliability in its operation.
Summary of Functionality:
1. Reads data bytes from the serial port.
2. Buffers up to 63 bytes of data.
3. Combines the last 4 bytes (60-63) into a single value (`sensorValue`).
4. Uses `sensorValue` to determine how many LEDs should light up, mapping the sensor value to the number of LEDs.
5. Prints the combined sensor value to the serial monitor.
Project Testing š§ššThis project demonstrates how to capture and visualize bio-signals using the Hexabitz Single-Lead EXG Monitor Module and Arduino Uno. By visualizing the data with LEDs and Serial Plotter, we can create an effective bio-signal analysis tool.
Happy 20th Birthday to Arduino! š
Comments
Please log in or sign up to comment.