Arduino può leggere segnali sinusoidali con variazione di frequenza?

Buongiorno a tutti,

sto ordinando le idee circa il mio progettino. Vorrei inserire sul cruscotto del mio Scarabeo 200 un piccolo display (0802) che integri e migliori alcune info:

  • temperatura esterna;
  • data e ora;
  • voltmetro;
  • contagiri.

Per le prime tre funzioni penso di essere apposto, almeno sulla carta, mentre con il contagiri sono in alto mare.

Vi mostro il circuito di accensione del mio scooter. Come vedete esso è composto da un elettromagnete e da un volano sul quale è fissata una spina meccanica, che assieme ad un pick-up chiudono un circuito, generando un segnale sinusoidale a frequenza variabile. Tale segnale poi viene inviato ad una centralina CDI, poi ad un bobina AT, ed infine alla candela:

|500x407

Sfruttando questa formula meccanica:

F= (N. giri max x N.Cilindri)/120= (10000x1)/120=83.3 Hz

ottengo il valore della frequenza massima che assume il segnale in uscita dal pick-up in riferimento alla massima rotazione che il mio motore può raggiungere. Ossia 83.3 Hz.

Ora conoscendo il range di frequenza del segnale con cui avrò a che fare 0-83.3Hz posso in qualche modo, prelevarlo ed elaborarlo attraverso Arduino in modo che esso restituisca sul display un numero. Ad es. 7000 gir/min?

Grazie

Ciao, recentemente sto lavorando a qualcosa di parallelo e i primi problemi sono stati proprio il condizionamento del segnale in uscita dal pick-up, ricordati che arduino è una scheda digitale è gradisce segnali in un range di tensioni 0-5V magari discreti e con frequenza non maggiore alla metà della frequenza di clock. Che che tipo di sensore è quello sul tuo scooter? personalmente so che ne esistono di due tipi, quelli ad effetto hall che generano segnali 0-5V molto graditi da arduino e sensori a riluttanza variabile che generano segnali sinusoidale con ampiezza variabile non digeribili da arduino. Cmq se dal pick-up non è un effetto hall sicuramente devi creare un circuito di condizionamento per il segnale prima di passarlo ad arduino.

In mio scooter è abbastanza vecchiotto, per cui escludo l'utilizzo di un sensore ad effetto di Hall, anzi ne sono certo. Dal pick-up escono due fili, uno di massa e uno col segnale. Il segnale è di tipo analogico ad ampiezza fissa (forse non arriva neanche ad 1 Volt) ma frequenza variabile. L'aumento della frequenza è direttamente proporzionale all'aumento del numero di giri motore. In passato ho costruito un contagiri a 10 led usando l'integrato L2917-8N come converter F-V che poi pilotava un L3914N usato come driver per i 10 led.

Quindi in parole povere, se voglio usare questo segnale, devo squadrare il segnale sinusoidale e mandarlo poi in ingresso all'Arduino?

Potrebbe andar bene un trigger di schmidt con ne555? Tu come hai fatto? E poi arduino come può leggere questa variazione di frequenza? Non esistono moduli o shield appositi?

Grazie

Perfetto un trigger di schmidt è quello che ti serve, può essere implementato in tanti modi compreso il nostro amico ne555 ma lo trovo obsoleto e non performante per questa applicazione, io ho usato un LM393 che contiene due comparatori, con un comparatore puoi fissare una tensione di riferimento con un partitore resistivo e applicarla al pin non invertente poi il segnale in uscita dal pick-up lo applichi al pin invertente, l'uscita del comparatore cambia di stato (l'uscita varia da zero a VDD quindi per arduino devi alimentare il comparatore a 5V ) ogni volta che la tensione si trova al di sotto o sopra la tensione di riferimento. Appena riesci a condizionare il segnale o con il 555 o con i comparatori quello che devi usare per lo strak sono o gli interrupt o la pulseIn().

Dal pik up esce un segnale fatto in questo modo:

