Ir para o conteúdo
Nspire

Pulse sensor with led or Buzzer

Mensagens Recomendadas

Nspire

Boa tarde pessoal.

Tenho os seguintes dois códigos que são referentes a um sensor de pulsação (são dois códigos distintos, não têm nada haver um com o outro). A minha intenção era meter um led a piscar ou um buzzer a tocar, sempre que o batimento cardíaco fosse por exemplo inferior a 50, mas sinceramente não o estou a conseguir fazer. Já perdi aqui bastantes horas com isto e não há maneira de conseguir.

Se alguém me conseguir ajudar, agradecia imenso!

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 = 512;             // 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
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

// 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 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! AQUI
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 = 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 = true;                     // when we get the heartbeat back
    }

sei();                                     // enable interrupts when youre done!
}// end isr


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
// UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,
// AND APPLY THAT VOLTAGE TO THE A-REF PIN
//analogReference(EXTERNAL);
}

void loop(){


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

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
}

// Pins
const int ledPin = 13;
const int sensePin = 0;

// LED blink variables
int ledState = LOW;
long ledOnMillis = 0;
long ledOnInterval = 50;
int ledsinal = 7;
// Hearbeat detect variables
int newHeartReading = 0;
int lastHeartReading = 0;
int Delta = 0;
int recentReadings[8] = {0,0,0,0,0,0,0,0};
int historySize = 8;
int recentTotal = 0;
int readingsIndex = 0;
boolean highChange = false;
int totalThreshold = 2;
// Heartbeat Timing
long lastHeartbeatTime = 0;
long debounceDelay = 150;
int currentHeartrate = 0;
void setup() {
// initialize the serial communication:
Serial.begin(9600);
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
pinMode (ledsinal, OUTPUT);
}
void loop() {
// Turn off LED
digitalWrite(ledPin, LOW);
// Read analogue pin.
newHeartReading = analogRead(sensePin);
//Serial.println(newHeartReading);
//Calculate Delta
Delta = newHeartReading - lastHeartReading;
lastHeartReading = newHeartReading;
// Find new recent total
recentTotal = recentTotal - recentReadings[readingsIndex] + Delta;
// replace indexed recent value
recentReadings[readingsIndex] = Delta;
// increment index
readingsIndex = (readingsIndex + 1) % historySize;
//Debug
//Serial.println(recentTotal);
// Decide whether to start an LED Blink.
if (recentTotal >= totalThreshold) {
// Possible heartbeart, check time
if (millis() - lastHeartbeatTime >= debounceDelay) {
// Heartbeat
digitalWrite(ledPin, HIGH);
currentHeartrate = 60000 / (millis() - lastHeartbeatTime);
lastHeartbeatTime = millis();
// Print Results
//Serial.println("Beat");
if (currentHeartrate <= 200) { Serial.println(currentHeartrate); } } } delay(10);

}

Editado por Rui Carlos
GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

Onde arranjaste os códigos?

Essa pessoa não te ajuda?


void loop() {
if (BPM > 50)
digitalWrite(fadepin, HIGH);
else
digitalWrite(fadepin, LOW);
delay (20);
}

Algo assim deve fazer o que pretendes... devo dizer que o código é estranho... por um lado é complexo, mas meter isso tudo dentro duma interrupção é esquisito.

Editado por bubulindo

include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Antes de mais, obrigado pelo comentário.

Esse código, o primeiro, está na página de onde comprei o sensor http://www.inmotion.pt/store/pulse-sensor

Já tinha tentado fazer isso que disseste e voltei novamente e sem sucesso. Meti com o led e com um buzzer e não dá.

Se mais alguém me conseguir ajudar, ficaria grato pois estou mesmo à rasca nisto.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

Mete aqui o código que tentaste...

O primeiro código com a alteração que fiz e com a função LedFadeToBeat comentada deve funcionar.

Se não funciona, que fizeste para ver onde está o problema?


