Mindwave Wheelchair
This project attempts to implement a device to control a wheelchair for paralyzed patients with an improved controlling method. The device should be able to move the wheelchair freely in anywhere under the control of the user and it is not required to predefine any map or path. An accurate and natural controlling method is provided, and the user can stop the wheelchair any time immediately to avoid risks or danger. This project is using a brainwave-reading cap to collect the EEG/EMG signal and send it to the Arduino UNO to control the movement of the wheelchair.
Supplies
Computer
Ultracortex "Mark IV" EEG Headset
Cyton Biosensing Board (8-channels)
Arduino UNO
Motor shield
DC Motors
Wires
EEG/EMG Signal Overview
Knowing EEG/EMG
The electroencephalogram (EEG) is a recording of the electrical activity of the brain from the scalp while electromyography (EMG) is a recording of the electrical activity of the muscle. We track these activities through wave patterns. Using small metal disks that measure potentials across the scalp or muscles, we are able to get a reading of the brain’s or muscles signals.
Assembling and Installing
Before starting the EEG/EMG monitoring we have to make sure every thing is prepared properly. in this project I used the Ultracortex "Mark IV" EEG Headset with Cyton Biosensing Board (8-channels) from OpenBCI this choice was under the advice of my doctor due to serval reasons:
- Open Source Hardware Certified.
- Can be used to sample brain activity (EEG), muscle activity (EMG), and heart activity (ECG).
- Arduino compatible.
- Communicates wirelessly.
Assembling the headset and installing the software
- Assembling the Ultracortex Mark IV EEG Headset
- Connecting the Cyton Biosensing Board (8-channels) to PC
- Downloading and installing the GUI
Setteing Up the GUI to Read EEG/EMG
Setting up the OpenGUI to connect to the CYTON
- Plug-in the USB CYTON dongle in the PC
- OpenGUI application (I'm using V 5.0.1)
- Main window there is a dropdown menu "System control panal"
- Then I connected to "CYTON (live)"
- Since I'm using the USB to communicate I chose "Serial"
- Session data to "OpenBCI"
- I have the 8 channel CYTON so I set the channel count to "8 channels"
- Auto connect if it's not working manually set the CYTON port and connect.
Setting the OpenGUI to stream and send data over LSL
- Notch "60Hz", Band Pass filter "7-13Hz", smoothing "on", and Gain "Body"
- Used the EMG widget to monitor EMG signals
- The network widget was used to setup streaming the EMG on LSL
First Attempt - Control 4 LEDs
In this attempt I succeed to control 4 LEDs using the OpenBCI cap and Arduino UNO.
Setup
- Arduino UNO connected to PC through USB.
- 4 LEDs (Green, red, yellow, and blue) to the Arduino UNO as diagram.
- OpenBCI GUI will stream and read with a Python code and send the Arduino UNO through serial port.
- Python and Arduino UNO code attached.
Video will show that I managed to control all 4 LED with channel 1-4
Second Attempt - Controlling 2W Robotic Car
In this attempt I succeed to control 2W robotic car.
Setup
- Arduino UNO connected to PC wireless through HC-05 bluetooth module diagram attached.
- Adafruit motor shield v2 connected to the Arduino UNO to control the 2W robotic car
- OpenBCI GUI will stream and read with a Python code and send to the Arduino UNO through serial port.
- Python and Arduino UNO code attached.
Video will show that I managed to control the 2W robotic car
Building the Miniature Wheelchair
To build a miniature wheelchair and keep it light in weight I had to carefully choose my materials
- Thin softwood boards "light and easy to cut"
- Natural sheep leather
- Craft glue
- Metal pins
- Sponge
- 2 x Swivel wheels
After that I installed
- Arduino UNO with Adafruit motor shield v2
- 2 x Battery holder
- 2 x Switches
- 2 x DC motors
- 2 x Plastic wheels
Final Product Demonstration
In this video we demonstrate the final product
Setup
- Headset
- Computer
- Miniature Wheelchair
Arduino (IDE) Code
#include <Wire.h> //This library allows you to communicate with I2C addresses #include <Adafruit_MotorShield.h> //Include Adafruit MotorShield libraries #include <SoftwareSerial.h> SoftwareSerial Bluetooth(2, 3); Adafruit_MotorShield AFMS = Adafruit_MotorShield(); Adafruit_DCMotor *myMotor1 = AFMS.getMotor(1); Adafruit_DCMotor *myMotor2 = AFMS.getMotor(2); int incomingByte; // variable to read serial data into void setup() { Bluetooth.begin(9600); AFMS.begin(); myMotor1->setSpeed(150); myMotor2->setSpeed(150); } void loop() { // check if there's incoming data if (Bluetooth.available() > 0) { // read the oldest byte in the buffer: incomingByte = Bluetooth.read(); if (incomingByte == 'F') { myMotor1->run(FORWARD); myMotor2->run(FORWARD); } if (incomingByte == 'R') { myMotor1->run(FORWARD); myMotor2->run(BACKWARD); } if (incomingByte == 'L') { myMotor1->run(BACKWARD); myMotor2->run(FORWARD); } if (incomingByte == 'B') { myMotor1->run(BACKWARD); myMotor2->run(BACKWARD); } if (incomingByte == 'S') { myMotor1->run(RELEASE); myMotor2->run(RELEASE); } }<strong><br></strong>
Python Code
"""Python Code""" from pylsl import StreamInlet, resolve_stream import time import serial # set up Arduino serial port - replace with the one you are using ser = serial.Serial('COM4', 9600) # resolve an EMG stream on the lab network and notify the user print("Looking for an EMG stream...") streams = resolve_stream('type', 'EEG') inlet = StreamInlet(streams[0]) # inlet_ch2 = StreamInlet(streams[1]) print("EMG stream found!") # initialize time threshold and variables for storing time time_thres = 500 prev_time = 0 flex_thres = 0.5 while True: samples, timestamp = inlet.pull_sample() # get EMG data sample and its timestamp curr_time = int(round(time.time() * 1000)) # get current time in milliseconds if ((samples[0] >= flex_thres) & (curr_time - time_thres > prev_time)): # if an EMG spike is detected from the left eyebrow muscles send 'F' prev_time = int(round(time.time() * 1000)) # update time ser.write(b'B') elif((samples[1] >= flex_thres) & (curr_time - time_thres > prev_time)): # if an EMG spike is detected from the right eyebrow muscles send 'R' prev_time = int(round(time.time() * 1000)) # update time ser.write(b'F') elif((samples[2] >= flex_thres) & (curr_time - time_thres > prev_time)): # if an EMG spike is detected from the left side of th jaw muscles send 'L' prev_time = int(round(time.time() * 1000)) # update time ser.write(b'L') elif((samples[3] >= flex_thres) & (curr_time - time_thres > prev_time)): # if an EMG spike is detected from the right side of th jaw muscles send 'B' prev_time = int(round(time.time() * 1000)) # update time ser.write(b'R') elif(curr_time - time_thres > prev_time): # if no spike is detected send 'S' prev_time = int(round(time.time() * 1000)) # update time ser.write(b'S')
Thank You Dr Jaber
Dr Jaber Al Yamany, we feel so truly lucky to have an adviser who shows all of the care, understanding, and patience that you do. Thank you for the project idea, the support ,the follow-up .....Thank you for everything.