--- /dev/null
+* inserire knight rider con millis
+* esempio con state machine per flight modes
+* battery voltage reader -> RGB
+** Schemi
+** descrizione componenti: transistor, array, stepdown
+** digital compass e RGB
+** barometer
+** 6 axis
+** Neopixel
--- /dev/null
+/* Common
+ *
+ * Oggetti di uso comune
+ */
+
+#include "Arduino.h"
+#include "common.h"
+
+
+//////////////////////
+// RGB LED
+// Common anode
+
+RGBLed::RGBLed(byte pinR, byte pinG, byte pinB) {
+ redPin = pinR ;
+ greenPin = pinG ;
+ bluePin = pinB ;
+
+ // Equvalente del Setup() per inizializzare i PIN
+ pinMode(redPin, OUTPUT);
+ pinMode(greenPin, OUTPUT);
+ pinMode(greenPin, OUTPUT);
+};
+
+void RGBLed::SetColor (byte r, byte g, byte b) {
+// Imposta il colore di un LED RGB
+ analogWrite(redPin, r);
+ analogWrite(greenPin, g);
+ analogWrite(bluePin, b);
+ };
+
+void RGBLed::Red () {
+// Accende il LED di rosso
+ SetColor(0,255,255);
+ };
+
+void RGBLed::Green () {
+// Accende il LED di verde
+ SetColor(255,0,255);
+ };
+
+void RGBLed::Blue () {
+// Accende il LED di blu
+ SetColor(255,255,0);
+ };
+
+void RGBLed::Magenta () {
+// Accende il LED di magenta
+ SetColor(0,255,0);
+ };
+
+void RGBLed::Cyano () {
+// Accende il LED di Cyano
+ SetColor(255,0,0);
+ };
+
+void RGBLed::Yellow () {
+// Accende il LED di giallo
+ SetColor(0,0,255);
+ };
+
+void RGBLed::White () {
+// Accende il LED
+ SetColor(0,0,0);
+ };
+
+void RGBLed::Off () {
+// Spegne il LED
+ SetColor(255,255,255);
+ };
+
+
+
+/////////////////////////////////////
+// Lampeggiatore
+// Constructor
+Lampeggiatore::Lampeggiatore(int pin)
+{
+ ledPin = pin;
+ pinMode(ledPin, OUTPUT);
+ ledState = LOW;
+ previousMillis = 0;
+ interval = 500;
+};
+
+// Una funzione facente parte di una classe prende il nome di "metodo" della stessa:
+void Lampeggiatore::Invert() {
+ // Inverte il lampeggio
+ ledState = HIGH ;
+}
+
+void Lampeggiatore::Blink() {
+ // Illumina il led a 500ms
+
+ if(millis() - previousMillis > interval) {
+ // save the last time you blinked the LED
+ previousMillis = millis();
+
+ // if the LED is off turn it on and vice-versa:
+ ledState = !ledState ; // Inverti il LED
+ }
+ // set the LED with the ledState of the variable:
+ digitalWrite(ledPin, ledState);
+};
+
+void Lampeggiatore::Blink(long time) {
+ // Illumina il led secondo un intervallo passato come argomento
+
+ if(millis() - previousMillis > time) {
+ // save the last time you blinked the LED
+ previousMillis = millis();
+
+ // if the LED is off turn it on and vice-versa:
+ ledState = !ledState ; // Inverti il LED
+ }
+ // set the LED with the ledState of the variable:
+ digitalWrite(ledPin, ledState);
+};
+
+void Lampeggiatore::Blink(long up, long down) {
+ // Illumina il ledB precisando ontime e downtime
+
+ if((ledState == HIGH)&& (millis() - previousMillis > up)) {
+ // save the last time you blinked the LED
+ previousMillis = millis();
+ ledState = LOW ;
+ }
+ else if((ledState == LOW)&& (millis() - previousMillis > down)) {
+ previousMillis = millis();
+ ledState = HIGH ;
+ }
+
+ // set the LED with the ledState of the variable:
+ digitalWrite(ledPin, ledState);
+};
+
+/////////////////////////////////////
+// Pwm
+// Constructor
+Pwm::Pwm(int pin)
+ // Gestione del PWM utilizzando millis
+ // per non bloccare il processore con delay
+ // Warning: serialWrite puo' interferire con i tempi.
+{
+ ledPin = pin;
+ pinMode(ledPin, OUTPUT);
+ previousMillis = 0;
+ byte brightness = 0 ;
+ increment = 1;
+};
+
+void Pwm::Up(long speed) {
+ // Aumenta progressivamente la luminosita' usanndo millis()
+ // quindi senza bloccare il processore
+ // Viene usato un float, in alternativa un coseno
+
+ if (millis() != previousMillis) { // si potrebbe togliere
+ brightness = 255.0 /(float)speed * millis() ;
+ analogWrite(ledPin, brightness);
+
+ previousMillis = millis();
+ };
+}
+
+void Pwm::Down(long speed ) {
+ // Riduce progressivamente la luminosita' usanndo millis()
+ // quindi senza bloccare il processore
+
+ if (millis() != previousMillis) {
+ brightness = 255 - 255.0 /(float)speed * millis() ;
+ analogWrite(ledPin, brightness);
+
+ previousMillis = millis();
+ };
+}
+
+void Pwm::UD(long speed ) {
+ // Aumenta e riduce in sequenza la luminosita' usanndo millis()
+ brightness = 128 + 127 * cos(2 * PI / speed * millis());
+ analogWrite(ledPin, brightness);
+}
+
+
+/////////////////////////////////////
+// Sequenza
+// Constructor
+Sequenza::Sequenza (byte passed[], byte dim) {
+ ledPins = passed ;
+ size = dim ;
+ for (int thisPin = 0; thisPin < size; thisPin++) {
+ pinMode(ledPins[thisPin], OUTPUT);
+ }
+ previousMillis = millis();
+ digitalWrite(ledPins[0], HIGH);
+}
+
+void Sequenza::Update(long value) {
+ // Incrementa dal primo all'ultimo valore dell'array
+ interval = value;
+ if (millis() - previousMillis >= interval) {
+ previousMillis = millis();
+
+ if ( i < size - 1 ) {
+ // Spegni precedente led
+ digitalWrite(ledPins[i], LOW);
+
+ // Accendi successivo led
+ digitalWrite(ledPins[++i], HIGH);
+ }
+
+ else if (i == size - 1 ) {
+ // Ultimo caso
+ i = 0;
+ previousMillis = millis();
+ digitalWrite(ledPins[i], HIGH);
+ digitalWrite(ledPins[ size - 1 ], LOW);
+ }
+ }
+}
+
+
+void Sequenza::Reverse(long value) {
+ interval = value;
+ if (millis() - previousMillis >= interval) {
+ previousMillis = millis();
+
+ if (i == 0) { // Entry point, ultimo LED
+ digitalWrite(ledPins[size -1],HIGH);
+ digitalWrite(ledPins[0],LOW);
+ i = size -1 ;
+ }
+ else {
+ digitalWrite(ledPins[i],LOW);
+ digitalWrite(ledPins[--i],HIGH);
+ }
+ }
+}
+
+void Sequenza::UD(long value) {
+ interval = value;
+ if (millis() - previousMillis >= interval) {
+ previousMillis = millis();
+ // Spegni precedente led
+ digitalWrite(ledPins[i], LOW);
+ i = i + inc ;
+ // Accendi successivo led
+ digitalWrite(ledPins[i], HIGH);
+
+ if (i == 0 || i == size -1) {
+ inc = -inc ;
+ }
+ }
+}
+
+
+//////////////////
+// Funzioni
+
+
+void brilla(byte pin, int velocita ) { // Defalt value di velocita' solo nell'Header
+ // Accende e spegne il LED accetando un argomento
+ // per impostare la velocita'.
+
+pinMode(pin, OUTPUT);
+ // sequenze di istruzione: accendere e spegnere il LED
+ digitalWrite(pin, HIGH); // turn the LED on (HIGH is the voltage level)
+ delay(velocita); // wait for a second
+ digitalWrite(pin, LOW); // turn the LED off by making the voltage LOW
+ delay(velocita); // wait for a second
+};
+
+
+byte lum(byte val) {
+ // Mappatura dell'intervallo 0-255 con correzione di luminosita.
+ // storata in SRAM
+return pgm_read_byte_near(BCORRECT + val);
+};
--- /dev/null
+/*
+ Common Class
+
+ Oggetti comuni
+
+*/
+
+#include "Arduino.h"
+#include <avr/pgmspace.h>
+
+#ifndef common_h
+#define common_h
+
+// Variabili
+const uint8_t BCORRECT[256] PROGMEM = { // Tabella per correzione luminosita' PWM
+ 0,0,0,1,1,1,2,1,1,2,1,2,2,2,3,2,
+ 2,2,3,2,2,3,2,3,3,3,4,3,3,3,4,4,
+ 4,5,4,5,4,5,5,6,5,5,6,5,6,6,7,6,
+ 7,7,8,7,8,8,9,8,9,10,9,10,10,11,10,11,
+ 11,12,11,12,13,12,13,13,14,14,15,15,15,16,16,17,
+ 17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,
+ 25,25,26,26,27,28,28,29,29,30,31,31,32,32,33,34,
+ 34,35,36,37,37,38,39,39,40,41,42,43,43,44,45,46,
+ 47,47,48,49,50,51,52,53,54,54,55,56,57,58,59,60,
+ 61,62,63,64,65,66,67,68,70,71,72,73,74,75,76,77,
+ 79,80,81,82,83,85,86,87,88,90,91,92,94,95,96,98,
+ 99,100,102,103,105,106,108,109,110,112,113,115,116,118,120,121,
+ 123,124,126,128,129,131,132,134,136,138,139,141,143,145,146,148,
+ 150,152,154,155,157,159,161,163,165,167,169,171,173,175,177,179,
+ 181,183,185,187,189,191,193,196,198,200,202,204,207,209,211,214,
+ 216,218,220,223,225,228,230,232,235,237,240,242,245,247,251,255
+};
+
+// Inserirne una con 32 valori
+
+
+class RGBLed {
+ // Classe rappresentativa di un LED RGB
+ protected: // Vedi esempio Ereditarieta'
+ byte redPin ;
+ byte greenPin ;
+ byte bluePin ;
+ byte redValue ;
+ byte greenValue ;
+ byte blueValue ;
+
+ public:
+ RGBLed (byte pinR, byte pinG, byte pinB) ;
+ void SetColor (byte r, byte g, byte b) ;
+ void Red ();
+ void Green ();
+ void Blue ();
+ void Magenta ();
+ void Cyano ();
+ void White ();
+ void Yellow ();
+ void Off ();
+};
+
+
+
+class Lampeggiatore {
+ // Lampeggia un LED utilizzando millis()
+ // Variabili
+ int ledPin ; // il numero del LED pin
+ long interval ; // milliseconds di intervallo nel lampeggiare
+ unsigned long previousMillis ; // precedente cambio di stato
+ int ledState ; // stato attuale del LED, pubblico per invertirlo
+
+ // Constructor: come viene instanziato un oggetto facente parte della classe
+public:
+ Lampeggiatore(int pin);
+ void Invert(); // Inverte il lampeggio
+ void Blink(); // Lampeggia ogni 500ms
+ void Blink(long interval); // Lampeggia inpostando l'intervallo
+ void Blink(long on, long down); // Imposta il tempo acceso e il tempo spento
+};
+
+
+
+////////////////////////////
+class Pwm {
+ /*
+ PWM per un LED: aumentare progressivamente la luminosita'.
+ Utilizza la funzione millis() invece che un delay()
+ in modo da non blocare il processore.
+ */
+ // Variabili
+ int ledPin ; // il numero del LED pin
+ int speed ; // velocita' del ciclo in ms
+ unsigned long previousMillis ; //precedente cambio di stato
+ byte increment ; // aumenta brighteness nel loop UD
+
+ // Constructor: come viene instanziato un oggetto facente parte della classe
+public:
+ Pwm(int pin); // numero di pin, velocita' di ciclo
+ void Up(long speed);
+ void Down(long speed);
+ void UD(long speed);
+ byte brightness ; // luminostia' iniziale
+};
+
+
+
+////////////////////////////
+class Sequenza {
+ // Lampeggia LED in sequenza utilizzando millis()
+ unsigned long previousMillis ;
+ byte i = 0;
+ byte *ledPins;
+ byte size;
+ int inc = 1;
+ long interval;
+
+ public:
+ Sequenza (byte passed[], byte dim) ; // Array contentente i PINS, dimensioni array
+ void Update(long value) ; // Accende in sequenza
+ void Reverse(long value) ; // Invertita
+ void UD(long value) ; // Up & Down
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//////////////////////
+// Funzioni
+
+void brilla(byte pin, int velocita = 200) ;
+#endif
+
+byte lum(byte val);
--- /dev/null
+/* Funzione Invert
+
+ Due LED con lampeggio alternato
+*/
+
+#include <common.h>
+
+Lampeggiatore right = 3;
+Lampeggiatore left = 5;
+
+void setup() {
+ left.Invert(); // Parte da stato invertito rispetto al default
+}
+
+void loop() {
+ // Due LED con lampeggio alternato:
+ right.Blink();
+ left.Blink();
+ // Si possono usare i soliti metodi dell'oggetto blink
+}
--- /dev/null
+/* Esempio
+
+ Utilizzo dell'oggetto Lampeggiatore:
+ Lampeggia un LED utilizzando millis()
+*/
+
+#include <common.h>
+
+// Instanziamo un LED fuori dal loop
+Lampeggiatore led = 13;
+
+void setup() {
+// I PINs vengono impostati dal constructor al momento
+// della dichiarazione dell'ogetto.
+
+led.Invert() ; // Opzionale: inverte l'ordine del lampeggio da
+ // HI -> LOW --> LOW -> HI
+ // per avere 2 LED che lampeggiano alternativamente
+}
+
+void loop() {
+ led.Blink(); // Lampeggia con un default di 1sec (0.5 HI 0.5 LOW)
+ led.Blink(500); // Lampeggia ogni 500ms
+ led.Blink(500,200); // Imposta il tempo acceso e il tempo spento
+}
--- /dev/null
+/* Ereditarieta'
+
+ La classe SuperLED definita in questo sketch
+ eredita le caratteristiche di RGBLed e introduce un nuovo metodo
+ per un nuovo colore custom.
+
+*/
+
+#include <common.h> // L'orine e' importante: prima l'include,
+ // poi la dichiarazione della nuova classe (non a fondo pagina)
+ // poi potremo usare la nuova classe
+
+class SuperLED : public RGBLed { // Ereditamo dalla classe RGBLed
+ // Nuovi colori per RGBLed
+
+ using RGBLed::RGBLed ; // Richiamiamo il constructor del genitore
+ public:
+ void Violet () { // Nuovo metodo
+ // Accende il LED di viola
+
+ analogWrite(redPin, 255 - 238);
+ analogWrite(greenPin, 255 - 130);
+ analogWrite(bluePin, 255 - 238);
+ };
+};
+
+void setup() {
+ // I PINs vengono impostati dalla dichiarazione dell'ogetto.
+}
+
+// Instanziamo un LED
+SuperLED led(11, 10, 9); //Istanziamo un oggetto led facente parte
+ // della inuova classe SuperLed che eredita da RGBLed
+
+void loop() {
+ led.Violet(); // Nuovo metodo
+ delay(1000);
+ led.Off(); // Vecchio metodo
+ delay(1000);
+}
+
--- /dev/null
+/* Esempio
+
+ Utilizzo dell'oggetto PWM:
+ Gestione del PWM utilizzando millis
+ per non bloccare il processore con delay
+*/
+
+#include <common.h>
+
+// Instanziamo un LED fuori dal loop
+Pwm led = 9;
+
+void setup() {
+// I PINs vengono impostati dal constructor al momento
+// della dichiarazione dell'ogetto.
+}
+
+void loop() {
+ led.Up(2000); // Aumenta la luminosita' in 2 sec
+ led.Down(1000); // Diminuisce la luminosita' in 1 sec
+ led.UD(4000); // Aumenta e poi diminuisce la luminostia' in 4 sec.
+}
--- /dev/null
+/* Esempio
+
+ Come caricare e usare un oggetto e una funzione
+ facente parte della libreria.
+*/
+
+#include <common.h>
+
+void setup() {
+ // I PINs vengono impostati dalla dichiarazione dell'ogetto.
+}
+
+// Instanziamo un LED
+RGBLed led(11, 10, 9); //Istanziamo un oggetto led facente parte
+ // della classe RGBLed
+
+void loop() {
+ led.Red();
+ delay(1000);
+ led.SetColor(255, 0, 255) ; // Mettiamo il LED in Green
+ delay(1000);
+ led.Off();
+}
+
+/* Colori disponibili:
+ Red
+ Green
+ Blue
+ Magenta
+ Cyano
+ White
+ Yellow
+
+Nota: per aggiungerne uno senza modificare la libreria originale
+si potrebbe usara l'ereditarieta': vedi esempio "eredita.ino" .
+*/
--- /dev/null
+/*
+ For Loop with millis()
+
+Blink di un array di led in sucessione,
+utilizzando millis() per non blocking.
+L'array puo' contenere un numero arbitrario di led
+(l'ordine in cui compaiono e' l'ordine in cui brillano).
+
+OOP version.
+
+ Schemi:
+ - http://lab.piffa.net/schemi/8_led_single_res_bb.png
+ - http://lab.piffa.net/schemi/8_led_single_res_schem.png
+
+ http://www.arduino.cc/en/Tutorial/ForLoop
+ */
+#include <common.h>
+void setup() {
+};
+
+byte pins[] = { // PIN dei LED che compongono la sequenza
+ 2, 3, 4, 5, 6, 7
+};
+Sequenza seq = Sequenza(pins,sizeof(pins)); // Array dei PINs, quanti elementi compongono l'array
+
+void loop() {
+ seq.Update(200); // Passa al segmento suciessivo ogni 200ms
+};
+
+
+
--- /dev/null
+RGBLed KEYWORD1
+Red KEYWORD2
+Green KEYWORD2
+Blue KEYWORD2
+Magenta KEYWORD2
+Cyano KEYWORD2
+White KEYWORD2
+Yellow KEYWORD2
+Off KEYWORD2
+SetColor KEYWORD2
+brilla KEYWORD2
--- /dev/null
+Pragmatica della luminosita' applicata al volo notturno
+**********************************************************
+
+Elementi disponibili
+=====================
+
+
+* lampeggi
+* fade (up / down / UD)
+* accensioni / spegnimenti sequenziali di segmenti (knight rider)
+* RGB: quanto sopra + cambio dei colori
+
+
+Lampeggi
+------------
+Dettaglio:
+
+* velocita' tempi HI / LOW
+* Variazione tempo HI / tempo LOW
+* Lampeggi sequenziali con una pausa LOW piu' lunga
+
+Considerazioni: un lampeggio con rapporto H/L 1/3 dimostra lo stesso consumo di segmento sequenziale a 3 unita'.
+
+
+Fade
+-----
+
+* E' difficile distinguere tra un UP e un DOWN
+* Le variazioni della luminosita', sopratutto ai valori bassi, sono poco percettibili. Un movimento sequenziale con velocita' variabile e' piu' evidente
+
+
+RGB
+----
+
+* si puo' usare un solo PWM sul catodo comune per pilotare l'intensita' di tutti i colori
+
+
+Sequenziali
+--------------
+
+
+* il minimo per un sequenziale e' 3 segmenti
+* I segmenti posso essere ripetuti
+* I segmenti posso essere messi in mirror (es. dal centro all'esterno per le ali)
+* si puo' variare il rapporto tra accesi / spenti
+* I neopixels sono i migliori per i sequenziali
+
+
+Considerazioni
+================
+
+* Piu' il LED e' acceso (White per RGB) piu' consuma: limitare tempo e luminosita'
+* Il binaco freddo e' il LED piu' luminoso
+* il contrasto acceso / spento e' il piu' evidente, il fade e' piu' subdolo.
+* la visibilita' delle estremita' permette la massima visibilita' della sagoma e delle rotazioni.
+
+Pragmatica
+================
+
+* la maggior parte del tempo l'aereo e' visibile da sotto
+* se l'aereo e' in orientamento normale e' ok, se in volo rovesciato e' allarme
+ * per un acrobatico si potrebbe indicare ogni orientamento con RGB
+* se l'aereo e' pari e' ok, se picchia e' allarme, se cabra puo' essere segnalato.
+
+
+Lessico
+----------
+* il lampeggio indica allarme
+* il fade UD indica riposo / stazionario
+* il sequenziale ha una connotazione di attivita' in corso
+
+
+Orientamento
+============
+
+Serve distinguere principalmente tra sopra e sotto, davanti e dietro. Secondariamente tra destra e sinistra.
+
+Quindi prevalentemente usare il bianco per il sotto e per le estremita'.
+Il rosso essendo il secondo colore predominante si puo' usare per il sopra.
+Verde e blu per i lati.
+
+Per dare un'indicazione della direzione usare segmenti sequenziali: sotto l'aereo per indicare il moto orizzontale
+
+
+Hardware
+=============
+
+Sensori
+-----------
+
+* per rilevare l'inclinazione basta una bussola HMC5883L
+* per rilevare lo stato della carica delle batterie bastano le entrate A. 5v di un Arduino
+* il throttle e' in genere l'unico che non prevede trim, per gli altri bisognerebbe compensare i trim con una autocalibrazione iniziale per fissare lo 0
+