How to give delay between sensors
Moderators: adafruit_support_bill, adafruit

How to give delay between sensors

by cutie_lovely_92 on Sat Jan 05, 2013 1:08 pm

I am combining 2 sensors, and is confused how to put a delay, so sensor from A0 will first be used then sensor from A1 because in the setup function, they have different code.

So for the void setup():
/*for pulse sensor*/
pinMode(blinkPin,OUTPUT); // pin that will blink to your heartbeat!
pinMode(fadePin,OUTPUT); // pin that will fade to your heartbeat!
Serial.begin(115200); // we agree to talk fast!
interruptSetup(); // sets up to read Pulse Sensor signal every 2mS

/*used for temperature sensor*/
analogReference(INTERNAL);

for the void loop():
/*for pulse sensor*/
if (QS == true){ // Quantified Self flag is true when arduino finds a heartbeat
fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse
Serial.print("\n BPM = ");
Serial.print(BPM);
QS = false; // reset the Quantified Self flag for next time
}

ledFadeToBeat();
delay(20); // take a break

/*used for temperature sensor*/
int span = 20;
int aRead = 0;
for (int i = 0; i < span; i++) {
aRead = aRead+analogRead(potPin);
}
aRead = aRead / 20;
temperature = ((100*1.1*aRead)/1024)*10;
// convert voltage to temperature
Serial.print("Analog in reading: ");
Serial.print(long(aRead));
// print temperature value on serial monitor
Serial.print(" - Calculated Temp: ");
//xbee.print(" - Calculated Temp: ");
printTenths(long(temperature));

The complete code:
Code: Select all | TOGGLE FULL SIZE
//  VARIABLES
int pulsePin = 0;                 // Pulse Sensor purple wire connected to analog pin 0
int blinkPin = 13;                // pin to blink led at each beat
int fadePin = 5;                  // pin to do fancy classy fading blink at each beat
int fadeRate = 0;                 // used to fade LED on with PWM on fadePin
int potPin = 1;                   //LM35 connected to analog pin 1
float temperature = 0;            // temperature of the input
int BPMresult[9];

// these variables are volatile because they are used during the interrupt service routine!
volatile int BPM;                   // used to hold the pulse rate
volatile int Signal;                // holds the incoming raw data
volatile int IBI = 600;             // holds the time between beats, the Inter-Beat Interval
volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.


void setup(){
  pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
  pinMode(fadePin,OUTPUT);          // pin that will fade to your heartbeat!
  Serial.begin(115200);             // we agree to talk fast!
  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS   
  Serial.println("Pulse Rate and Body Temperature detector ");
  analogReference(INTERNAL);
}

void printTenths(int value) {
  // prints a value of 123 as 12.3
  Serial.print(value / 10);
  Serial.print(".");
  Serial.println(value % 10);
}

void loop(){
  if (QS == true){                       // Quantified Self flag is true when arduino finds a heartbeat
        fadeRate = 255;                  // Set 'fadeRate' Variable to 255 to fade LED with pulse
        Serial.print("\n BPM = ");
        Serial.print(BPM);
        QS = false;                      // reset the Quantified Self flag for next time   
     }
 
  ledFadeToBeat();
  delay(20);                             //  take a break
 
  int span = 20;
  int aRead = 0;
  for (int i = 0; i < span; i++) {
    aRead = aRead+analogRead(potPin);
  }
    aRead = aRead / 20;
    temperature = ((100*1.1*aRead)/1024)*10;
    // convert voltage to temperature
    Serial.print("Analog in reading: ");
    Serial.print(long(aRead));
    // print temperature value on serial monitor
    Serial.print(" - Calculated Temp: ");
    printTenths(long(temperature));
}

void ledFadeToBeat(){
    fadeRate -= 15;                         //  set LED fade value
    fadeRate = constrain(fadeRate,0,255);   //  keep LED fade value from going into negative numbers!
    analogWrite(fadePin,fadeRate);          //  fade LED
  }
Last edited by cutie_lovely_92 on Sun Jan 06, 2013 5:33 am, edited 1 time in total.
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by adafruit_support_rick on Sat Jan 05, 2013 2:15 pm

Where is the rest of the code for the pulse sensor? All you have of it is the (QS == true) test and a call to some interruptSetup function.

adafruit_support_rick
 
Posts: 13657
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: How to give delay between sensors

by cutie_lovely_92 on Sun Jan 06, 2013 5:32 am

driverblock wrote:Where is the rest of the code for the pulse sensor? All you have of it is the (QS == true) test and a call to some interruptSetup function.


Sorry forget to post the interrupt code. Here's the code:
Code: Select all | TOGGLE FULL SIZE
volatile int rate[10];                    // used to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find the inter beat interval
volatile int P =512;                      // used to find peak in pulse wave
volatile int T = 512;                     // used to find trough in pulse wave
volatile int thresh = 475;                // used to find instant moment of heart beat
volatile int amp = 100;                   // used to hold amplitude of pulse waveform
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = true;       // used to seed rate array so we startup with reasonable BPM


void interruptSetup(){     
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED     
}


// THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE.
// Timer 2 makes sure that we take a reading every 2 miliseconds
ISR(TIMER2_COMPA_vect){                         // triggered when Timer2 counts to 124
    cli();                                      // disable interrupts while we do this
    Signal = analogRead(pulsePin);              // read the Pulse Sensor
    sampleCounter += 2;                         // keep track of the time in mS with this variable
    int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise

//  find the peak and trough of the pulse wave
    if(Signal < thresh && N > (IBI/5)*3){       // avoid dichrotic noise by waiting 3/5 of last IBI
        if (Signal < T){                        // T is the trough
            T = Signal;                         // keep track of lowest point in pulse wave
         }
       }
     
    if(Signal > thresh && Signal > P){          // thresh condition helps avoid noise
        P = Signal;                             // P is the peak
       }                                        // keep track of highest point in pulse wave
   
  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
if (N > 250){                                   // avoid high frequency noise
  if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){       
    Pulse = true;                               // set the Pulse flag when we think there is a pulse
    digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
    IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
    lastBeatTime = sampleCounter;               // keep track of time for next pulse
         
         if(firstBeat){                         // if it's the first time we found a beat, if firstBeat == TRUE
             firstBeat = false;                 // clear firstBeat flag
             return;                            // IBI value is unreliable so discard it
            }   
         if(secondBeat){                        // if this is the second beat, if secondBeat == TRUE
            secondBeat = false;                 // clear secondBeat flag
               for(int i=0; i<=9; i++){         // seed the running total to get a realisitic BPM at startup
                    rate[i] = IBI;                     
                    }
            }
         
    // keep a running total of the last 10 IBI values
    word runningTotal = 0;                   // clear the runningTotal variable   

    for(int i=0; i<=8; i++){                // shift data in the rate array
          rate[i] = rate[i+1];              // and drop the oldest IBI value
          runningTotal += rate[i];          // add up the 9 oldest IBI values
        }
       
    rate[9] = IBI;                          // add the latest IBI to the rate array
    runningTotal += rate[9];                // add the latest IBI to runningTotal
    runningTotal /= 10;                     // average the last 10 IBI values
    BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
    QS = true;                              // set Quantified Self flag
    // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }                       
}

  if (Signal < thresh && Pulse == true){     // when the values are going down, the beat is over
      digitalWrite(blinkPin,LOW);            // turn off pin 13 LED
      Pulse = false;                         // reset the Pulse flag so we can do it again
      amp = P - T;                           // get amplitude of the pulse wave
      thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
      P = thresh;                            // reset these for next time
      T = thresh;
     }
 
  if (N > 2500){                             // if 2.5 seconds go by without a beat
      thresh = 475;                          // set thresh default
      P = 512;                               // set P default
      T = 512;                               // set T default
      lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date       
      firstBeat = true;                      // set these to avoid noise
      secondBeat = true;                     // when we get the heartbeat back
     }
 
  sei();                                     // enable interrupts when youre done!
}// end isr
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by adafruit_support_rick on Sun Jan 06, 2013 1:28 pm

I haven't tried to compile it, but it all looks OK. I don't think I understand the problem. Why do you need a delay?

adafruit_support_rick
 
Posts: 13657
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: How to give delay between sensors

by cutie_lovely_92 on Sun Jan 06, 2013 2:12 pm

driverblock wrote:I haven't tried to compile it, but it all looks OK. I don't think I understand the problem. Why do you need a delay?


Because somehow the analogReference(INTERNAL); which is used only in temperature sensor to used only 1.1V affected the result of the pulse sensor. So when I run the code, the pulse sensor shows number by itself when I haven't touch the sensors. So I am planing to just first let the temperature sensors measure the temperature then show some direction for user to put their fingers on the pulse sensor. May be in this way both sensors won't affect each others. But what's your opinion?
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by adafruit_support_rick on Sun Jan 06, 2013 2:42 pm

Alright. So, if I understand this correctly, you are trying to merge two separate programs - one that monitors a pulse sensor, and another that monitors a temperature sensor.

I'm guessing you merged the analogReference(INTERNAL) from the temperature sensor code?

And I'll also guess that there was no call to analogReference in the pulse sensor code?

If so, then this is the problem. Assuming you're using a Uno or equivalent and not an Arduino Mega, analogReference(INTERNAL) selects a 1.1V reference voltage for analog measurements. Your temperature sensor produces a voltage level that represents the temperature - a higher voltage means a higher temperature. when you call analogRead, the arduino compares the voltage level from the sensor with 1.1V, and gives you a number between 0 and 1023. A higher temperature means a higher voltage, and that results in a higher number.

Your code does a little bit of math to convert that number into a temperature.

This all works because the temperature sensor puts out a voltage between 0 and 1.1V

The pulse sensor does the very same thing. However, if my second guess is correct and there was no call to analogReference in the original pulse sensor code, then it is expecting to use the default analog reference voltage of 5V. So, the pulse sensor is producing voltages ranging somewhere between 0 and 5V.

So, lets assume that the pulse sensor puts out 1.0V to indicate that there is no pulse signal. The code expects analogRead to return (1023/5V) * 1.0V = 204 in that case.

But, with analog reference set to 1.1V, analogRead will actually return (1023/1.1V) * 1V = 930, which indicates a very strong pulse signal, instead of no pulse signal at all.

Next post: How to fix?

adafruit_support_rick
 
Posts: 13657
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: How to give delay between sensors

by cutie_lovely_92 on Sun Jan 06, 2013 2:56 pm

driverblock wrote:Next post: How to fix?


Yes, you are perfectly right. I am thinking of 2 solution but don't know which one is better and haven't try it out and need some input from a more experienced person since I am new to this.

1. To change the temperature sensor using 5v instead of 1.1v, cause in the case of 5v it will use 0 to 1023 while 1.1v will use 0 to 930.

2. I look through several source, it was said that:
Problems you may encounter with multiple sensors:
If, when adding more sensors, you find that the temperature is inconsistant, this indicates that the sensors are interfering with each other when switching the analog reading circuit from one pin to the other. You can fix this by doing two delayed readings and tossing out the first one

So I am wondering whether putting delay will solve the problem.
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by adafruit_support_rick on Sun Jan 06, 2013 3:05 pm

If all of my assumptions are valid, then you are going to have to get rid of the call to analogReference(INTERNAL) in order to make the pulse sensor work. You might be able to get away with switching the voltage reference between 1.1V and 5V, but the performance would probably be a bit unstable.

Instead, I think you should first try changing the temperature calculation to reflect the 5V reference voltage. This is easy to do, but it will reduce the resolution of your temperature readings. With the 1.1V reference, your resolution is about 0.1 degree. With the 5V reference, your resolution will be about 0.5 degree.

Give it a try. Delete the call to analogReference(INTERNAL), and change the temperature calculation to be like this:

Code: Select all | TOGGLE FULL SIZE
    aRead = aRead / 20;
    temperature = ((100*5.0*aRead)/1024)*10;   //substitute 5.0V reference for 1.1V reference


IMPORTANT: This all assumes you are using a Uno or other 5V ATmega328 arduino. If you are using something different, let me know and I'll tell you how to adjust for it.

adafruit_support_rick
 
Posts: 13657
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: How to give delay between sensors

by adafruit_support_rick on Sun Jan 06, 2013 3:08 pm

cutie_lovely_92 wrote:So I am wondering whether putting delay will solve the problem.


I don't think that's necessary. And, since you are reading the pulse sensor asynchronously (that is, in an interrupt), a delay would have no practical effect at all.

adafruit_support_rick
 
Posts: 13657
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: How to give delay between sensors

by cutie_lovely_92 on Sun Jan 06, 2013 3:27 pm

driverblock wrote:
IMPORTANT: This all assumes you are using a Uno or other 5V ATmega328 arduino. If you are using something different, let me know and I'll tell you how to adjust for it.


I am using arduino UNO R3.

