Salve, sto provando a leggere 3 segnali distinti generati da 3 ventole per determinare la loro velocita. Ho usato la funzione pulsein() per misurare la lunghezza sia del impulso positivo che negativo. Il codice sembra funzionare bene e la rilevazione dei giri funziona, ma randomicamente viene rilevato un picco di quest'ultimo su tutte e tre le ventole (Grafico).
Inizialmente attribuivo la problematica al pull-up interno di Arduino UNO, cosi ho deciso di toglierlo e riferire i segnali mediante dei resistori esterni. Il problema non si è risolto.
Ho quindi analizzato la forma d'onda in ingresso ai 3 pin digitali, il segnale è pulito non presenta rumore di nessun tipo.
Allora può essere un problema relativo al fatto che la funzione pulsein blocca il codice?
Direi proprio di si. pulsein lavora così e funziona bene fintantoché che gli impulsi tra due pin sono sufficientemente distanti. Prova con una sola ventola non dovresti avere alcuno problema.
Ricorda anche che le Serial.print() e compagnia si prendono tempo per inviare dati. Per tre tachimetriche ti servirebbero 3 ingressi INT0, INT1 e INT2 che ci sono solo sulla mega. In alternativa si può tentare con la UNO usando gli interrupt PIN CHANGED.
Potresti mettere un array ciclico di 20 elementi, fare continuamente la media ed escludere la lettura corrente se il valore non è entro il valore medio +/-30%.
Il fatto che la lettura diventa il doppio, però, mi fa pensare che ogni tanto perda il Ltime perché segue immediatamente l'altro pulseIn dell'Htime... Prova a leggere solo Htime (o solo Ltime) e moltiplicalo per due:
Potresti anche fare una prova mettendo un delay (200) fra ciascun pulseIn HIGH e il successivo pulseIn LOW, solo per capire se dipende dalla vicinanza delle due letture.
La cosa strana è che se leggo Htime, i valori che mi restituisce non sono quelli corretti ma del tutto errati.
Visto che il periodo Htime e Ltime sono identici non dovrebbero essere equivalenti le misure?
Credo sia un problema della funzione pulseIn() , comunque se leggo la semionda "negativa" non ho problemi. Il vero problema si verifica quando a uno dei due pin non viene collegato nessun segnale. Ho dei valori che vanno da + 60.000 a 0. Questa funzione non dovrebbe restituire 0 se non vi è nessun impulso?
@Maurotec
Scusa se rispondo solo ora. PulseIn restituisce valori corretti, se non fosse che di tanto in tanto restituisce 0 e questo è un grande problame per me. Credo che il problema sia legato proprio a quello di cui parlavamo prima, ovvero che la funzione in se è di tipo bloccante. Ho dato uno sguardo alla libreria PinCHANGEDInt che mi avevi mensionato, per avere interrupt interni su tutti i pin, ma non l'ho mai utilizzata onestamente. Dovrei scrivere delle funzioni separate per ognuna delle due ventole/pin?
Puoi darmi un idea del codice per misurare la velocità delle due ventole?
Grazie
Al momento non posso, non ricordo neanche come è fatta quella lib. Conosco i registri della MCU ATmega, ma prima di pensare a scrivere il codice sarebbe bene fare un analisi così da ricavare almeno in via teorica i valori che arduino dovrebbe restituire se il codice fosse corretto.
Supposizione:
Ad ogni giro di ventola questa emette un impulso positivo per poi tornare LOW, chiamo periodo il tempo tra due fronti di salita della onda quadra. allora l'impulso positivo è ampio periodo/2.
Se accumulo in un contatore questi impulsi nella unità di tempo di 1 secondo e il contatore ha valore 16, in 1 minuti (60 secondi) avrò 16 x 60 = 960 rpm. Questo vuole dire non potrò mai avere visualizzato 1000 rpm perché 1000 / 60 = 16,666666667, se si accetta questo errore si può procedere con gli interrupt. Al massimo mi posso aspettare che il contatore ha valore 17 x 60 = 1020 rpm.
Queste sono ipotesi mie non confermate, se li potessi confermare sapremmo cosa aspettarci e potrei anche pensare di usare micros() per aumentare la precisione, ma non ho la minima idea di quanti impulsi si presentano ogni secondo alla massima velocità della ventola.
Questa immagine riproduce l'andamento dei giri/min nel tempo di entrambe le ventole. Oscilla pò ma non è quello ad interessarmi. Mi interessa di più che spesso la rilevazione rpm mi resistituisce 0. In realtà è un funzione pulseIn che mi restituisce 0. Sia su una ventola che sull'altra
Ogni volta che i segnali della v1 o v2 vanno su, copi t1 o t2 in t, segni il nuovo tempo in t1 o t2 e poi calcoli la velocità: 60000000/t. Se noti cose strane, non calcolare la velocità se i valori non sono ragionevoli.