include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Meti o primeiro código com o que tinhas dito, ficando como eu meti em baixo e não dá. O led de vez em quando pisca e outras vezes desliga, mas não me parece estar a dar bem, pois eu meto para ligar quando o BPM maior que 80 e ele liga na mesma, lendo as minhas pulsações que estão nos 60.

Já tentei com um buzzer, metendo +/- o mesmo código mas o resultado é o mesmo ...

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 = 512;			 // 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
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
// 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 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! AQUI
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 = 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 = true;					 // when we get the heartbeat back
 }
sei();									 // enable interrupts when youre done!
}// end isr

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
// UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,
// AND APPLY THAT VOLTAGE TO THE A-REF PIN
//analogReference(EXTERNAL);
}
void loop(){

ledFadeToBeat();
if (BPM > 80)
digitalWrite(fadePin, HIGH);
else
digitalWrite(fadePin, LOW);
delay(20);							 // take a break
}
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
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

com a função LedFadeToBeat comentada

Void loop (){

//ledFadeToBeat();

...

Como sabes que o BPM está correcto? Não vejo um unico serial.print com esse valor...

Editado por bubulindo

include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Meti agora a função em comentário e não dá na mesma.

Nessa página que meti a dizer de onde tirei o código, também tem lá o código para o processing. Código esse que abre uma janela e mostra o gráfico com o valor de BPM e vejo por aí ...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

O processing deve ser mágico... Estás-me a dizer que sem um único print no código, o teu computador sabe o que se passa no arduino???

Experimenta meter um serial.println(BPM); no loop para ver o que dá...


include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

Ambos os código são bastante diferentes... e claramente feitos por pessoas diferentes. Eu adaptei ambos para ligar um LED quando o batimento cardíaco passar dos 80.

No primeiro exemplo, adicionei um Serial.print para poderes fazer debug do que o código está a medir. Aquele if só falha se não tiveres a olhar para o led correcto ou se a variável BPM não estiver correcta.

O segundo exemplo tem exactamente a mesma condição, mas já que era esse que estavas a usar e supostamente a funcionar, provavelmente será mais simples de fazer com que funcione. Nota que tens de ter os LEDs nas portas correctas. Ambos os exemplos fazem uso de dois leds e eu não estou convencido que tu tenhas percebido isso.

Primeiro exemplo:

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 = 512;			 // 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
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
// 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 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! AQUI
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 = 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 = true;					 // when we get the heartbeat back
 }
sei();									 // enable interrupts when youre done!
}// end isr

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
// UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,
// AND APPLY THAT VOLTAGE TO THE A-REF PIN
//analogReference(EXTERNAL);
}
void loop(){

//ledFadeToBeat();
if (BPM > 50) {
digitalWrite(fadepin, HIGH);
} else {
digitalWrite(fadepin, LOW);
}
Serial.println(BPM); //DEBUG
delay(20);							 // take a break
}
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
}

Corre isto com o Serial Port aberto e diz o que aparece lá... ao passar de 80 no Serial Port o LED deve acender. Neste caso o LED é o pino 5. Certifica-te que tens lá um LED.

Segundo exemplo:

// Pins
const int ledPin = 13;
const int sensePin = 0;
// LED blink variables
int ledState = LOW;
long ledOnMillis = 0;
long ledOnInterval = 50;
int ledsinal = 7;
// Hearbeat detect variables
int newHeartReading = 0;
int lastHeartReading = 0;
int Delta = 0;
int recentReadings[8] = {0,0,0,0,0,0,0,0};
int historySize = 8;
int recentTotal = 0;
int readingsIndex = 0;
boolean highChange = false;
int totalThreshold = 2;
// Heartbeat Timing
long lastHeartbeatTime = 0;
long debounceDelay = 150;
int currentHeartrate = 0;

