Pages: [1]   Go Down
Author Topic: PWM in arduino  (Read 744 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am a newbie in arduino programming and constructed a circuit in order to measure GSR and Heart rate.
For heart rate measuring I used an algorithm and a circuit similar to pulsesensor.com.
The measuring of heart rate was not stable (sometimes it was functioning well and sometimes the values were very high). I tried to use PWM and the measuring seemed to be much more stable.
Could you explain to me if PWM can affect the way that the arduino is functioning?
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know what heart rate is but what is GSR - gun shot residue??  smiley-lol


Quote
Could you explain to me if PWM can affect the way that the arduino is functioning?
Could you explain how and why you used PWM?

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

GSR is Gavlanic Skin Response.

We used PWM for indication that heart beat has been found. We connected PWM to pin 11 and to ground.

It looks logical that PWM has no effect in the circuit but if we do not use PWM, the circuit does not get synchronize such well.



Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What are you using to read GSR?

Please post your code, it probably has a bug.

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
/*
This program reads data from the Pulse Sensor.
Serial Protocol initiates datastring with coded ascii character, ends each message with carriage return
We named the variable that holds the heart rate (BPM) after the group Quantified Self.
*/

// VARIABLES
unsigned long time;      // Holds current time for pulse rate calculation
unsigned long lastTime;  // Used for calculating time between beats
int Sensor;              // Holds current analog Sensor Reading
int lastSensor=0;          // Used to find waveform direction
int Peak;                // Holds value of peak in waveform
int Trough;              // Holds value of trough in waveform
int beats[10];           // Array to collect time between beats for calculating BPM
int beatCounter = 0;     // Used to hold position in beats array
int QuantifiedSelf;      // Used to hold the heart rate value (BPM)
int drop;                // Holds the amplitude of waveform
int Fade = 0;            // Fade variable will set PWM
int fadeRate = 10;       // when arduino finds a heartbeat, it will fade an LED on pin 11 (PWM)

boolean falling = false; // used to keep track of waveform direction

// PINS
int LED = 13;         // pin 13 LED blinks on each pulse
//int dimLED = 8;      // LED on pin 8 fades with each pulse gia elegxo me ton palmografo
int dimLED = 11;      // LED on pin 11 fades with each pulse
int PulseSensor = 1;  // Pulse Sensor purple wire connected to analog pin 5
int gsr_count=0;
 byte a=0;
int prevLoop;

void setup()
{
  pinMode(LED, OUTPUT);        // set the LED pins as outputs
  pinMode(dimLED, OUTPUT);    
 
  // baud rate:
  // I send: (worst case)
  // Q 1 0 0 \n             5-xar
  // A 0 0 0 \n             5-xar

  Serial.begin(57600);        // start the hardware serial block and set the baud rate

  lastTime = millis();         // initialize lastTime variable

}


void loop()
{
  //  USE WITH LED ON PIN 11 FOR FADE EFFECT
    Fade -= fadeRate;              // Fade variable set to 255 when heart beat is found
    Fade = constrain(Fade,0,191);  // these lines fade the LED
    analogWrite(dimLED,Fade);


    gsr_count++;
    if (gsr_count>=41) {  //41*17 approx 700mS
      gsr_count=0;
       a=analogRead(0);

    }
        //Code needs 16,47ms to run
        delay(16);
//Accuracy +- 1us - enough

//        digitalWrite(dimLED, HIGH);
Sensor = analogRead(PulseSensor);
delayMicroseconds(100);
Sensor += analogRead(PulseSensor);
delayMicroseconds(100);
Sensor += analogRead(PulseSensor);
delayMicroseconds(100);
Sensor += analogRead(PulseSensor);
//        digitalWrite(dimLED, LOW);
Sensor /= 4; //Low-pass Filtering
        Sensor=1023-Sensor; //
  
    
// KEEP TRACK OF THE DIRECTION OF THE WAVEFORM
    if (falling == false){                       // if the sensor values are rising
      if (Sensor < lastSensor-1){                  // if current reading is less than last reading - noise      
         falling = true;                         // a peak has been reached
        
         digitalWrite(LED,LOW);                  // turn off pin 13 LED
      }else if(Sensor > lastSensor){             // otherwise, if current reading is bigger, values are still rising
         Peak = Sensor;                          // record the next potential peak
         lastSensor = Sensor;                    // keep track of rising signal  
      }
    }
    if (falling == true){                        // if the sensor values are falling
      if (Sensor > lastSensor){                  // if current reading is bigger than last reading
        falling = false;                         // a trough has been reached
        drop = Peak - Trough;                    // difference = signal amplitude
        Peak = 0;                                // setting Peak to 0 here helps get rid of noise
// THIS IF STATEMENT IS HOW THE HEARTBEAT IS FOUND IN PULSE SENSOR WAVEFORM        
//my circuit amplify the signal to 1V, this means
//1V = 20% ADU = 204 ADU
        if (drop > 20 && drop <280){               // ignore noise in signal. adjust as needed
          timeBeat();                            // go work out the BPM
          digitalWrite(LED,HIGH);                // start pin 13 LED blink
          Fade = 191;
        }                
       }else if (Sensor < lastSensor){           // otherwise, if current reading is smaller weΚ»re still falling
         Trough = Sensor;                        // record the next potential trough      
         lastSensor = Sensor;                    // keep track of falling signal
       }  
      }
    
}// END VOID LOOP


void timeBeat(){
        time = millis();                          // take note of the current time
        beats[beatCounter] = time - lastTime;     // record miliseconds since the last pulse in beats array
        lastTime = time;                          // stay up to date!
        beatCounter ++;                           // move array pointer to next position in array
        if (beatCounter == 10){                   // if we've taken 10 readings, it's time to derive heart rate
          QuantifiedSelf = getBPM();              // go derive the heart rate
          Serial.print("A");                            //------for GSR
          Serial.print(a, BYTE);
          Serial.print("q");                      //send the heart rate to Processing sketch (or other)
          Serial.println(QuantifiedSelf);         // 'q' = heart rate
          
//          Serial.println(QuantifiedSelf, BYTE);
          beatCounter = 0;
        }
}// END OF timeBeat FUNCTION


// This function will return a value for heart rate (Beats Per Minute)
int getBPM(){
    int dummy;                          // used in sorting
    int mean;                           // used in averaging
    boolean done = false;               // clear sorting flag    
// this simple sorting routine will arrange values in the beat array from lowest to highest
    while(done != true){                
    done = true;
    for (int j=0; j<9; j++){           // simple swap sorts numbers from lowest to highest
      if (beats[j] > beats[j + 1]){     // sorting numbers here
        dummy = beats[j + 1];
        beats [j+1] = beats[j] ;
        beats[j] = dummy;
        done = false;
       }
     }
   }
// this FOR loop selects the longer beat time values to avoid incorrect heart rate readings
   for(int k=1; k<9; k++){              // exclude lowest and highest values from averaging
    mean += beats[k];                   // add beat times together
   }
   mean /=8;                            // averaging
   mean = 60000/mean;                   // devide 60 seconds by average pulse length
   return mean;                         // return beats per minute
}// END OF getBPM function
« Last Edit: January 11, 2012, 04:19:24 pm by paran » Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I can't see why PWM would change whether or not the code will detect heart rate. I'm not sure that your heartbeat detection method is a very effective way of doing it but, for sure, there's a bug. In getBPM() you need to initialize mean to zero:
Code:
    int mean = 0;                           // used in averaging
otherwise it is averaging the four readings plus a random value. It is possible that whatever you added to do PWM has changed what is on the stack when getBPM is called and this made it work better.

I've been browsing the web and came across some other code. Have you seen or tried either of these?
http://code.google.com/p/pulse-sensor/downloads/list?saved=1&ts=1324407501

See Step 1 for link to code. You'd have to extract the heartbeat detection part.
http://makeprojects.com/Project/Beating-Heart-Headband/1622/1

Pete



Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 627
Posts: 34246
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
We connected PWM to pin 11 and to ground.
PWM comes FROM pin 11, so I don't know what you mean.
Can you post a schematic please.
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1636
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
PWM comes FROM pin 11
There is that too! Thanks Grumpy_Mike  smiley-grin

Pete
Logged

Pages: [1]   Go Up
Jump to: