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.