Arduino - magie in pochi grammi e pochissimi Euro

Tutto quello che l'elettrone consente di fare e a volte... strafare per i nostri modelli!!!

Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 04/05/2018, 16:08

Ciao,
in questo periodo che ci frequentiamo ho visto che alcuni dei nostri modelli beneficerebbero volentieri di qualche alchimia elettronica, fosse solo per renderli più semplici da assemblare e gestire con la radio.
In questo ci viene certamente in contro Arduino, nelle sue molteplici forme e taglie, per automatizzare ed ottimizzare il comando, il controllo e la supervisione di quanto c'è di elettrico sui nostri piccoli gioielli.
Ma cos'è Arduino, il cui nome ci ricorda tanto un personaggio del nostro amato Alberto Sordi? Arduino, che prende il nome proprio dal personaggio appena citato, è quella che tecnicamente si chiama "piattaforma di prototipazione", cioè una piattaforma per mettere a punto il prototipo di un progetto che poi verrà ingegnerizzato e messo in commercio in una forma più adatta allo scopo. In pratica è una schedina con un microcomputer e tanti piedini, di progettazione italiana, che nasce per fare progetti sperimentali. La sua versatilità ed economicità, specialmente nella versione "clone cinese", ha reso Arduino un must per chi si occupa di robotica, automazione, domotica e, perché no, modellismo dinamico.
Cosa sa fare Arduino? Come tutti i computer, è ossessivamente stupido ma veloce e preciso nell'eseguire il compito che gli viene assegnato. Abbiamo capito quindi che lo dobbiamo istruire, come farlo lo vedremo più avanti, ma non abbiamo ancora capito come può aiutarci.
Arduino ha la sua forza nella capacità di avere in ingresso e in uscita un certo numero di piedini (pin) e di gestirli autonomamente ed in modo abbastanza semplice. I piedini possono essere di input o di output e possono gestire sia segnali digitali che analogici. Ai piedini di input possiamo collegare l'uscita della nostra radio, e quindi fargli conoscere i comandi che inviamo al modello, possiamo collegarci sensori di varia natura (tensione, corrente, temperatura, campo magnetico, luce, etc etc) e farlo reagire ai valori letti da questi sensori. Ai piedini di output possiamo collegare attuatori di ogni tipo: rele, servi, mosfet (interruttori elettronici ad alta potenza), led, altoparlanti, etc etc, fino ad arrivare anche all'ingresso dell'eventuale modulo di telemetria della nostra radio, per ricevere nelle nostre mani le informazioni presenti nel nostro modello.
Qualcuno potrebbe obiettare che già le radio sanno fare molte di queste cose, ed è vero, ma la semplicità ed economicità con cui Arduino ci aiuta in queste funzionalità è semplicemente disarmante e ci permette di superare agevolmente i limiti delle radio, specialmente quelle più economiche o datate.
Nel prossimo articolo vedremo i primi esempi pratici.
Alla prossima

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda alimurimeta » 06/05/2018, 10:28

Ciao Carlo, mi interessa molto questo argomento. Ti seguo con grande attenzione e piacere. Ho letto in giro nel web che hanno implementato una scheda Arduino per usare i multiswitch delle vecchie radio robbe-futaba, con i moderni sistemi di trasmissione a 2,4Ghz.
Potrebbe essere un valido esempio per farci capire le potenzialità di Arduino.
Saluti
    Francesco G. - ALIMURIMETA
ImmagineImmagine
Immagine
Immagine
Avatar utente
alimurimeta
 
Messaggi: 1205
Iscritto il: 01/06/2013, 10:51

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 06/05/2018, 21:43

Ciao Francesco,
non conosco l'oggetto di cui parli ma, da quel poco che ho sbirciato adesso in rete, è una delle possibili applicazioni di questo microcontrollore.

In pratica sulla radio si sostituisce un dispositivo di ingresso proporzionale (tipicamente un potenziometro) con un arduino che riceve come input una serie di interruttori. Attraverso un algoritmo, se ne codificano i singoli stati in un unico valore e lo trasmette al modello. Qui un altro arduino riceve il segnale, lo decodifica ed aziona un certo numero di uscite on/off.

Visto che il multiswitch nasce già integrato con la radio, e che quindi è stato realizzato con tecnologia dedicata e proprietaria, è sufficiente prendere la parte della ricevente.
Il bello di questi sistemi è che non c'è nulla di segreto, con un analizzatore di segnali puoi decifrare quasi qualsiasi codice e costruire un decodificatore specifico.

Volendo approfondire su come funziona il sistema in questione, partiamo dal concetto che un canale proporzionale viene trasmesso come un impulso PWM della frequenza di 50 hertz e della durata compresa tra 700 e 2100 microsecondi. In questo tempo noi possiamo trasmettere, multiplandoli tra loro, un certo numero di canali virtuali on/off.

Immaginiamo, per semplicità, di avere solo 4 interruttori da gestire. Ad ogni interruttore assegniamo un "peso" che è il doppio del precedente:

int 1: peso 1
int 2: peso 2
int 3: peso 4
int 4: peso 8

Sommando poi il peso dei soli interruttori "accesi", otteniamo un numero compreso tra 0 e 15 (16 possibili combinazioni) che descrive in modo univoco lo stato dei singoli interruttori. Non c'è possibilità di errore o ambiguità.

Dividiamo poi il range di tempo disponibile per la durata dell'impulso PWM (che è di 2100-700=1400 microsecondi) per 16 (il numero delle possibili combinazioni degli interruttori) ed otteniamo che ogni incremento del numero codificato che corrisponde agli interruttori è codificabile come un aumento dell'impulso PWM pari a 1400/16=87,5 microsecondi. Alla fine ci dovremo sempre ricordare di riaggiungere i 700 microsecondi che corrispondono al numero 0.

Immaginiamo quindi, per esempio, di avere accesi l'int 2 e l'int 4. La somma dei pesi fa 2+8=10, che corrisponde ad un impulso di 87,5*10=875 microsecondi. Sommiamo i 700 microsecondi che costituiscono l'impulso "zero" ed otteniamo un impulso di 1575 microsecondi, che corrisponde appunto al numero 10 che dobbiamo trasmettere. Questo impulso viene trasmesso dalla radio esattamente come se fosse un valore letto dal potenziometro originale della radio.

In ricezione facciamo la procedura inversa ed otteniamo l'esatta decodifica dei quattro interruttori.

Volendo si può salire con il numero di interruttori, ma diminuisce l'affidabilità del sistema, che potrebbe generare errori nella gestione degli interruttori con peso più basso. Il limite a cui possiamo spingerci dipende dalla risoluzione in passi del nostro sistema trasmissivo. Con un sistema da 1024 passi potremmo teoricamente ad avere 10 interruttori su un unico canale, ma non credo che il sistema sia così stabile ed affidabile da avere la precisione richiesta, quindi occorre ridurci a 8 interruttori. Se hai un sistema trasmissivo che arriva ad una risoluzione di 4096 passi, allora i 10 interruttori diventano possibili.

Volendo si può anche fare un sistema ibrido, che multipla sia interruttori che potenziometri, ma la precisione dei potenziometri diminuisce ed aumenta notevolmente la complessità della codifica e decodifica.

Ma abbiamo divagato rispetto allo scopo di questi articoli, andando un pochino troppo avanti senza aver prima gettato le basi.

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 06/05/2018, 22:36

Vorrei riprendere il discorso in modo più organico, cercando di seguire un discorso passo-passo, logico e comprensibile anche a chi non mastica ne l'elettronica ne la matematica e neanche la programmazione.

Partiamo da "di cosa ho bisogno per cominciare?". Di pochissimo! Un Arduino, un cavetto USB ed un pc, oltre ad una sana voglia di apprendere. Per fare le prime esperienze ci occorre poi un potenziometro (qualsiasi tipo di non oltre 50.000 Ohm di valore) e di un interruttore, necessari per simulare sensori analogici e digitali. Volendo fare un passo completo, vendono dei "starter kit" con inclusi anche tanti sensori che utilizzeremo in futuro.

Arduino è acquistabile sia nei negozi di elettronica che online ed i prezzi sono molto variabili in base alla tipologia che alla provenienza. Si va da un paio di un euro per un Arduino Nano (più avanti parliamo delle varie versioni) comprato in cina e consegnato in 30-60 giorni fino a qualche decina di € per un Mega2560 comprato in un negozio fisico in Italia.

Già ma quale Arduino comprare? Ne esistono almeno una decina di versioni diverse, che si differiscono per il tipo di processore che ospitano e dal numero di piedini di input/output di cui dispongono. Ne esistono alcuni che integrano moduli di comunicazione WiFi o LAN, ma a noi in modellismo non ci interessano e quindi non li prendiamo in esame.

Personalmente mi trovo molto bene con l'Arduino Nano V3 (https://it.aliexpress.com/item/MINI-USB ... autifyAB=0), che dispone di un processore Amtel328 (tra i più potenti della categoria).
Dal sito che ho linkato vediamo quali sono le sue caratteristiche principali in termini di input ed output

8 ingressi analogici porte: A0 ~ A7
14 Digital porte di ingresso/uscita: TX, RX, D2 ~ D13
6 porte PWM: D3, D5, D6, D9, D10, D11
1 paia di porte ricetrasmettitore seriale a livello TTL RX/TX

Gli ingressi analogici sono in grado di leggere un segnale analogico compreso (tipicamente) tra 0 e 5V e renderne disponibile il valore in una scala tra 0 e 1023 (tecnicamente diciamo che il convertitore lavora con 10 bit di risoluzione). Questo significa, ad esempio, che se ci applichiamo un potenziometro e questo è posizionato a metà corsa, l'ingresso ci riporterà un valore di c.ca 500. L'utilizzo tipico di questi ingressi è per leggere una tensione (di una batteria, ad esempio) o una corrente (attraverso una resistenza esterna), una luminosità ambientale (attraverso una fotoresistenza), etc etc.
Gli ingressi digitali invece riconoscono solo se la tensione al loro ingresso supera una determinata soglia (c.ca 2-3 Volt) e restituisce solo un valore LOW o HIGH (purtroppo il sistema parla solo inglese.) L'utilizzo tipico è di leggere lo stato di un interruttore o di un fotodiodo che rileva il passaggio di un oggetto attraverso una barriera ottica, etc. , cioè di quei dispositivi che forniscono una informazione che può essere solo SI o NO. Attraverso delle funzioni dedicate, il sistema ci permette di conoscere la lunghezza di un segnale impulsivo (PWM) applicato al suo ingresso, permettendoci quindi di interfacciarci facilmente con le riceventi delle nostre radio (vedi mio post precedente).
Tutti gli ingressi digitali sono anche utilizzabili come uscite, per accendere un led o un dispositivo magari anche più grosso (attraverso un adattatore esterno). Con apposite funzioni, possiamo utilizzare queste porte per generare segnali PWM in grado di pilotare i nostri servi, esattamente come se fossero comandati dalla ricevente della radio.
Le porte PWM sono porte speciali, che permettono di simulare la generazione una tensione analogica attraverso la generazione di un segnale digitale in cui il rapporto tra tempo di tensione alta e tensione bassa è regolabile con precisione. Con questa tecnica è possibile pilotare un motore a spazzole e determinarne la velocità, esattamente come se lo avessimo collegato ad un ESC (che, peraltro, funziona con lo stesso identico principio).
Infine le porte seriali ci permettono di comunicare con un altro arduino o con qualsiasi altro apparato che supporta questo sistema di comunicazione.

Una volta che abbiamo comprato Arduino, dobbiamo collegarlo al pc e siamo quasi pronti ad iniziare. Prima dobbiamo però installare sul pc il programma che ci permette di scrivere il codice da caricare su Arduino. Il programma si chiama IDE e si scarica direttamente dal sito Arduino.cc.

Alcuni modelli di Arduino richiedono la preventiva installazione di un driver sul pc per essere riconosciuti dal sistema, ma si tratta di casi isolati e specifici. Nella maggior parte dei casi Arduino verrà visto come un dispositivo che implementa una porta seriale COM.
Abbiamo tutto? Ed allora PRONTI E VIA! Nel prossimo messaggio vediamo come scrivere il nostro primo programma.

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 06/05/2018, 23:18

