Bugatti Il Bugatti di Antonino, vedi esempio sull’uso del throttle.

Il Bugatti usa una striscia i LED arancioni sul motore con luminosita’ proporzionale al throttle, una striscia RGB sotto le ali, due rosse indipendenti sulla parte superiore delle ali.

Bugatti

/* Bugatti di Antonino

Outputs:
   2 LED / Strisce laterali che lampeggiano alternativamente
   1 LED in PWM per il motore
   1 Striscia RGB sotto per tutta la lunghezza delle ali

Inputs:
   Lettura del canale Throttle (3) con la funzione Pulsein
   Lettura alettoni con interrupt 0 (PIN2)

TODO:
* Cambiare il PIN del throttle su A5 da A3
* attaccare il canale degli alettoni al pin2
* guardare che tipo di RGB e', anodo o cat
* a full throttle RGB fa un Rand, vedere che non vada in conflitto con la sec FSM

*/

#include <common.h>
#define DEBUG

// LED disponibili
Lampeggiatore left = 7;
Lampeggiatore right = 8;
Pwm motore = 3;

// RGB
RGBLed ailerons(6,5,9,255);
// Transizione: lampeggiatori sui PIN RGB
Lampeggiatore sxLamp(5); // Lampeggiatore
Lampeggiatore dxLamp(9); // Lampeggiatore
Pwm rsotto = 6;
Pwm gsotto = 5;
Pwm bsotto = 3;


// Var thr
//////////////// !!!! cambiare thrIn
const byte thrPin = A2; // PIN collegato al CH3
byte thr ;  // Throttle a 8bit
int thrIn ; // Valore del th in ingresso dal servo

// Variabili per interrupt 0 su PIN 2
volatile unsigned int ail = 1500; // Valore computato
volatile unsigned int chStart2 = 1500; // Inizio rilevamento


// Vars Alettoni
const byte chPin2 = 2; // PIN per la calibrazione
int mid_point = 1450 ; // centro del segnale, trimmato nel setup
const int deviation = 40 ; // deviazione dal punto medio
//per entrare nello stato successivo dal centro


// 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 = 600;  // Pausa per la transizione durante gli stati 2, 4 della FSM

// Variabili comuni:
unsigned long currentMillis; // timestamp reference per millis per tutto il loop
byte caso ; // Valore random


void setup() {
    // I PINs vengono impostati dal constructor al momento
    // della dichiarazione dell'ogetto.
    pinMode(thrPin,INPUT);
    right.Invert() ;  // Opzionale: inverte l'ordine del lampeggio da

    attachInterrupt(0, chRise2, RISING); // PIN 2 su 328p / 168

    randomSeed(analogRead(0));

    // Test iniziale dei LED per verifica contatti:
    left.High();
    right.High();
    ailerons.White();
    motore.Set(255);
    delay(4000);


    mid_point =  calibraTrim(chPin2) + 8 ; // + LED di servizio per monitor calibrazione
#ifdef DEBUG
    Serial.begin(9600);
#endif
}

void loop() {
    currentMillis = millis(); // Timestamp per tutto il loop

// Lettura CH3
    thrIn = pulseIn(thrPin, HIGH, 25000);
    // Hint: thrIn andrebbe calibrato son un Serial.write
    if (thrIn != 0) {
        thr = map(thrIn, 870, 2000, 0, 255);
    };


// Gestione throttle
    if (thr >= 0 && thr < 15) {
        // IDLE

        right.Blink();
        left.Blink();
        motore.UD(2000);
        // RGB
        rsotto.lDown(3000);
        gsotto.lUp(1000);
        bsotto.lUp(2000);


    } else if (thr < 245) {
        // Throttle medio

        right.Blink(1120 - 4 * thr );
        left.Blink(1120 - 4 * thr );
        motore.lSet(thr);   // Luminosita' proporzionale al throttle

        //// Ailerons:
        switch (ailstate) {
        case middle:
        //    ailerons.White();
        rsotto.UD(2000);
        gsotto.UD(2000);
        bsotto.UD(2000);
            // Alettoni piatti
            if (ail > mid_point + deviation + deviation /3) {
                // extra margine per avere un po' di gioco
                ailstate = sxin;
                ailerons.Off();
                FSM_lastMillis = currentMillis;
            }
            else if (ail < mid_point - deviation - deviation / 3) {
                ailstate = dxin;
                ailerons.Off();
                FSM_lastMillis = currentMillis ;
            } ;
            break;

        case sxin:
            // Transizione a sx
            sxLamp.Blink(150);
            if (currentMillis - pausa > FSM_lastMillis ) {
                ailstate = sx;
            }
            break;

        case sx:
            ailerons.Red();
            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(150);
            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;
        };

    } else {
        // Throttle al massimo: LED laterali lampeggiano a caso,
        // Sotto luminosita' a caso

        caso = random(20, 240) ;
        right.Swap();
        left.Swap();
        motore.lSet(caso);
// TODO: check this
        ailerons.Rand();
        delay(caso);
    }




#ifdef DEBUG
    Serial.print(thrIn);
    Serial.print("\tthr: ");
    Serial.print(thr);
    Serial.print("\tail: ");
    Serial.print(ail);
    Serial.print("\t ailstate:");
    Serial.println(ailstate);
    //Serial.print("\t mid_point:");
    //Serial.print(mid_point);
#endif
}
// ISRs
void chRise2() {
    attachInterrupt(0, chFall2, FALLING);
    chStart2 = micros();
}

void chFall2() {
    attachInterrupt(0, chRise2, RISING);
    ail = micros() - chStart2;
}