acquisizione segnale analogico e misurazione della frequenza

salve a tutti sono nuovo ed essendo alle prime armi con arduino duemilanove mi sono rivolto a voi.... ho acquistato questa scheda per rilevare il battito cardiaco attraverso il dito----->Introducing Easy Pulse: A DIY photoplethysmographic sensor for measuring heart rate | Embedded Lab
dovrei acquisire la tensione d'uscita con arduino e misurare la frequenza di questa in un determinato arco di tempo per poi calcolare la frequenza cardiaca.... dopodiche devo visualizzare il risultato su un display a 3 cifre ... potete darmi una mano? grazie in anticipo

carloandrea:
salve a tutti sono nuovo ed essendo alle prime armi con arduino duemilanove mi sono rivolto a voi.... ho acquistato questa scheda per rilevare il battito cardiaco attraverso il dito----->Introducing Easy Pulse: A DIY photoplethysmographic sensor for measuring heart rate | Embedded Lab
dovrei acquisire la tensione d'uscita con arduino e misurare la frequenza di questa in un determinato arco di tempo per poi calcolare la frequenza cardiaca.... dopodiche devo visualizzare il risultato su un display a 3 cifre ... potete darmi una mano? grazie in anticipo

...un passo alla volta... il sensore ti da già l'onda quadra: riesci a leggerla? hai attaccato bene il sensore?
se riesci a leggerla poi passiamo a come calcolare la frequenza...
però vedo un ostacolo all'orizzonte: display 3 cifre... di che tipo attaccato come?
in poche parole: quanto sei ferrato a livello di elettronica e quanto sei ferrato a livello di programmazione?

non è proprio un onda quadra ma l'arduino riesce comunque a leggerlo come treno di impulsi dagli ingressi digitali... il sensore funziona, l'unica cosa è la programmazione i display sono 3 a 7 segmento catodo comune, di cui uno dovra visualizzare solo il numero "1" poiche i battiti di una persona normale non arrivano a 200

nessuno puo aiutarmi?

ho fatto delle prove e i ho concluso che il segnale essendo simile ad un onda quadra viene letto anche in digitale

carloandrea:
ho fatto delle prove e i ho concluso che il segnale essendo simile ad un onda quadra viene letto anche in digitale

quindi sei a posto? vuoi sapere come si fa a calcolare la frequenza?

non proprio la frequenza, vorrei contare i battiti, gli impulsi, nell'arco di 15 secondi per poi moltiplicare il risultato per 4 in modo che mi escano fuori i battiti al minuto.... solo che con arduino sono alle prime armi e non riesco a scrivere il programma... la mia pseudo codifica sarebbe:

abilita il conteggio quando il pulsante sul pin x viene premuto
durata conteggio 15 sceondi
ogni impulso incrementa il contatore
alla fine dei 15 secondi si deve disattivare il conteggio e moltiplicare il risultato per 4
poi ci sarebbe da visualizzare su display la cifra ma magari piu in avanti, intanto ho imparato a leggere il monitor seriale percio posso provarlo con quello

c'è lo stesso programma ma scritto col pic...

/*
Project: Measuring heart rate through fingertip
Copyright @ Rajendra Bhatt
January 18, 2011
PIC16F628A at 4.0 MHz external clock, MCLR enabled
*/

sbit IR_Tx at RA3_bit;
sbit DD0_Set at RA2_bit;
sbit DD1_Set at RA1_bit;
sbit DD2_Set at RA0_bit;
sbit start at RB7_bit;
unsigned short j, DD0, DD1, DD2, DD3;
unsigned short pulserate, pulsecount;
unsigned int i;
//-------------- Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0xC0;
case 1 : return 0xF9;
case 2 : return 0xA4;
case 3 : return 0xB0;
case 4 : return 0x99;
case 5 : return 0x92;
case 6 : return 0x82;
case 7 : return 0xF8;
case 8 : return 0x80;
case 9 : return 0x90;
} //case end
}

void delay_debounce(){
Delay_ms(300);
}

void delay_refresh(){
Delay_ms(5);
}

void countpulse(){
IR_Tx = 1;
delay_debounce();
delay_debounce();
TMR0=0;
Delay_ms(15000); // Delay 1 Sec
IR_Tx = 0;
pulsecount = TMR0;
pulserate = pulsecount*4;
}

void display(){
DD0 = pulserate%10;
DD0 = mask(DD0);
DD1 = (pulserate/10)%10;
DD1 = mask(DD1);
DD2 = pulserate/100;
DD2 = mask(DD2);
for (i = 0; i<=180*j; i++) {
DD0_Set = 0;
DD1_Set = 1;
DD2_Set = 1;
PORTB = DD0;
delay_refresh();
DD0_Set = 1;
DD1_Set = 0;
DD2_Set = 1;
PORTB = DD1;
delay_refresh();
DD0_Set = 1;
DD1_Set = 1;
DD2_Set = 0;
PORTB = DD2;
delay_refresh();
}
DD2_Set = 1;
}

void main() {
CMCON = 0x07; // Disable Comparators
TRISA = 0b00110000; // RA4/T0CKI input, RA5 is I/P only
TRISB = 0b10000000; // RB7 input, rest output
OPTION_REG = 0b00101000; // Prescaler (1:1), TOCS =1 for counter mode
pulserate = 0;
j = 1;
display();
do {
if(!start){
delay_debounce();
countpulse();
j= 3;
display();
}
} while(1); // Infinite loop
}

prova questo... pinCardio = A0...
Dai un occhio al sistema di antirimbalzo ho messo 10ms... forse per il cuore sarebbe meglio mettere 100...
Si basa sul fatto che l'input è comunque digitale altrimenti bisogna sostituire il digitalread con l'analog e settare dei livelli di high e low.

prima dei 15 secondi sulla seriale non esce nulla ovviamente... e va di 15 in 15... che non mi piace tanto ma per il momento vedi se puoi digerirlo...

const int  CardioPin = A0;    
const int ledPin = 13;       

long oldMillis;
long oldMillis_antiBounce;

byte contatore = 0;
byte stato = 0;
byte ultimoStato = 0;


void setup() {

  pinMode(CardioPin, INPUT);
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
  oldMillis = millis();
  oldMillis_antiBounce = oldMillis;
  
}


void loop() {
  
  stato = digitalRead(CardioPin);
  if (stato != ultimoStato) {

    if (stato == HIGH) {
      //sistole...fronte di salita...
      digitalWrite(ledPin, HIGH);
      if ( millis()- oldMillis_antiBounce  > 10)
              {  // se impiega meno di 10 millisecondi per cambiare di stato è un rimbalzo e non lo conto
              contatore ++;
              oldMillis_antiBounce = millis();

              };
                    
      } else {
      // else stato = low significa che sono in diastole
              digitalWrite(ledPin, LOW);
     
      
    } 
    ultimoStato = stato;  // lo stato è variato
  }

   if ( millis()- oldMillis  > 15000) {
     //15 secodi di statistica... calcolo media
     Serial.print ("bpm:");
     Serial.println ( contatore * 4);
     contatore = 0;
     oldMillis = millis();
     oldMillis_antiBounce =      oldMillis;
     }

  
}

GRAZIE MILLLEEEEEE :smiley: apparentemente funziona, domani porto tutto il materiale a scuola e verifico il tutto ti faccio sapere grazie infinite ancora... appena torno da scuola scrivo qua :smiley:

@ qsecofr
Cosa serve un sistema antirimbalzo per un segnale creato elettronicamente?
@carloandrea
Puoi misurare il tempo tra 2 battiti e calcolarti in questo modo la frequenza cardiaca. Il vantaggio é che la misura é piú veloce.
Ciao Uwe

uwefed:
@ qsecofr
Cosa serve un sistema antirimbalzo per un segnale creato elettronicamente?
@carloandrea
Puoi misurare il tempo tra 2 battiti e calcolarti in questo modo la frequenza cardiaca. Il vantaggio é che la misura é piú veloce.
Ciao Uwe