Avete tutto? Avete installato la IDE? Avete collegato Arduino al PC e lui lo ha riconosciuto come una porta COM? Bene, siete quasi pronti per il primo compito: far accendere il led che è sulla schedina. Prima però dobbiamo fare un briciolo di presentazioni e di teoria.
Innanzitutto avrete capito che arduino lo istruiamo scrivendo un programma, esattamente come si fa per qualsiasi cosa dobbiamo far fare al nostro pc.
Ma cosa è un programma? Semplicemente una serie di istruzioni, fornite attraverso PAROLE CHIAVE, che la macchina eseguirà in sequenza. Sono istruzioni che manipolano informazioni, contenute in oggetti chiamati "VARIABILI". Le informazioni sono tipicamente di tipo logico (SI/NO o VERO/FALSO o LOW/HIGH), numeriche o di testo.

Le istruzioni dicono, esattamente e senza ambiguità, cosa deve fare il nostro Arduino. Possono essere istruzioni che eseguono un calcolo matematico, una operazione su un testo, la lettura o la scrittura di un valore da/su un pin di /I/O (abbreviazione di Input/Ouput). Possono esserci istruzioni che "prendono una decisione" e sono probabilmente le istruzioni più potenti che abbiamo a disposizione.

Quasi ogni istruzione è composta da una parola chiave e da uno o più argomenti e restituisce un risultato.

Per chi già mastica qualcosa di computerese, aggiungo che il linguaggio utilizzato è una versione ridotta del C++.

Proviamo a vedere un esempio semplicissimo di un programma. Per questo scopo utilizzerò un pseudolinguaggio più "umano".

DEFINISCI Variabile1 come Numero.
DEFINISCI Variabile2 come Numero
DEFINISCI Variabile3 come Numero

ASSEGNA a Variabile1 il valore 5
ASSEGNA a Variabile2 il valore 3
ASSEGNA a Variabile3 il risultato della moltiplicazione tra il valore di Variabile1 e Variabile2

STAMPA il valore della Variabile3


In questo semplice esempio ho definito tre variabili numeriche, a due di loro ho assegnato dei valori ed alla terza ho assegnato come valore il risultato della moltiplicazione dei primi due. Infine ho stampato il contenuto della terza variabile.

Riscrivo ora lo stesso codice nel linguaggio compreso da arduino

int Variabile1;
int Variabile2;
int Variabile3;

Variabile1 = 5;
Variabile2 = 3;
Variabile3 = Variabile1 * Variabile2;

Serial.println(Variabile3);


Osserviamo intanto una prima cosa che è fondamentale per non farsi restituire una montagna di errori dalla IDE: tutte le righe terminano con il punto e virgola. Se ve lo dimenticate, nel momento in cui chiedete di caricare su Arduino il programma appena scritto, la IDE si rifiuta di proseguire.
Vediamo poi che le variabili numeriche sono state definite attraverso la parola chiave "int", che sta per Integer (intero). Sono variabili che possono contenere solo numeri interi, compresi tra -32,768 to 32,767. Altri tipi di variabili numeriche possono contenere numeri più grandi ed anche con i decimali.
Poi seguono le tre assegnazioni. La sintassi è elementare:
NomeDellaVariabile = ValoreDaAssegnare;
il ValoreDaAssegnare può essere esplicito, come nelle prime due assegnazioni, o il risultato di una operazione come nel caso della terza assegnazione (in questo caso la moltiplicazione, rappresentata dal carattere "asterisco").

L'ultima riga corrisponde a "STAMPA", ma la esaminiamo con più calma in futuro. L'unica cosa che osserviamo è che si tratta di una funzione (vedremo poi cos'è) che segue una operazione ma che non restituisce un valore e che richiede, come tutte le funzioni, che il valore su cui deve operare gli venga fornito tra le parentesi tonde.

Per oggi mi fermo qui. Se qualcuno volesse cominciare a dare una occhiata alla guida di riferimento al linguaggio, la trova qui https://www.arduino.cc/reference/en/

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda alimurimeta » 07/05/2018, 10:28

Grazie Carlo, un argomento non proprio semplice, però spiegato da te in modo chiaro e anche "divertente"

Aspetto le prossime "lezioni"
    Francesco G. - ALIMURIMETA
ImmagineImmagine
Immagine
Immagine
Avatar utente
alimurimeta
 
Messaggi: 1205
Iscritto il: 01/06/2013, 10:51

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 07/05/2018, 11:19

Grazie Francesco.
Mi rendo conto che non è un argomento banale, ma per affrontarlo con serenità è sufficiente la voglia di imparare cose nuove ed una mente aperta a ragionare secondo schemi nuovi, legati alla rigida logica delle macchine.
Di mio ci metto la consapevolezza che i numerosi tutorial, pur essendo spesso veramente ben fatti, partono tutti dal presupposto che l'interlocutore sia già un informatico. Per questo cerco di partire "da lontano", evitando (per quanto possa riuscirci) di dare per scontate tante cose.

Ma torniamo a bomba e per farlo copio brutalmente uno dei tanti esempi già disponibili nella IDE (Menu File, Examples, 01-basic, Blink).
Cerchiamo, per semplicità, di adottare il vocabolario usato in questo ambiente. La prima parola che impariamo è "sketch"; che in questo contesto è sinonimo di "programma". Quello che segue è lo sketch "Blink", che ha lo scopo di far lampeggiare il led presente sulla scheda.
Altra cosa importante è che il linguaggio è "case sensitive", cioè che per lui è differente scrivere in maiuscolo o in minuscolo. "Prova" e "prova" sono due cose diverse.

Codice: Seleziona tutto
/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}


La prima cosa che notiamo in alto è una sezione che inizia con i caratteri /* e termina con */. Questa sequenza di caratteri permette di fare una delle cose più importanti in programmazione: documentare, attraverso dei commenti, cosa fa un determinato spezzone di prigramma. Sono troppo cattivo se evito di tradurre dall'inglese il contenuto del commento iniziale?

Segue poi la definizione di due funzioni speciali, sempre presenti in uno sketch: setup() e loop(). la prima viene eseguita una sola volta all'avvio del programma, la seconda viene ripetuta continuamente, cioè appena termina viene automaticamente riavviata dall'inizio.
Nella setup() si fanno le impostazioni iniziali, cioè le cose da fare appena partiti e da non dover più fare per tutto il programma. Nell'esempio, nella setup() viene impostato in OUTPUT il pin LED_BUILTIN (costante di sistema che punta al pin ove è collegato il led). Questa operazione è necessaria perchè, per default e per ragioni di sicurezza, all'avvio tutti i pin sono predefiniti come INPUT. Come è intuibile, questa operazione va fatta una volta per tutte.

Nota di redazione: il pin LED_BUILTIN è, ovviamente, un pin di tipo digitale. Nel corso della programmazione ci imbatteremo spesso in parole chiave scritte in maiuscolo: si tratta di variabili speciali, definite COSTANTI in quanto il loro valore può essere solo letto ma non modificato, che ci aiutano nella programmazione. Alcune di queste parole sono HIGH, LOW, INPUT, OUTPUT.

Nella loop() invece troviamo quattro istruzioni che, in sequenza, impostano il pin LED_BUILTIN ad HIGH (cioè impostiamo la tensione di uscita a +5V, accendendo quindi il led), attendono 1 secondo (1000 millisecondi), impostano il pin LED_BUILTIN ad LOW (cioè impostiamo la tensione di uscita a 0, quindi spegnendo il led), attendono un altro 1 secondo. Visto che la loop() finisce quì, il sistema la riavvia immediatamente ed il ciclo continua all'infinito.

Capisco che questo può apparire banale, ma preferisco fare un passo alla volta.

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 07/05/2018, 11:59

L'esempio successivo, sempre preso dalla IDE, è "Fade" (dissolvenza).

Codice: Seleziona tutto
/*
  Fade

  This example shows how to fade an LED on pin 9 using the analogWrite()
  function.

  The analogWrite() function uses PWM, so if you want to change the pin you're
  using, be sure to use another PWM capable pin. On most Arduino, the PWM pins
  are identified with a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Fade
*/

int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}


Quì troviamo due novità: la prima è che troviamo delle istruzioni ancora prima della funzione setup(). Si tratta delle dichiarazioni delle variabili, cioè quelle istruzioni che occorrono alla IDE per sapere quali variabili vogliamo utilizzare all'interno delle varie funzioni. la sintassi è molto semplice: si indica prima il tipo di variabile (int in questo caso), poi si dichiara il nome che gli vogliamo assegnare e, facoltativo, il suo valore iniziale. Terminiamo, come al solito, con il punto e virgola.
La seconda novità è che nel codice troviamo sia l'esecuzione di alcune operazioni matematiche, che vi avevo anticipato in un mio messaggio precedente e che non credo occorra spiegare ulteriormente, che una istruzione FONDAMENTALE: la "if" ("se").
Questa istruzione da al programma la capacità di scegliere cosa fare in base al verificarsi di una determinata condizione. La sintassi è la seguente:
if (condizione) {
istruzione 1;
istruzione 2;
....
}else{
istruzione 3;
istruzione 4;
...
}

la "condizione" è una espressione matematica o logica che restituisce un risultato di tipo VERO o FALSO, 1 o 0, HIGH o LOW (sono valori tutti affini tra loro). Un esempio potrebbe essere
if (Variabile1 == 5) { ....
notare che l'operatore di comparazione per l'uguaglianza è "==" e non semplicemente "=", che invece eseguirebbe l'assegnazione del valore 5 alla Variabile1.
Gli operatori più comuni sono ">" (maggiore), "<" (minore), "!=" (non uguale). L'elenco completo degli operatori utilizzabili lo trovate sempre sulla Reference che vi ho indicato ieri, dove trovate anche gli operatori logici && e || (quest'ultimo usato nell'esempio) e che affronteremo in un secondo momento.

L'istruzione IF prosegue con una coppia di parentesi graffe, in cui racchiudiamo l'elenco delle istruzioni da eseguire se la "condizione" restituisce un valore "VERO" o affine. Opzionalmente, troviamo un "else" seguito da una seconda coppia di parentesi graffe. Quì possiamo inserire, se vogliamo, l'elenco delle istruzioni da eseguire nel caso in cui la "condizione" restituisca un valore "FALSO" o affine.

Analizzando le righe di codice, vediamo che la variabile brightness viene usata per memorizzare il valore di luminosità del led, la variabile fadeAmount contiene la quantità di aumento (o diminuzione, come vedremo più avanti) della luminosità da applicare ad ogni esecuzione della loop().
la riga
brightness = brightness + fadeAmount;
esegue proprio la variazione, sommando al valore preesistente della brightness il valore della fadeAmount ed assegnando il risultato alla brightness stessa.
le righe
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
invertono il valore di fadeAmount quando si verifica una delle due condizioni "brightness <= 0" o "brightness >= 255". Impariamo quì che l'operatore logico "||" significa OR, cioè "OPPURE". La condizione complessiva è vera se è vera almeno una delle due a destra e sinistra del "||".

In questo modo si evita che il valore di brightness possa diventare negativo o maggiore di 255. Infatti questi sono i due valori limite assegnabili al pin a cui è attestato un led esterno, che è un pin di tipo PWM, cioè che supporta la generazione di una uscita pseudo analogica.

Visto che ci siamo, diciamo che l'altro operatore logico è "&&" e significa "AND", cioè "E". La condizione complessiva è vera se sono vere entrambe le due a destra e sinistra del "&&".

L'ultimo operatore logico, che abbiamo già incontrato senza neanche accorgercene, è "!", che significa "NOT", cioè "NON" o "IL CONTRARIO DI". Inverte il valore VERO o FALSO di ciò che ha alla sua destra: !VERO equivale a FALSO.

Nulla ci vieta di usare più operatori nella stessa espressione, anche combinandoli con le parentesi tonde. Le regole di esecuzione sono le stesse dell'algebra di base studiata in terza media.

Per adesso mi fermo, preferisco aspettare i vostri commenti e le vostre domande.

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda Eupon » 08/05/2018, 22:56

Ottimo, mi procuro subito il materiale...
Eupon
 
Messaggi: 58
Iscritto il: 06/04/2017, 22:11

Re: Arduino - magie in pochi grammi e pochissimi Euro

Messaggioda carloroma63 » 12/05/2018, 15:48

Ciao,
vi ho lasciato alcuni giorni per sedimentare le informazioni che vi ho dato, quindi possiamo proseguire.
Lo scopo di questa mini lezione è di creare un semplice servo tester, cioè quell'oggettino che ci permette di muovere un servo (o anche pilotare l'ESC di un motore) con una semplice manopola di un potenziometro, permettendoci di mettere a punto un modello senza dover utilizzare la radio.

Come premessa spieghiamo come si comanda un servo e come funziona un potenziometro.

