L’aereo di Cirso: in questo aereo il comportamento delle luci e’ e predeterminato (non dipende da nessun inupt ) ma e’ stato abilitato un interruttore della radio per accendere e spegnere le luci.
L’interruttore a due stati e’ gestito da un interrupt.
In un primo esempio questo e’ un semplice ON/OFF impostato con un ciclo if , nel secondo invece viene implementata una FSM (macchina a stati) per gestire anche le transizioni tra i vari stati.
ON / OFF
/* Aereo di Cirso
Output:
2 LED ai lati con lampeggio alternato
1 LED in coda lampeggio a freq doppia
Input:
1 interruttore su interrupt 0 per accensione / spegnimento luci
Note :
Realizzato con un semplice ciclo IF per ON / OFF ,
lo sketch successsivo ha un macchina a stati per gestire
la transizione ON <-> OFF con una dissolvenza .
* /
#include <common.h>
// Variabili per interrupt 0
volatile unsigned int chValue = 1500 ; // Valore computato
volatile unsigned int chStart = 1500 ; // Inizio rilevamento
// Instanziamo un LED fuori dal loop
Lampeggiatore left = 5 ;
Lampeggiatore right = 6 ;
Lampeggiatore coda = 9 ;
void setup () {
// I PINs vengono impostati dal constructor al momento
// della dichiarazione dell 'ogetto.
attachInterrupt(0, chRise, RISING); // PIN 2 su 328p / 168
right.Invert() ; // Opzionale: inverte l' ordine del lampeggio da
// HI -> LOW --> LOW -> HI
// per avere 2 LED che lampeggiano alternativamente
}
void loop () {
if ( chValue > 1500 ) {
left . Blink (); // Lampeggia con un default di 1 sec ( 0 . 5 HI 0 . 5 LOW )
right . Blink ();
coda . Blink ( 1000 ); // Lampeggio in 1000 ms = 1 secondo
} else {
// sarebbe carino mettere una transizione da on -> off con un fade down . . .
left . Low ();
right . Low ();
coda . Low ();
} ;
}
// Functions
void chRise () {
attachInterrupt ( 0 , chFall , FALLING );
chStart = micros ();
};
void chFall () {
attachInterrupt ( 0 , chRise , RISING );
chValue = micros () - chStart ;
};
FSM
C’e’ una transizione tra gli stati On <-> Off: una dissolvenza in PWM a salire e a scendere quando si accende e si spegne le luci.
/* Cirso TransStates Focke-Wulf Fw 190
Output:
2 LED ai lati con lampeggio alternato
1 LED in coda lampeggio a freq doppia
Input:
1 interruttore su interrupt 0 per accensione / spegnimento luci
FSM per la gesrione delle transizioni tra i 2 stati .
* /
#include <common.h>
// FSM gestione interruttore luci
enum { // Stati della FMS
On , // Acceso
toOff , // Trans On -> Off
Off , // Spento
toOn // Trans OFF -> On
} toggle = Off ;
// Variabili per interrupt 0
volatile unsigned int chValue = 1500 ; // Valore computato
volatile unsigned int chStart = 1500 ; // Inizio rilevamento
const int soglia = 1500 ; // soglia per scatto toggle a 2 posizioni
// Var FSM
unsigned long FSM_lastMillis = 0 ; // Timestamp per la FSM degli alettoni
unsigned long pausa = 2000 ; // Pausa per la transizione durante gli stati 2 , 4 della FSM
unsigned long currentMillis = 0 ;
// Instanziamo gli oggetti per gli stati On / Off
Lampeggiatore left = 5 ;
Lampeggiatore right = 6 ;
Lampeggiatore coda = 9 ;
// Instanziamo gli oggetti per gli stati di transizione
Pwm leftPWM = 5 ;
Pwm rightPWM = 6 ;
Pwm codaPWM = 9 ;
void setup () {
attachInterrupt ( 0 , chRise , RISING ); // PIN 2 su 328 p / 168
right . Invert () ; // Invertiamo uno dei due lampeggiatori
}
void loop () {
currentMillis = millis ();
switch ( toggle ) {
case Off :
// Spento
left . Low ();
right . Low ();
coda . Low ();
if ( chValue > soglia ) {
FSM_lastMillis = currentMillis ;
toggle = toOn ;
leftPWM . Set ( 0 );
rightPWM . Set ( 0 );
codaPWM . Set ( 0 );
}
break ;
case On :
// Acceso
left . Blink (); // Lampeggia con un default di 1 sec ( 0 . 5 HI 0 . 5 LOW )
right . Blink ();
coda . Blink ( 1000 ); // Lampeggio in 1000 ms = 1 secondo
if ( chValue <= soglia ) {
FSM_lastMillis = currentMillis ;
toggle = toOff ;
leftPWM . Set ( 255 );
rightPWM . Set ( 255 );
codaPWM . Set ( 255 );
}
break ;
case toOn:
// Trans off -> on
leftPWM . lUp ( pausa );
rightPWM . lUp ( pausa );
codaPWM . lUp ( pausa );
if ( chValue > soglia && currentMillis - pausa > FSM_lastMillis ) {
toggle = On ;
} else if ( chValue <= soglia ) {
toggle = Off ;
}
break ;
case toOff:
// Trans on -> off
leftPWM . lDown ( pausa );
rightPWM . lDown ( pausa );
codaPWM . lDown ( pausa );
if ( chValue <= soglia && currentMillis - pausa > FSM_lastMillis ) {
toggle = Off ;
} else if ( chValue > soglia ) {
toggle = On ;
}
break ;
} ;
}
// Functions
void chRise () {
attachInterrupt ( 0 , chFall , FALLING );
chStart = micros ();
};
void chFall () {
attachInterrupt ( 0 , chRise , RISING );
chValue = micros () - chStart ;
};
Please enable JavaScript to view the comments powered by Disqus.