void setup() {
// initialize the serial communication:
Serial.begin(9600);
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
pinMode (ledsinal, OUTPUT);
}
void loop() {
// Turn off LED
digitalWrite(ledPin, LOW);
// Read analogue pin.
newHeartReading = analogRead(sensePin);
//Serial.println(newHeartReading);
//Calculate Delta
Delta = newHeartReading - lastHeartReading;
lastHeartReading = newHeartReading;
// Find new recent total
recentTotal = recentTotal - recentReadings[readingsIndex] + Delta;
// replace indexed recent value
recentReadings[readingsIndex] = Delta;
// increment index
readingsIndex = (readingsIndex + 1) % historySize;
//Debug
//Serial.println(recentTotal);
// Decide whether to start an LED Blink.
if (recentTotal >= totalThreshold) {
// Possible heartbeart, check time
if (millis() - lastHeartbeatTime >= debounceDelay) {
// Heartbeat
digitalWrite(ledPin, HIGH);
currentHeartrate = 60000 / (millis() - lastHeartbeatTime);
lastHeartbeatTime = millis();
// Print Results
//Serial.println("Beat");
if (currentHeartrate <= 200) { Serial.println(currentHeartrate); } } }
if (currentHeartrate > 50) {
digitalWrite(ledsinal, HIGH);
} else {
 digitalWrite(ledsinal, LOW);
}
delay(10);
}

Tem cuidado que o pino onde tens de ligar o LED é o 7!!!! Certifica-te que tens lá um LED.

Editado por bubulindo

include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Eu sei que ambos os programas têm de ter dois leds lol

Em ambos os casos, o led do pino 13 dá o batimento das minhas pulsações, mas o outro continua a não corresponder.

Quanto ao Serial.print, eu bem abro o Serial monitor mas aquilo não aparece lá nada :\

Edit: Aquilo do processing dá esta janela http://ram-e-shop.com/oscmax/catalog/images/images_big/sf11574_2.jpg

Editado por Nspire

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

E sabes onde e que os leds tem de estar?

Quando abres o serial monitor que baud rate e que colocas?? Os sketchs tem dois tipos de baud rate... Ajustas o baud para ambos?

Nos dois sketches que abres, que e que aparece no Serial Monitor? No segundo exemplo tem de aparecer algo no serial monitor (senao nao aparece no processing...)

Que e que sabes ao certo de microcontroladores ou do Arduino? Tu apenas dizes que nao funciona, mas nao trazes muita informacao para ajudar a perceber o que possa estar mal.

// Pins
const int ledPin = 13;
const int sensePin = 0;
// LED blink variables
int ledState = LOW;
long ledOnMillis = 0;
long ledOnInterval = 50;
int ledsinal = 7;
// Hearbeat detect variables
int newHeartReading = 0;
int lastHeartReading = 0;
int Delta = 0;
int recentReadings[8] = {0,0,0,0,0,0,0,0};
int historySize = 8;
int recentTotal = 0;
int readingsIndex = 0;
boolean highChange = false;
int totalThreshold = 2;
// Heartbeat Timing
long lastHeartbeatTime = 0;
long debounceDelay = 150;
int currentHeartrate = 0;
void setup() {
// initialize the serial communication:
Serial.begin(9600);
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
pinMode (ledsinal, OUTPUT);
}
void loop() {
// Turn off LED
digitalWrite(ledPin, LOW);
// Read analogue pin.
newHeartReading = analogRead(sensePin);
//Serial.println(newHeartReading);
//Calculate Delta
Delta = newHeartReading - lastHeartReading;
lastHeartReading = newHeartReading;
// Find new recent total
recentTotal = recentTotal - recentReadings[readingsIndex] + Delta;
// replace indexed recent value
recentReadings[readingsIndex] = Delta;
// increment index
readingsIndex = (readingsIndex + 1) % historySize;
//Debug
//Serial.println(recentTotal);
// Decide whether to start an LED Blink.
if (recentTotal >= totalThreshold) {
// Possible heartbeart, check time
if (millis() - lastHeartbeatTime >= debounceDelay) {
// Heartbeat
digitalWrite(ledPin, HIGH);
currentHeartrate = 60000 / (millis() - lastHeartbeatTime);
lastHeartbeatTime = millis();
// Print Results
//Serial.println("Beat");
if (currentHeartrate <= 200) {
Serial.println(currentHeartrate);
 if (currentHeartrate > 50) {
 digitalWrite(ledsinal, HIGH);
  } else {
 digitalWrite(ledsinal, LOW);
  }
} } }
delay(10);
}