Un servo ha un connettore con tre fili: due sono l'alimentazione (tipicamente 5Volt), il terzo è l'ingresso PWM. Questo segnale è costituito da un impulso digitale (quindi i possibili valori sono solo 0V e +5V) , della durata variabile tra 700 e 2100 microsecondi. L'impulso viene ripetuto 50 volte al secondo, cioè ogni 20 millisecondi.
La durata effettiva dell'ìmpulso determina quale posizione deve assumere il servo: 700 microsecondi significa "tutto a destra", 2100 microsecondi significa "tutto a sinistra", o viceversa... non ricordo. Un impulso di 1500 microsecondi significa "servo al centro".
Questi valori (700, 2100, 1500) possono variare un pochino da servo a servo, quindi non sono da considerare come valori fissi ed immutabili.
Il servo riceve questo segnale e lo compara con la posizione attuale del braccetto. Se le due posizioni non corrispondono, allora aziona il motore e sposta il braccetto per portarlo alla posizione richiesta.

Un potenziometro è costituito da una striscia di materiale resistivo, cioè debolmente conduttore, su cui scorre un contatto mobile (cursore). In pratica si comporta come se fossero due resistenze in serie, la cui somma dei valori è il valore nominale del potenziometro (ad esempio 10.000 Ohm), e che costituiscono un "partitore resistivo" o "partitore di tensione" (https://it.wikipedia.org/wiki/Partitore_di_tensione) . Il valore delle due singole resistenze dipende dalla posizione del cursore, che azioniamo attraverso la sua manopola. Immaginiamo che colleghiamo il terminale destro del potenziometro al positivo dell'alimentazione del nostro circuito (per semplicità facciamo sempre riferimento ai 5V di alimentazione del servo) e il terminale sinistro del potenziometro al negativo dell'alimentazione, avremo che il terminale centrale, che corrisponde al punto di giunzione delle due resistenze, produrrà una tensione in uscita che è una percentuale della tensione di alimentazione ed è funzione della posizione del cursore: se il cursore è tutta a destra, il centrale sarà a +5V, se tutto a sinistra avremo 0V. Una posizione intermedia produrrà una tensione intermedia tra le due. Tutto questo dipende anche dall'eventuale circuito che colleghiamo all'uscita del potenziometro, che potrebbe alterare (anche pesantemente) la regola che ho appena definito. Per evitare questo, è opportuno che il carico applicato abbia una resistenza non inferiore a quella nominale del potenziometro.

A cosa ci serve tutto questo? Vediamo come costruire il nostro servo tester.
Utilizziamo il potenziometro per produrre una tensione variabile che applicheremo al nostro arduino e lui, di conseuenza, produrrà un segnale adatto a pilotare il nostro servo. Allo scopo introdurremo alcune nuove cose: il comando in analogRead(), il concetto di libreria ed il concetto di oggetto.

Partiamo, come al solito, da uno sketch di esempio. Userò lo sketch "Knob", disponibile tra gli esempio della IDE

Codice: Seleziona tutto
/*
 Controlling a servo position using a potentiometer (variable resistor)
 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

 modified on 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Knob
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  delay(15);                           // waits for the servo to get there
}


Analizziamo il codice.
Le prime righe ormai le riconosciamo, sono il commento racchiuso tra /* e */
Poi troviamo la riga
#include <Servo.h>
Significa che il nostro sketch deve includere una libreria di comandi aggiuntivi, cioè non nativi della IDE, che si chiama Servo.h. Le librerie sono delle cose estremamente diffuse in ambito di programmazione. Contengono delle funzioni aggiuntive specifiche per un determinato lavoro. Nel nostro caso, questa libreria aggiunge i comandi necessari a comandare facilmente un servo. Vedremo il dettaglio nel momento in cui lo utilizzaremo.

La riga successiva crea l'oggetto myservo utilizzando la tipologia Servo. Ma cos'è un "oggetto" in programmazione? E' la rappresentazione di un oggetto (fisico o virtuale, non importa) che può avere delle proprietà ed a cui possiamo far fare delle azioni. In altri ambienti di programmazione gli oggetti sono anche capaci di generare eventi, ma non nell'IDE di Arduino.
Cos'è una proprietà di un oggetto? Facciamo un esempio semplice. Andiamo a negozio e compriamo una lampadina (in programmazione "creiamo l'oggetto"). Questa lampadina avrà delle caratteristiche (tensione, potenza, colore, forma, etc), che in programmazione chiamiamo "proprietà". Alcune proprietà sono fisse (quindi le possiamo solo leggere): una volta comprata, non possiamo cambiarne la tensione a cui funziona, ma altre possono essere variabili. Ad esempio la proprietà "accesa" di una lampadina può valere "si" o "no" in funzione del suo stato reale. Analogamente possiamo leggere la proprietà "guasta" per sapere se è sana o se è fulminata.
Ad una lampadina possiamo chiedergli di accendersi o di spegnersi; in programmazione queste azioni si chiamano azioni o, più correttamente, "metodi".

Torniamo al nostro servo.
La riga #include <Servo.h> ci dice che abbiamo a disposizione un negozio dove comprare dei servi.
Con la riga "Servo myservo;" compriamo il servo myservo da quel negozio e ce lo portiamo a casa. Mi perdonino eventuali programmatori esperti che mi leggono se uso delle espressioni non proprio ortodosse, lo scopo di questi articoli è di rendere accessibile la materia a dei profani assoluti.

E' da notare che io potrei benissimo definire due o più servi, basta dargli nomi diversi e collegarli a pin diversi di Arduino.

Servo myservo1;
Servo myservo2;
Servo myservo3;


Le due righe che seguono definiscono un paio di variabili che utilizzerò nel corpo dello sketch.

int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin


Le due variabili conterranno il numero del pin a cui è collegato il potenziometro ed il valore di tensione che Arduino leggerà su quel pin.

Notate che ci sono dei commenti sulla destra, preceduti dal doppio slash //? Sono commenti su una sola riga, a differenza di quelli inclusi tra /* e */ che possono essere scritti su più righe.

Finalmente arriviamo alla setup(), che contiene solo la riga
myservo.attach(9);
Questa riga istruisce il sistema per dirgli che il nostro servo sarà collegato al pin 9 di Arduino. La libreria si occuperà di configurare correttamente quel pin, esonerandoci dal doverlo fare noi.

Se avessi avuto più servi, sarebbe stato sufficiente avere più righe:

myservo1.attach(9);
myservo2.attach(10);
myservo3.attach(11);

La loop() contiene infine il codice che viene eseguito continuamente.

val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there

La prima riga legge il valore del pin del potenziometro e mette il valore letto nella variabile val. Questo valore è un numero compreso tra 0 e 1023. Non rappresenta un valore assoluto di tensione, come sarebbe stato logico aspettarsi, in quanto la tensione di riferimento della analogRead potrebbe essere diversa dal default di 5V. Per adesso ci interessa solo sapere che 0 significa 0V, 1023 significa +5V ed ogni valore intermedio significa una tensione intermedia. Nella pratica, questo valore ci indicherà la posizione del cursore (manopola) del potenziometro. In questo momento Arduino legge la posizione del potenziometro e la userà più tardi. Se muovo il potenziometro dopo che Arduino ha fatto questa lettura, l'esito lo vedremo al prossimo ciclo.

La seconda riga converte il valore di val, che attualmente può valere da 0 a 1023, in un range compreso tra 0 e 180. Questo avviene perché l'oggetto myservo vuole essere istruito semplicemente con l'angolo (espresso in gradi) che deve assumere: 0 gradi significa tutto da una parte, 180 gradi tutto dall'altra e cosi via.

La terza riga "invoca" (altro verbo usatissimo in programmazione, sinonimo di "chiama" o "esegue") il "metodo" (cioè l'azione) write nel nostro servo, passandogli come parametro il valore di val. In questo momento il nostro servo si posiziona secondo la posizione del potenziometro letto due righe prima.

La quarta riga introduce semplicemente un ritardo di 15 millisecondi prima di ricominciare il ciclo, in tempo per poter generare un nuovo segnale per il nostro servo. Ricorderete che il segnale per il servo viene prodotto ogni 20 millisecondi.

Domande?

Carlo
carloroma63
 
Messaggi: 15
Iscritto il: 03/05/2018, 15:01

Prossimo

Torna a Diavolerie elettroniche

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite