PulseIn
PulseIn e’ il modo piu’ semplice per decodificare un canale PWM in ingresso, puo’ lavorare su qualunque PIN che possa essere utilizzato come INPUT . Il problema e’ che la funzione e’ blocking: mentre viene misurata la lunghezza dell’intervallo il processore non puo’ fare altro.
Quindi possiamo anticipare un blocco di circa 1.5ms (media tra il minimo di 1ms e il massimo di 2ms) ogni 20ms (se la TX manda un impulso a ~50Hz, la FRSky che sto utilizzando ha un periodo di 18ms ma puo’ essere impostata anche a 8ms).
Questo puo’ non avere un grosso effetto su dei lampeggi da 500ms ma e’ influente su dei FADE o ovviamente la lettura di altri eventuali INPUT! Una soluzione potrebbe essere di lanciare la lettura con una frequenza minore, ad es. 5 volte al sec puo’ essere adeguato per leggere un interruttore, vedi esempio di pulseIn con millis.
Soluzione migliore: utilizzare gli interrupts.
Lettura di un canale
/* Lettura di un canale servo della RX
Lettura tramite la funzione pulsein
Utilizzabile su qualunque PIN
Il codice e' blocking fin tanto che il segnale passa da RISE a FALL
quindi blocca per 1-2ms a ogni esecuzione.
Il segnale dalla rx dovrebbe essere ~50hz,
vedere questo sketch $_millis con lettura a intervalli programmabili.
*/
#include <common.h>
// Variabili
const byte chPin = 2 ; // PIN su cui e ' collegato il canale
unsigned int chIn = 1500; // Valore catturato
unsigned int chValue = 1500; // Valore computato
// Attenzione che pulsein e' blocking
// Variabili per autocalibrazione
int mid_point = 1500 ;
void setup () {
// Funzione relativa a calibrazione:
mid_point = calibraTrim ( chPin ) ;
Serial . begin ( 9600 ); // Warning : interrupts e serial potrebbero dare problemi
};
void loop () {
// Lettura canale
chIn = pulseIn ( chPin , HIGH , 25000 );
if ( chIn > 1000 && chIn < 2000 ) {
// Scartiamo valori fuori range , talvolta pero ' alcune RX
// hanno il minimo un po' sotto a 1000
chValue = chIn ;
};
// do something with chValue
Serial . print ( chIn );
Serial . print ( " > chValue= " );
Serial . print ( chValue );
Serial . print ( " - base: " );
Serial . println ( mid_point );
delay ( 200 );
}
Lettura di un canale con millis
/* Lettura di un canale servo della RX
Lettura tramite la funzione pulsein
Utilizzabile su qualunque PIN
Il codice e' blocking fin tanto che il segnale passa da RISE a FALL
quindi blocca per 1-2ms a ogni esecuzione. Con la variabile freq
si imposta ogni quanto fare una lettura.
*/
#define DEBUG
#include <common.h>
unsigned long currentMillis ; // timestamp reference per millis per tutto il loop
// Variabili
const byte chPin = 2 ; // PIN su cui e ' collegato il canale
long unsigned chStamp = 0; // Timestamp per
unsigned int chIn = 1500; // Valore catturato
unsigned int chValue = 1500; // Valore computato
unsigned int freq = 200 ; // Ogni quanti millisecondi leggere il valore
int mid_point = 1500; // Punto medio per calibrazione
// Attenzione che pulsein e' blocking
void setup () {
// Funzione relativa a calibrazione: per il throttle si puo ' evitare
mid_point = calibraTrim ( chPin ) ;
#ifdef DEBUG
Serial . begin ( 9600 ); // Warning : interrupts e serial potrebbero dare problemi
#endif
} ;
void loop () {
currentMillis = millis (); // Timestamp per tutto il loop
// Lettura ailerons channel ogni 200 ms
if ( currentMillis - chStamp >= freq ) {
chIn = pulseIn ( chPin , HIGH , 25000 );
if ( chIn != 0 && chIn > 1000 && chIn < 2000 ) {
// get only resonable values
chValue = chIn ;
chStamp = currentMillis ;
} ;
};
// do something with chValue
#ifdef DEBUG
Serial . print ( chValue );
Serial . print ( " - base: " );
Serial . println ( mid_point );
delay ( 200 );
#endif
}
Please enable JavaScript to view the comments powered by Disqus.