I try like what u said, the result for temperature is right, but i think the pulse rate is too high
Code: Select all | TOGGLE FULL SIZE
 BPM = 238Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 59 - Calculated Temp: 28.8
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 64 - Calculated Temp: 31.2
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 59 - Calculated Temp: 28.8
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 59 - Calculated Temp: 28.8

 BPM = 238Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 59 - Calculated Temp: 28.8
Analog in reading: 64 - Calculated Temp: 31.2
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 62 - Calculated Temp: 30.2

 BPM = 238Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 59 - Calculated Temp: 28.8

 BPM = 238Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 58 - Calculated Temp: 28.3
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 62 - Calculated Temp: 30.2
Analog in reading: 59 - Calculated Temp: 28.8

 BPM = 238Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 59 - Calculated Temp: 28.8
Analog in reading: 63 - Calculated Temp: 30.7
Analog in reading: 59 - Calculated Temp: 28.8
Analog in reading: 61 - Calculated Temp: 29.7
Analog in reading: 60 - Calculated Temp: 29.2
Analog in reading: 61 - Calculated Temp: 29.7



I try printing only the BPM and it always increases to the max.
Code: Select all | TOGGLE FULL SIZE
Pulse Rate and Body Temperature detector

 BPM = 65
 BPM = 68
 BPM = 73
 BPM = 79
 BPM = 87
 BPM = 96
 BPM = 108
 BPM = 115
 BPM = 129
 BPM = 151
 BPM = 182
 BPM = 200
 BPM = 206
 BPM = 206
 BPM = 206
 BPM = 206
 BPM = 206
 BPM = 230
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 136
 BPM = 142
 BPM = 148
 BPM = 155
 BPM = 163
 BPM = 172
 BPM = 182
 BPM = 193
 BPM = 206
 BPM = 220
 BPM = 237
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
 BPM = 238
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by adafruit_support_rick on Sun Jan 06, 2013 3:47 pm

What processor was the pulse code written for originally? A beat is detected when the analog reading exceeds the value of "thresh", which is a constant set to 475.

This value may be calibrated for some reference voltage other than 5V. You're going to have to find the specs for the pulse sensor and figure out what the value of thresh should be for a reference voltage of 5V.

What is the Pin 13 LED doing? Is it flashing at a rate equivalent to 238 BPM?

adafruit_support_rick
 
Posts: 13657
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: How to give delay between sensors

by odometer on Sun Jan 06, 2013 3:58 pm

Arithmetic will show that a pulse rate of 238 bpm corresponds to 252 milliseconds per beat.

I see an interval of 250 milliseconds mentioned in your code. It seems that you are throwing out everything shorter than 250 milliseconds. I strongly suspect that your 238 bpm has something to do with this 250 milliseconds.

Perhaps your code for detecting heartbeats is detecting a beat when there is no beat.
odometer
 
Posts: 98
Joined: Sun Aug 21, 2011 11:01 pm

Re: How to give delay between sensors

by cutie_lovely_92 on Mon Jan 07, 2013 3:04 am

driverblock wrote:What processor was the pulse code written for originally? A beat is detected when the analog reading exceeds the value of "thresh", which is a constant set to 475.

This value may be calibrated for some reference voltage other than 5V. You're going to have to find the specs for the pulse sensor and figure out what the value of thresh should be for a reference voltage of 5V.

What is the Pin 13 LED doing? Is it flashing at a rate equivalent to 238 BPM?



I think the pulse code would apply for any Arduino UNO family microprocessor. I follow the instruction and use the code available in this website http://pulsesensor.myshopify.com/pages/code-and-guide. While for the thresh the original is 512 used for 5V, i browse through the internet and some said if the pulse sensor doesn't detect heart rate we should adjust the thresh until it detects continuously and that's what i did.

The Pin 13 LED and TX keeps blinking as long as i am putting my fingers on it, even in 238 BPM.
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by cutie_lovely_92 on Mon Jan 07, 2013 3:05 am

odometer wrote:Perhaps your code for detecting heartbeats is detecting a beat when there is no beat.


If this is the case, then whenever I didn't put my fingers on it it should still detects beat, but that doesn't happened.
cutie_lovely_92
 
Posts: 21
Joined: Fri Jan 04, 2013 3:59 am

Re: How to give delay between sensors

by odometer on Mon Jan 07, 2013 3:11 am

But still, it seems that your code is overzealous in detecting heartbeats.

Maybe your "threshold" is too low.
odometer
 
Posts: 98
Joined: Sun Aug 21, 2011 11:01 pm