1
#define TIM2_EN() (TIMSK2 = 0x02)
#define TIM2_DIS() (TIMSK2 = 0x00)
//HEART SENSOR
// Include Libraries
#include "Arduino.h"
class PulseSensor
{
public:
 static void begin(int pulsePin);
 static volatile int BPM; // used to hold the pulse rate
 static volatile int Signal; // holds the incoming raw data
 static volatile int IBI; // holds the time between beats, must be seeded!
 static volatile boolean QS; // becomes true when Arduoino finds a beat.
};
// Pin Definitions
#define HEARTPULSE_PIN_SIG A0
// Global variables and defines
// object initialization
PulseSensor heartpulse;
volatile int rate[10]; // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0; // used to determine pulse timing
volatile unsigned long lastBeatTime = 0; // used to find IBI
volatile int P =512; // used to find peak in pulse wave, seeded
volatile int T = 512; // used to find trough in pulse wave, seeded
volatile int thresh = 512; // used to find instant moment of heart beat, seeded
volatile int amp = 100; // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true; // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false; // used to seed rate array so we startup with reasonable BPM
volatile boolean Pulse = false; // true when pulse wave is high, false when it's low
volatile int pulsePin;
volatile int PulseSensor::IBI = 600; // holds the time between beats, must be seeded!
volatile int PulseSensor::BPM; // used to hold the pulse rate
volatile int PulseSensor::Signal; // holds the incoming raw data
volatile boolean PulseSensor::QS = false; // becomes true when Arduino finds a beat
void PulseSensor::begin(int pPin)
{
 pinMode(pulsePin, INPUT);
 pulsePin = pPin;
 // Initializes Timer1 to throw an interrupt every 2ms.
 TCCR1A = 0x00;
 TCCR1B = 0x0C; // CTC (Compare match mode) and ClockIO/256
 OCR1A = 0x7C; // 2 ms
 TIMSK1 = 0x02;
 sei(); // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
// THIS IS THE TIMER 1 INTERRUPT SERVICE ROUTINE. 
// Timer 1 makes sure that we take a reading every 2 miliseconds
ISR(TIMER1_COMPA_vect)
{ // triggered when Timer1 counts to 124
 cli(); // disable interrupts while we do this
 PulseSensor::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(PulseSensor::Signal < thresh && N > (PulseSensor::IBI/5)*3){ // avoid dichrotic noise by waiting 3/5 of last IBI
 if (PulseSensor::Signal < T){ // T is the trough
 T = PulseSensor::Signal; // keep track of lowest point in pulse wave 
 }
 }
 if(PulseSensor::Signal > thresh && PulseSensor::Signal > P){ // thresh condition helps avoid noise
 P = PulseSensor::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 ( (PulseSensor::Signal > thresh) && (Pulse == false) && (N > (PulseSensor::IBI/5)*3) )
 { 
 Pulse = true; // set the Pulse flag when we think there is a pulse
 PulseSensor::IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
 lastBeatTime = sampleCounter; // keep track of time for next pulse
 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] = PulseSensor::IBI; 
 }
 }
 if(firstBeat){ // if it's the first time we found a beat, if firstBeat == TRUE
 firstBeat = false; // clear firstBeat flag
 secondBeat = true; // set the second beat flag
 sei(); // enable interrupts again
 return; // IBI value is unreliable so discard it
 } 
 // 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] = PulseSensor::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 
 PulseSensor::BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
 PulseSensor::QS = true; // set Quantified Self flag 
 // QS FLAG IS NOT CLEARED INSIDE THIS ISR
 } 
 }
 if (PulseSensor::Signal < thresh && Pulse == true){ // when the values are going down, the beat is over
 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 = 512; // 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 = false; // when we get the heartbeat back
 }
 sei(); // enable interrupts when youre done!
} // end isr
//LDR SENSOR
int sensorPin = A1; // select the input pin for LDR
int sensorValue = 0; // variable to store the value coming from the sensor
//LCD
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
//DHT
#include "dht.h"
int dht_apin = 2; 
dht DHT;
//HEART RATE SENSOR
unsigned long current_time,start_time=0;
int BPM,Interval;
void setup(){
 Serial.begin(115200);
 heartpulse.begin(HEARTPULSE_PIN_SIG);
 delay(1500);
 lcd.init(); // initialize the lcd 
 lcd.backlight();
 lcd.print(" INITIALISING");
 delay(2500);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" CHECKING HEART");
 lcd.setCursor(0,1);
 lcd.print(" RATE NOW......");
 delay(2000);
 lcd.clear();
}
void loop() {
 current_time = millis();
 if ( current_time-start_time < 30000 ) {
 BPM = heartpulse.BPM;
 Interval = heartpulse.IBI; 
 lcd.print(" SYNCHRONIZING ");
 lcd.setCursor(0,1);
 lcd.print(" BEATS:"); 
 lcd.print(BPM);
 lcd.clear();
 } else {
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("BEATS PER MINUTE");
 lcd.setCursor(6,1);
 lcd.print(BPM); 
 Serial.print(BPM);
 Serial.println('b');
 delay(4000);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" BEAT INTERVAL ");
 lcd.setCursor(7,1);
 lcd.print(Interval); 
 Serial.print(Interval);
 Serial.println('p');
 delay(4000);
 TIM2_DIS(); //Enable TIMER2 Interrupt
 DHT.read11(dht_apin); 
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" HUMIDITY ");
 lcd.setCursor(6,1);
 lcd.print(DHT.humidity);
 lcd.print("%");
 Serial.print(DHT.humidity);
 Serial.println('h');
 delay(4000);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" TEMPERATURE ");
 lcd.setCursor(5,1);
 lcd.print(DHT.temperature);
 lcd.print("C");
 Serial.print(DHT.temperature);
 Serial.println('t');
 TIM2_EN(); //Disable TIMER2 Interrupt
 delay(4000); 
 sensorValue = analogRead(sensorPin); // read the value from the sensor
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("LIGHT INTENSITY");
 lcd.setCursor(7,1);
 lcd.print(sensorValue);
 Serial.print(sensorValue);
 Serial.println('l');
 delay(4000);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" CHECKING HEART");
 lcd.setCursor(0,1);
 lcd.print(" RATE NOW......");
 delay(2000); 
 lcd.clear();
 start_time = millis();
 }
}

I am trying to run LDR,PULSE AND DHT11 sensor together. DHT11 was not giving out readings along with pulse sensor before so I searched stack exchange and found out this solution.

DHT11 and Pulse sensor incompatibility?

But now the problem is Arduino gets stuck at the line when I disable timer 2 interupt -

TIM2_EN(); //Disable TIMER2 Interrupt

Any solution?

asked Mar 23, 2019 at 19:20
8
  • 1
    are you sure that TIM2_EN() disables the interrupt? ...... what does TIM2_DIS() do? Commented Mar 23, 2019 at 19:43
  • 1
    I came up with this idea from here. arduino.stackexchange.com/questions/21489/… The code given in this works with this solution but my code is stuck and it is not even reading values from DHT Commented Mar 23, 2019 at 19:44
  • 1
    If i remove this line the code isn't stuck anymore- TIM2_EN(); //Disable TIMER2 Interrupt....But still Arduino is not able to read values from DHT11. Commented Mar 23, 2019 at 19:53
  • 1
    I do not know, can you explain in detail. Commented Mar 23, 2019 at 19:57
  • 1
    From Github I got this - TIMSK2 = 0x02; // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A. What can I do to read values from DHT11 and pulse sensor in the same program? Commented Mar 23, 2019 at 20:11

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.