Introduction: 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

Step 1: 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.

Step 2: 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

Step 3: 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

Step 4: 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

Step 5: 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

Step 6: 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

Step 7: 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')

Step 8: 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.