كل يوم أقوم بنشر معلومة مفيدة أو فكرة جديدة أو نشاط جديد أو ابتكار . ستجد معلومات عن القراءة والكتابة والابتكارات والرياضة والطبيعة والزراعة وكل ماهو مفيد وجديد . ستجد معلومات عن طائرات الكوادكوبتر ومكوناتها وأحدث التقنيات الجديدة فى هذا المجال. This is my outlet to the world. Here I put new post everyday.

tank offer

Monday, April 23, 2018

How to make Galvanic Response Sensor with Arduino?

Today I found a Mind controlled quadcopter that is fully controlled by the power of thoughts with the NeuroSky headset and Arduino MKR1000 Board.

The project is very cool and thrilling.
It's definitely for quadcopter or Arduino haters. It actually needs a lot of work, patience and understanding.

Above all, it needs that you have the NeuroSky MindWave Headset(~$75) and MKR1000 Board(~$60) from Microsoft.

I've been searching all night about a way to make a simple and easy way to read mind signals (EKG Sensor) but without any result.

All circuits and sensors are complicated and very expensive.

Then I just stumpled upon the GSR (Galvanic Skin Response) which is typically the skin resistance variation in different times due to stress or fear.


I found that this sensor is faily simple and easy to make.

It is actually made of two simple electrodes to measure the skin resistance without the need for any amplifiers or filters as in any other biometric signal measurement.

With one lead sends current while the other measures the difference.

Arduino is used to measure the resistance at a 50 milliseconds intervals.

The results are sent to processing code to be displayed.

That's what I call an easy project.

So I've decided to include it here on my blog.


Code

Arduino Code:
void setup(){
  Serial.begin(9600); 
}

void loop(){
  int a=analogRead(0);
  if (Serial.available() > 0) {

    byte inbyte=Serial.read();
    if(inbyte=='a'){
      Serial.print(a,BYTE);


    }
  }
}
Processing Code:
import processing.serial.*;
Serial myPort;  

int hPosition = 1;     // the horizontal position on the graph
float currentReading;
float lastReading;
int count=0;
int zeroLinePos=0;

float gsrAverage,prevGsrAverage;
float baseLine=0;
long lastFlatLine=0;
color graphColor=color(255,255,255);
int baselineTimer=10000;
int gsrValue;
int gsrZeroCount=0;
float gsrRange=0;
int downhillCount=0;
int uphillCount=0;
boolean downhill;
boolean peaked=false;
float peak, valley;

void setup () {
  size(900, 450);
  // List all the available serial ports
  //println(Serial.list());

  myPort = new Serial(this, Serial.list()[0], 9600);
  currentReading=0;
  lastReading=0;
  gsrAverage=0;
  background(0);

  smooth();
}

void draw () {
  //best delay setting for gsr readings
  delay(50);
  //image(myMovie, 0, 0);

  if (gsrValue<15 &&gsrValue>-15){
    if( gsrZeroCount>10){
      currentReading=0;//flatline
      gsrAverage=0;
      baseLine=0;
      lastFlatLine=millis();
      gsrZeroCount=0;
      // println("reset");

    }
    gsrZeroCount++;
  }
  else{
    currentReading=gsrValue-baseLine;
    gsrZeroCount=0;
  }

  if(millis()-lastFlatLine>baselineTimer){
    baseLine=gsrAverage;
  }

  //graph colors
  if(gsrAverage>0 && gsrAverage<height/2.0*.25) graphColor=color(255,255,255);
  else if(gsrAverage>height/2.0*.25 && gsrAverage<height/2.0*.5) graphColor=color(255,250,100);
  else if(gsrAverage>height/2.0*.5 && gsrAverage<height/2.0*.75) graphColor=color(255,250,0);
  else if(gsrAverage>height/2.0*.75) graphColor=color(255,100,0);

  gsrRange=peak-valley;

  // at the edge of the screen, go back to the beginning:
  if (hPosition >= width) {
    hPosition = 0;

    //cover last drawing
    fill(0,200);
    noStroke();
    rect(0,0,width,height);
  }
  else {
    hPosition+=1;
  }

  gsrAverage=smooth(currentReading,.97,gsrAverage);

  //draw stuff

  //spike
  noStroke();
  if(gsrRange>200){
    fill(255);
    ellipse(10,10,20,20); 
  }
  else{
    fill(0);
    ellipse(10,10,20,20); 
  }

  //graph
  strokeWeight(.5);
  stroke(graphColor);
  line(hPosition-1, height/2.0-lastReading, hPosition, height/2.0-currentReading);
  stroke(255,0,100);
  line(hPosition-1,height/2.0-prevGsrAverage,hPosition,height/2.0-gsrAverage);

  //draw peaks
  int thres=7;

  noFill();
  stroke(255,0,0);
  strokeWeight(2);

  if (currentReading-thres>lastReading&& peaked==true){
    downhill=false;
    //println(downhillCount);
    uphillCount++;  
    downhillCount=0;
    point(hPosition-1, height/2.0-lastReading);
    valley=lastReading;
    peaked=false;

  }
  if(currentReading+thres<lastReading && peaked==false){
    //println(uphillCount);
    downhill=true;
    uphillCount=0;
    downhillCount++;
    point(hPosition-1, height/2.0-lastReading);
    peak=lastReading;
    peaked=true;
  }


  prevGsrAverage=gsrAverage;
  lastReading=currentReading;
  //send 'a' for more bytes
  myPort.write('a');
}


void serialEvent (Serial myPort) {
  int inByte=myPort.read();
  //0-255
  gsrValue=inByte;
}

void keyPressed(){
  if (keyCode==DOWN)zeroLinePos+=3;
  if (keyCode==UP)zeroLinePos-=3;

  strokeWeight(1);
  stroke(255,0,0);
  line(0,zeroLinePos,2,zeroLinePos);
}


int smooth(float data, float filterVal, float smoothedVal){
  if (filterVal > 1){      // check to make sure param's are within range
    filterVal = .99;
  }
  else if (filterVal <= 0){
    filterVal = 0;
  }
  smoothedVal = (data * (1 - filterVal)) + (smoothedVal  *  filterVal);
  return (int)smoothedVal;
} 

No comments:

Post a Comment