E se for assim... o que podera estar a acontecer e a variavel currentHeartRate nem sempre ter valores correctos...


include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Antes de mais o que percebo de Arduino não é muito, pois este é o meu primeiro trabalho em Arduino. Posso dizer que sei o básico...

Quanto à montagem, está bem feita. Por exemplo para este código que meteste no último comentário, tenho um led ligado ao pino 13 que me vai dar os batimentos cardíacos e o outro led está ao pino 7 que deveria avisar quando o valor fosse menor ou maior que o que eu estipular.

Quanto ao Serial.print, ele não me aparece nada, não percebo porquê ... Fica-me assim http://tinypic.com/r/20h3m7p/8

Um colega já me tinha dito para fazer isso mas para outro valor e também não conseguia imprimir nada no serial monitor

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Não faço a mínima LOL

Eu abro o processing com o programa que consegues tirar daquela página. Nestes códigos eu tirei as linhas que faziam a comunicação com o processing, pois para o trabalho em si o processing não me interessa. Mas meto já em baixo o código completo a fazer comunicação com o processing...

Código do sensor:

/*
>> Pulse Sensor Amped 1.1 <<
This code is for Pulse Sensor Amped by Joel Murphy and Yury Gitman
   www.pulsesensor.com
   >>> Pulse Sensor purple wire goes to Analog Pin 0 <<<
Pulse Sensor sample aquisition and processing happens in the background via Timer 2 interrupt. 2mS sample rate.
PWM on pins 3 and 11 will not work when using this code, because we are using Timer 2!
The following variables are automatically updated:
Signal :    int that holds the analog signal data straight from the sensor. updated every 2mS.
IBI  :	  int that holds the time interval between beats. 2mS resolution.
BPM  :	  int that holds the heart rate value, derived every beat, from averaging previous 10 IBI values.
QS  :	   boolean that is made true whenever Pulse is found and BPM is updated. User must reset.
Pulse :	 boolean that is true when a heartbeat is sensed then false in time with pin13 LED going out.
This code is designed with output serial data to Processing sketch "PulseSensorAmped_Processing-xx"
The Processing sketch is a simple data visualizer.
All the work to find the heartbeat and determine the heartrate happens in the code below.
Pin 13 LED will blink with heartbeat.
If you want to use pin 13 for something else, adjust the interrupt handler
It will also fade an LED on pin fadePin with every beat. Put an LED and series resistor from fadePin to GND.
Check here for detailed code walkthrough:
http://pulsesensor.myshopify.com/pages/pulse-sensor-amped-arduino-v1dot1
Code Version 02 by Joel Murphy & Yury Gitman  Fall 2012
This update changes the HRV variable name to IBI, which stands for Inter-Beat Interval, for clarity.
Switched the interrupt to Timer2.  500Hz sample rate, 2mS resolution IBI value.
Fade LED pin moved to pin 5 (use of Timer2 disables PWM on pins 3 & 11).
Tidied up inefficiencies since the last version.
*/

//  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

// 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
  // UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,
  // AND APPLY THAT VOLTAGE TO THE A-REF PIN
  //analogReference(EXTERNAL);  
}

void loop(){
 sendDataToProcessing('S', Signal);	 // send Processing the raw Pulse Sensor data
 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
    sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix
    sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix
    QS = false;					  // reset the Quantified Self flag for next time   
 }

 ledFadeToBeat();

 delay(20);							 //  take a break
}

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
 }

void sendDataToProcessing(char symbol, int data ){
   Serial.print(symbol);			    // symbol prefix tells Processing what type of data is coming
   Serial.println(data);			    // the data to send culminating in a carriage return
 }

Interrupção:

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 = 512;			    // 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 = 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 = true;					 // when we get the heartbeat back
 }

 sei();									 // enable interrupts when youre done!
}// end isr

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

Desculpa, mas esta aqui uma confusao que nao da para entender.

Tu tinhas um ficheiro de codigo... agora vindo do nada apresentas dois...

Mete la este codigo do processing no Arduino e ve o que te aparece na porta serie... nota tambem que te falta uma parte de codigo que me parece importante nos codigos anteriores...

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
	    sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix
	    sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix
	    QS = false;								   // reset the Quantified Self flag for next time  
	 }

Mas vamos por partes. Mete la este codigo do processing, ve o que aparece na porta serie e mete aqui.


include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Vou tentar explicar-me melhor, para o caso de me ter explicado mal ...

Eu comprei o sensor e tirei os códigos desta página http://www.inmotion.pt/store/pulse-sensor onde diz "Arduino code" e "processing Sketch".

O ultimo código que meti no meu ultimo comentário, é o código original que está nessa página e que tu ou outra pessoa qualquer podem fazer download (vem dois ficheiros que ao abrir, abrem em abas separadas).

O código que meti logo no inicio do tópico, foi uma alteração onde eu fiz, onde retirei todo o código que ligava o código principal ao Processing, pois para o trabalho que estou a fazer, não preciso do processing para nada. Daí ter retirado esses excertos de código.

Dito isto, o código que uso para ver no processing o valor do BPM é o original (o ultimo que postei). mas mesmo a meter um Serial.print, não me aparece nada no serial monitor.

meti agora no código original, o que faz a ligação com o processing, a parte dos "if" com o serial.print e não dá nada na mesma :\

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Agora experimentei meter um programa daqueles básicos para ler e escrever usando o Serial Monitor e para meu espanto não dá nada. Escrevo lá na caixinha e meto "enter" mas não dá nada. De que será isto? Pelo menos nestes programas básicos devia aparecer algo ...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

Ou seja, fazer debug... ta quieto... mas mesmo assim... o codigo deveria alterar o estado do LED... no entanto, sem porta serie nao da para ver porque.

E diz-me uma coisa... tens a certeza absoluta que isto ja funcionou no teu Arduino?

Outra coisa... mete o exemplo da tabela ASCII no arduino para ver se funciona...


include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

Felizmente posso dizer que o problema está resolvido :) Andei uma semana e pouco à volta disto por uma parvoice.

O problema disto tudo estava não no código, mas sim no pc -.- Como desde sempre liguei o Arduino ao pc e ele reconhecia logo a placa, nunca tinha tido problema. Mas ontem tentei experimentar num outro pc, que não reconheceu o Arduino e tive de configurar as portas USB. Com isto, depois de já reconhecer o Arduino, o programa já funcionou ás mil maravilhas e até o serial Monitor funcionou bem.

Resumindo, tenho de configurar as portas USb no meu pc.

Desde já, obrigado bubulindo pelo tempo que perdeste aqui a tentar explicar-me, acredita que não foi em vão ;)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
bubulindo

Algo nao me cheira bem...

Experimentaste ontem noutro PC... e nos dias todos anteriores onde estavas a experimentar?

Ou seja... tudo isto porque nao configuraste a porta serie e nao te deste sequer ao trabalho de ver as indicacoes que o Arduino te dava quando fazias download e nao funcionava.

Eu acredito que seja em vao... isso e do mais obvio que existe, mas tu bateste sempre na mesma tecla que era o codigo que nao estava bem e que todas as tuas ligacoes estavam boas.

Enfim...


include <ai se te avio>

Mãe () {

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Nspire

O meu pc é um fixo, onde sempre liguei o Arduino e sempre foi logo reconhecido no pc. Todos os programas que usei até á data, davam perfeitamente. Este pelos vistos não deu e como também nunca tinha usado o Serial Monitor, nunca me tinha apercebido que não dava.

O outro pc que disse que experimentei, foi no portátil do meu primo. Liguei o cabo do Arduino e o portátil não reconheceu o dispositivo. Fui ao youtube ver como se configurava e lá o fiz e depois disso, nesse portátil já funcionava tudo direito.

Pode ser óbvio, mas como o meu pc sempre reconheceu o Arduino, eu nunca pensei que viesse a ser esse o problema.

Mas pronto, já está resolvido e obrigado pela ajuda.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.