E' un segnale AC, deve essere raddrizzato, squadrato e condizionato 0-5 V prima di poterlo applicare ad un micro. Leggere la frequenza del segnale, in modo da ottenere gli rpm, non è un problema con Arduino, però eviterei l'uso della apposita libreria fcount perché lavora con il classico sistema del conteggio impulsi in tempo determinato, tipicamente 1 secondo, cosa che può andare benissimo in laboratorio, va male nel caso di un contagiri perché verrebbe aggiornato solo una volta al secondo e la risoluzione, in rpm, è scarsa sulle basse frequenze. Meglio optare per una misura basata sul periodo tra due impulsi consecutivi, fatta con pulsein, in modo da avere letture veloci che consentono un rapido aggiornamento del contagiri, rammento che 10.000 rpm sono solo 166,66 Hz.

Grazie mille ragazzi! Comincio ad avere le idee più chiare adesso.

Per la precisione la F=166.66 hz è per un motore 2T, mentre 83.3 hz è per uno a 4T.

Ok per il trigger. E se usassi il modulo PCF8591 come convertitore AC-DC, come la vedete?

Grazie

Meglio optare per una misura basata sul periodo tra due impulsi consecutivi, fatta con pulsein, in modo da avere letture veloci che consentono un rapido aggiornamento del contagiri, rammento che 10.000 rpm sono solo 166,66 Hz.

E' un ottima soluzione software

Non conosco il modulo PCF8591 :( ti direi di usare il comparatore perchè io ho fatto in questo modo e funziona ma sicuramente esistono altre soluzioni magari più efficaci. Googla un'altro po e fatti un idea in base ai componenti che già possiedi.

mario55: io ho usato un LM393 che contiene due comparatori, con un comparatore puoi fissare una tensione di riferimento con un partitore resistivo e applicarla al pin non invertente poi il segnale in uscita dal pick-up lo applichi al pin invertente, l'uscita del comparatore cambia di stato (l'uscita varia da zero a VDD quindi per arduino devi alimentare il comparatore a 5V ) ogni volta che la tensione si trova al di sotto o sopra la tensione di riferimento.

Potresti mostrarmi lo schema che hai usato tu con successo?

Grazie

|500x394 A parte la resistenza di retroazione da 20M che ho sostituito con una da 1M ho usato questo schema con un lm393. Sul terminale non invertente viene posta una tensione di riferimento a circa 0,5V con alimentazione 5V, che forse nel tuo caso sono pochi se dal pick-up la tensione non supera il volt, fai dei tentativi cambiando il valore delle resistenze che fungono da partitore per poter cambiare il riferimento.

Perfetto! Mi ritiro nelle mie stanze x riflettere e sperimentare. Grazie 1000!

Buongiorno a tutti,

in attesa di reperire i componenti che mi serviranno a condizionare il segnale proveniente dal pick-up, pensavo ad un ipotetico sketch che usi la funzione pulsein. Se ho capito bene, tale funzione serve a misurare il periodo di un’onda quadra con ampiezza 0-5v max.

Partendo da questa formula:

f=n.giri x n.cilindri/120*

*120 perchè il mio è un 4T altrimenti si usa 60 per un 2T.

ho pensato a questo codice:

int pin = 7;

int RPM;

unsigned long INpick-up;

void setup()

{

 pinMode(pin, INPUT);

}

void loop()

{

 INpick-up = pulseIn(pin, HIGH);
 RPM = [(1 / INpick-up)*120]*1.000.000.000; 

}

Ovviamente poi la variabile RPM la andrò a stampare sul LCD. Ma questa è un altra storia.

Secondo voi funziona?

Grazie

— NON usare i tag TABLE, usa i tag CODE per il codice. Ho corretto io il tuo post. - gpb01

Ho corretto la formula, ma nell'espressione dentro allo sketch, sono ammesse le parentesi quadre?

Grazie

NO, le parentesi quadre in 'C' si usano per altre cose (es. array) ... nelle formule sempre e solo tonde ;)

Guglielmo

Grazie Guglielmo, invece la compilazione dello sketch come ti sembra? Può funzionare?

In pulsein, il risultatto se non sbaglio è espresso in microsecondi, per semplificare i conti, conviene ragionare in millisecondi? Riporto il codice con le parentesi tonde:

int pin = 7;

int RPM;

unsigned long INpick-up;

void setup()

{

 pinMode(pin, INPUT);

}

void loop()

{

 INpick-up = pulseIn(pin, HIGH);
 RPM = ((1 / INpick-up)*120)*1.000.000.000; 

}

Grazie

Buonasera a tutti, forse di qua ero off topic http://forum.arduino.cc/index.php?topic=384287.0 cerco mi mettermi in regola :D :D...

In parole povere devo realizzare un contagiri per un motore monocilindrico a 4T. Il segnale lo prelevo dal pick-up lato BT e lo condiziono opportunamente con un comparatore.

Partendo da questa formula:

F=RPM x n.cilindri/120*

*120 per il 4T altrimenti si usa 60 per un 2T.

Sostituisco alla F l'equivalente 1/T per cui:

1/T=RPM x n.cilindri/120 perciò:

RPM= 1/T x 120

so che T è il periodo del mio segnale che la funzione pulsein misurerà, perciò abbozzo un codice:

int pin = 7;

int RPM;

unsigned long INpick-up;

void setup()

{

 pinMode(pin, INPUT);

}

void loop()

{

 INpick-up = pulseIn(pin, HIGH);
 RPM = ((1 / INpick-up)*120)*1.000.000.000; 

}

Come vi pare? Può funzionare?

Grazie

secondo me il - nel nome della variabile potrebbe causare problemi. poi secondo me misurerai 0 RPM costanti.

ma hai provato se compila?

Ciao Uwe

droidprova: Grazie Guglielmo, invece la compilazione dello sketch come ti sembra? Può funzionare?

In pulsein, il risultatto se non sbaglio è espresso in microsecondi, per semplificare i conti, conviene ragionare in millisecondi? Riporto il codice con le parentesi tonde:

int pin = 7;

int RPM;

unsigned long INpick-up;

void setup()

{

pinMode(pin, INPUT);

}

void loop()

{

INpick-up = pulseIn(pin, HIGH); RPM = ((1 / INpick-up)*120)*1.000.000.000;

}




Grazie

Ma hai provato di compilare lo sketch che metti?

sketch_mar08a.ino:20:30: error: too many decimal points in number
sketch_mar08a:5: error: expected initializer before '-' token
sketch_mar08a.ino: In function 'void loop()':
sketch_mar08a:19: error: 'INpick' was not declared in this scope
sketch_mar08a:19: error: 'up' was not declared in this scope

Mi sento preso per il ... perché non dimostri iniziativa e pensi che risolviamo tutti i tuoi problemi di mancanza di basi di programmazione.

Ciao Uwe

In effetti è vero il - ha dato problemi. Eliminato l'IDE ha compilato senza problemi.

Essendo il mio primo tentativo di programmazione, sono aperto a qualsisi consiglio.

Come posso quindi, migliorare il codice? Dove sbaglio e perché pensi che non avrò una lettura costante?

Ciao e grazie per avermi risposto.

droidprova: In effetti è vero il - ha dato problemi. Eliminato l'IDE ha compilato senza problemi.

Essendo il mio primo tentativo di programmazione, sono aperto a qualsisi consiglio.

Come posso quindi, migliorare il codice? Dove sbaglio e perché pensi che non avrò una lettura costante?

Ciao e grazie per avermi risposto.

I messaggi di errore sono chiari, prova a leggerli. Avrai una lettura costante perché leggi sempre zero. Ciao Uwe

@droidprova: Ti rammento che il cross-posting è proibito dal regolamento e tu stavi discutendo di questo argomento già in questo thread ... ... dato che uwe ti ha risposto NON ho chiuso il thread ed è stato fatto un "merge", ma in futuro, cortesemente, evita di aprire più thread relativi allo stesso argomento. Grazie.

Guglielmo