
EEG, PROCESSING AND ARDUINO VIA BLUETOOTH
FROM MIND TO THE MACHINE
As we did in previous sketches, we are going to use EEG data to control the speed of a DC motor by using PWM. But this time, we will remove the USB cable and use the Bluetooth connection to transfer the EEG data from Processing to Arduino.
Here is the Arduino code
/* Developed by Alis Design, March 2015 Revisited November 2017 www.alis.design based on the sketch developed by Guilherme “guibot” Martins Control your motors with L293D Sep, 2008 http://letsmakerobots.com/node/2074 */ #include <SoftwareSerial.h>// import the serial library SoftwareSerial B(4, 5); // RX, TX int motor_left[] = {2, 3}; int motor_right[] = {7, 8}; int motor_speed = 9; int BluetoothData; // the data given from Computer void setup() { B.begin(9600); Serial.begin(57600); // Setup motors for(int i = 0; i < 2; i++){ pinMode(motor_left[i], OUTPUT); pinMode(motor_right[i], OUTPUT); } pinMode(motor_speed,OUTPUT); } void loop() { if (B.available()){ BluetoothData=B.read(); if(BluetoothData>50){ analogWrite(motor_speed, BluetoothData); drive_forward(); } else{ motor_stop(); } } Serial.println(BluetoothData); } //================================= drive void motor_stop(){ digitalWrite(motor_left[0], LOW); digitalWrite(motor_left[1], LOW); digitalWrite(motor_right[0], LOW); digitalWrite(motor_right[1], LOW); delay(25); } void drive_forward(){ digitalWrite(motor_left[0], HIGH); digitalWrite(motor_left[1], LOW); digitalWrite(motor_right[0], HIGH); digitalWrite(motor_right[1], LOW); } void drive_backward(){ digitalWrite(motor_left[0], LOW); digitalWrite(motor_left[1], HIGH); digitalWrite(motor_right[0], LOW); digitalWrite(motor_right[1], HIGH); } void turn_left(){ digitalWrite(motor_left[0], LOW); digitalWrite(motor_left[1], HIGH); digitalWrite(motor_right[0], HIGH); digitalWrite(motor_right[1], LOW); } void turn_right(){ digitalWrite(motor_left[0], HIGH); digitalWrite(motor_left[1], LOW); digitalWrite(motor_right[0], LOW); digitalWrite(motor_right[1], HIGH); }
and the Processing code
/* Developed by Alis Design, March 2015 Revisited November 2017 www.alis.design based on the sketch developed by Guilherme “guibot” Martins Control your motors with L293D Sep, 2008 http://letsmakerobots.com/node/2074 based on the library developed by Andreas Borg http://crea.tion.to/ */ //================================= neurosky import neurosky.*; import org.json.*; ThinkGearSocket neuroSocket; int attention, meditation, delta, theta, low_alpha, high_alpha, low_beta, high_beta, low_gamma, mid_gamma, sig, blinkStrength; //================================= arduino and bluetooth import processing.serial.*; Serial port; int[] numbers = new int[10]; int BluetoothData; //================================= smoothing int numReadings = 300; int[] readings=new int[numReadings]; // the readings from the analog input int index = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average //================================= font PFont f; //================================= init void setup() { size(500, 500); for (int thisReading = 0; thisReading < numReadings; thisReading++) readings[thisReading] = 0; // initialize the font object f = createFont("Arial", 16, true); // Arial, 16 point, anti-aliasing on // use the serial device println(Serial.list()); port = new Serial(this, "/dev/tty.HC-06-DevB", 9600); // initialize the headset ThinkGearSocket neuroSocket = new ThinkGearSocket(this); try { neuroSocket.start(); } catch (Exception e) { println("Is ThinkGear running??"); } } void clearBackground() { background(40); } //================================= loop void draw() { clearBackground(); textFont(f, 180); // Specify font to be used fill(255); // Specify font color text(BluetoothData, width/2, height/2); // Display Text textAlign(CENTER); total= total - readings[index]; // subtract the last reading: readings[index] = attention; // read from the sensor: total= total + readings[index]; // add the reading to the total: index = index + 1; // advance to the next position in the array: // if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0; average = total / numReadings; // calculate the average: BluetoothData = floor(average * 2.55); // we are mapping the attention value (0-100) to (0-255) port.write(BluetoothData); delay(1); // delay in between reads for stability } //================================= neurosky functions void poorSignalEvent(int sigLevel) { sig=sigLevel; } void attentionEvent(int attentionLevel) { attention = attentionLevel; } void meditationEvent(int meditationLevel) { meditation = meditationLevel; } void blinkEvent(int blinkStrengthLevel) { blinkStrength = blinkStrengthLevel; } void eegEvent(int deltaLevel, int thetaLevel, int low_alphaLevel, int high_alphaLevel, int low_betaLevel, int high_betaLevel, int low_gammaLevel, int mid_gammaLevel) { delta = deltaLevel; theta = thetaLevel; low_alpha = low_alphaLevel; high_alpha = high_alphaLevel; low_beta = low_betaLevel; high_beta = high_betaLevel; low_gamma = low_gammaLevel; mid_gamma = mid_gammaLevel; } void rawEvent(int[] rawArray) { } void stop() { neuroSocket.stop(); super.stop(); }
In Processing, before sending the Attention Values to Arduino, we are smoothing the values so that the data that will be transferred to drive the DC motor will be cleared out from spikes that may affect the efficiency of the system.
https://vimeo.com/241054033
That is all for this sketch and we are going to proceed with creating some tangible devices using the information we gathered through these sketches.
Stay tuned…