ho letto distrattamente come era fatto il sensore: c'è il classico led trasmettitore ed il ricevitore e c'è un operazionale che amplifica questo segnale... chiaramente questo segnale è molto molto flebile di suo... non so se dentro avesse dispositivi per stabilizzare il segnale ma mi è parso di no...mi è parso che fosse abbastanza terra terra come sensore... al che ho pensato che il minimo movimento o il dito freddino potessero fare dei rimbalzi non corrispondenti al battito cardiaco....diremo che ho pensato più ad un filtro passa basso che ad un antirimbalzo.
eppoi siccome siamo tutti malati di cuore in famiglia potrebbero esserci dei casi di extrasistole: mettendo il ramo else sull'antirimbalzo ed un flag forse li becchiamo :grin:

allora il programma funge, l'unico problema è che alcune volte l'arduino non capta il segnale che il sensore capta(il led arduino non si accende mentre quello del sensore si), capita raramente ma capita.... sai da cosa puo dipendere?

carloandrea:
allora il programma funge, l'unico problema è che alcune volte l'arduino non capta il segnale che il sensore capta(il led arduino non si accende mentre quello del sensore si), capita raramente ma capita.... sai da cosa puo dipendere?

...significa che abbiamo un problema: io tutte le volte che vedo anche una minima variazione accendo o spengo coerentemente il led a prescindere dal codice di debounce.... evidentemente se c'è incoerenza significa che il segnale del sensore non è tanto quadrato come si credeva ed a volte da segnali sotto la soglia di accensione.
sostituisci il digitalread con un analogread... i test sull' HIGH falli come > 200 e sul low come < 100...vediamo cosa succede.... intanto vado a vedere meglio come ha costruito il coso.

ho riguardato il circuito.... c'è una fase iniziale di filtro che probabilmente rende inutile il mio filtro software: ma ormai c'è: teniamocelo.
Il led del sensore è attaccato prima del buffer che amplifica il segnale definitivamente.... potresti attaccare un led direttamente all'uscita del sensore con una resistenza per non bruciarlo che vediamo se è coerente?

ok domani provo
e ti faccio sapere

allora ho provato e il led che esce dal buffer è sincorno con il led che sta prima del buffer... com'è sta cosa che non prende alcuni battiti? alcune volte il led si accende poco e l'arduino non li prende... altre volte il led si accende del tutto e non li prende...

carloandrea:
allora ho provato e il led che esce dal buffer è sincorno con il led che sta prima del buffer... com'è sta cosa che non prende alcuni battiti? alcune volte il led si accende poco e l'arduino non li prende... altre volte il led si accende del tutto e non li prende...

allora significa che il segnale di input in realtà non è un vero 5 volt pulito come si pensava ma delle volte è meno. Fai questa sostituzione (pseudocodice)

int val = analogread(cardiopin)
if val >100
stato = HIGH
else
stato = LOW
endif

e poi continui... vediamo cosa esce: prelevo un segnale più basso...

a... sarebbe bello vedere anche come lo attacchi questo affare... ci sono resistenze di pulldown?

mm no ho collegato direttamente al pin di arduino l'ucita del sensore.... a che servono queste resistenze di cui parli?

carloandrea:
mm no ho collegato direttamente al pin di arduino l'ucita del sensore.... a che servono queste resistenze di cui parli?

dipenda un po' da che tipo di uscita hai da gestire. La prima cosa che ti invito a fare è gestire in analogica l'uscita di modo che se il segnale non è esattamente 5 volt lo becchiamo lo stesso.
Le resistenze di pulldown sono delle resistenze, di solito grandine, che si mettono tra il pin e massa: questo evita che eventuali disturbi possano alzare il pin... non sempre sono necessarie: sono necessarie ad esempio se metti un tasto... non so se servono: probabilmente non servono però va provato.