Questo sketch pilota una striscia RGB in base agli alettoni: bianco con roll neutro, verde da un lato e blu dall’altro. Per enfatizzare la transizione tra neutro -> rollio si verifica un lampeggio di mezzo secondo nella transizione.
Il throttle e’ associato a un ciclo IF che pilota un LED in PWM sul motore e due lampeggiatori laterali: al throttle e’ a zero corrisponde uno PWM in dissolvenza verso il bassso per il motore e per i lampeggiatori, con throttle normali la luminosita’ del motore e’ proporzionale a questo, i LED laterali lampeggiano a una frequenza proporzionale al throttle. A throttle al massimo c’e’ una serie di lampeggi casuali per simulare un effetto afterburner.
INPUT:
PIN 2 : throttle
PIN 3 : alettoni
OUTPUT:
ailerons RGB Alettoni
motore Motore PWM
left, right 2 Lampeggiatori PWM laterali + PWM
FSM per alettoni
= 3 stati + 2 transizioni:
piatto
roll a sx
roll a dx
piatto -> sx
piatto -> dx
Tramite la lettura del valore del throttle vengono indicati 3 stati:
IDLE: gas praticamente a zero
Max: a tutto gas!
Medio: tutti i valori intermedi
/* Ailerons state machine
Serial.print(mid_point);
Pilotare un LED RGB in base al canale degli alettoni:
Questo sketch usa 2 interrupts per thr e alettoni.
INPUT:
PIN 2 : throttle
PIN 3 : alettoni
OUTPUT:
ailerons RGB Alettoni
motore Motore PWM
left, right 2 Lampeggiatori PWM laterali + PWM
FSM per alettoni
= 3 stati + 2 transizioni:
- piatto
- roll a sx
- roll a dx
- piatto -> sx
- piatto -> dx
Ciclo if per gestione di 3 stati del motore:
- idle
- middle
- max
TODO:
* Da testare! Mai provato.
*/
#include <common.h>
#define DEBUG
// Variabili per interrupt 0 si PIN 2
volatile unsigned int thr = 1500 ; // Valore computato
volatile unsigned int chStart2 = 1500 ; // Inizio rilevamento
// Variabili per interrupt 1 su PIN 3
volatile unsigned int ail = 1500 ; // Valore computato
volatile unsigned int chStart3 = 1500 ; // Inizio rilevamento
// Variabili per autocalibrazione 0
const byte chPin2 = 3 ; // PIN per la calibrazione
int mid_point2 = 1500 ;
// LEDs:
Pwm motore = 11 ;
// LED RGB alettoni
RGBLed ailerons ( 5 , 6 , 9 , 255 ); // Common Cat
// Transizione: Pwm
Lampeggiatore sxLamp ( 6 ); // Lampeggiatore
Lampeggiatore dxLamp ( 9 ); // Lampeggiatore
// Variabili per lettura canale servo
byte ailPin = 3 ; // Calibrazione
// Vars Alettoni
int mid_point = 1560 ; // centro del segnale, trimmato nel setup
const int deviation = 50 ; // deviazione dal punto medio
//per entrare nello stato successivo dal centro
// Led motore e altri:
Lampeggiatore left = 10 ;
Lampeggiatore right = 12 ;
Pwm sotto = 9 ;
// Quando il Throttle e' in IDE facciamo un PWM anche sui laterali
Pwm lpwm = 10 ;
Pwm rpwm = 12 ;
// Variabili:
unsigned long currentMillis ; // timestamp reference per millis per tutto il loop
byte caso ; // Random var
byte thrBit ; // Valore a 8bit per il throttle
// FSM gestione alettoni
enum { // Stati della FMS
middle , // centrale
sxin , // transizione a sx
sx , // sx
dxin , // transizione a dx
dx // dx
} ailstate = middle ;
// Vars FSM
unsigned long FSM_lastMillis = 0 ; // Timestamp per la FSM degli alettoni
unsigned long pausa = 500 ; // Pausa per la transizione durante gli stati 2, 4 della FSM
///////////////////////////////////////////////////////////
void setup () {
#ifdef DEBUG
Serial . begin ( 9600 );
#endif
attachInterrupt ( 0 , chRise2 , RISING ); // PIN 2 su 328p / 168
attachInterrupt ( 1 , chRise3 , RISING ); // PIN 3 su 328p / 168
// Funzione relativa a calibrazione:
mid_point = calibraTrim ( ailPin ) + 10 ; // + LED di servizio per monitor calibrazione
//Serial.print(mid_point);
//while(1) {
//}
}
void loop () {
currentMillis = millis (); // Timestamp per tutto il loop
switch ( ailstate ) {
case middle :
ailerons . White ();
// Alettoni piatti
if ( ail > mid_point + deviation + deviation / 3 ) {
// extra margine per avere un po' di gioco
ailstate = sxin ;
FSM_lastMillis = currentMillis ;
}
else if ( ail < mid_point - deviation - deviation / 3 ) {
ailstate = dxin ;
FSM_lastMillis = currentMillis ;
} ;
break ;
case sxin :
// Transizione a sx
sxLamp . Blink ( 200 );
if ( currentMillis - pausa > FSM_lastMillis ) {
ailstate = sx ;
}
break ;
case sx :
ailerons . Green ();
if ( ail < mid_point + deviation ) {
ailstate = middle ;
}
else if ( ail < mid_point - deviation ) {
FSM_lastMillis = currentMillis ;
ailstate = dxin ;
} ;
break ;
case dxin :
// Transizione a dx
dxLamp . Blink ( 200 );
if ( currentMillis - pausa > FSM_lastMillis ) {
ailstate = dx ;
}
break ;
case dx :
ailerons . Blue ();
if ( ail > mid_point - deviation ) {
ailstate = middle ;
}
else if ( ail > mid_point + deviation ) {
FSM_lastMillis = currentMillis ;
ailstate = dxin ;
} ;
break ;
}
// Gestione throttle
if ( thr < 1050 ) {
// IDLE
rpwm . UD ( 2000 );
lpwm . UD ( 2000 );
motore . lDown ( 1500 );
}
else if ( thr > 1900 ) {
// Throttle al massimo: LED laterali lampeggiano a caso,
// Sotto luminosita' a caso
caso = random ( 30 , 250 ) ;
right . Swap ();
left . Swap ();
motore . lSet ( caso );
delay ( caso ); // Blocking!
}
else {
// Throttle medio
thrBit = map ( thr , 1050 , 1900 , 0 , 255 );
right . Blink ( 1220 - 4 * thrBit );
left . Blink ( 1220 - 4 * thrBit );
motore . lSet ( thrBit ); // Luminosita' proporzionale al throttle
}
#ifdef DEBUG
Serial . print (( thr - 980 ) / 4 );
Serial . print ( " \t ail: " );
Serial . print ( ail );
Serial . print ( " \t ailstate:" );
Serial . println ( ailstate );
#endif
}
// Functions
void chRise2 () {
attachInterrupt ( 0 , chFall2 , FALLING );
chStart2 = micros ();
}
void chFall2 () {
attachInterrupt ( 0 , chRise2 , RISING );
thr = micros () - chStart2 ;
}
// Seconod iterrupt
void chRise3 () {
attachInterrupt ( 1 , chFall3 , FALLING );
chStart3 = micros ();
}
void chFall3 () {
attachInterrupt ( 1 , chRise3 , RISING );
ail = micros () - chStart3 ;
}
Please enable JavaScript to view the comments powered by Disqus.