Learning Shield

Presentiamo il nostro progetto di shield di apprendimento (Learning Shield) per Arduino UNO, realizzandone il PCB e scrivendo qualche codice di prova

Un modo pratico per apprendere la programmazione in Arduino è avvicinarsi a sketch già scritti ed a sensori molti diffusi e semplici da programmare. Realizzare una shield per l’apprendimento è un modo di proporsi per chi è agli inizi, dandogli il necessario per far pratica e iniziare anche a sviluppare i propri primi progetti. La Learning Shield si propone come uno strumento per i beginners, che possono trovare divertimento nell’assemblarla e nel programmarla. Questo progetto è stato realizzato grazie alla collaborazione di PCBWay che ha stampato per noi il PCB su cui lavoreremo. Potete anche voi stamparlo scaricandolo a questo LINK e andando sul sito https://www.pcbway.com/

Progetto

Il progetto della Learning Shield parte dall’idea che ci si debba divertire. Pensiamo che poter lavorare direttamente su un PCB, saldando da sè ogni singola parte, sia già il primo modo per imparare. Dovendo saldare ogni componente, l’utente è anche invogliato a distingue e conoscere le singole parti, trovando anche più comodo programmare senza l’ausilio delle breadboard e dei jumper. Abbiamo pensato di utilizzare le componenti più semplici e rapide da reperire per insegnare a programmare con la dev-board più conosciuta al mondo. Negli sketch di prova troverete l’utilizzo di sensori e attuatori, nonché dell’interfaccia I2C, molto comoda da usare.

  • Learning Shield



Componenti

Per la nostra Learning Shield abbiamo adoperato molte parti facilmente reperibili online, alcune sono sensori, altri attuatori, altre componenti necessarie ai collegamenti o al funzionamento. Partiamo dai LED, ben 3 di colorazione verde, bianca e rossa, a rappresentare la bandiera dell’Italia, ma voi potete anche optare per altre colorazioni.

Sulla shield è collocato anche un led RGB a catodo comune, che abbiamo visto in questo ARTICOLO. Vicino al Led RGB troviamo un fotoresistore (visto QUI), un buzzer passivo, il sensore analogico di temperatura LM35 e un pulsante di Reset.

Sul margine più esterno della Learning Shield troviamo collocato il sensore di temperatura e umidità DHT11, mentre al suo fianco lo spazio per collocare il dispositivo HC-05, una scheda che possiamo adoperare per fornire la connessione Bluetooth ad Arduino. Di fronte a questo troviamo uno switch che serve per dare corrente al modulo Bluetooth; esso è importante perchè prima di caricare lo sketch su Arduino dovrà essere posizionato nella posizione di OFF, in modo da spegnere il modulo. Questo, infatti, sfrutta l’interfaccia seriale, quindi quando è attivo, interferisce con il caricamento dello sketch. In evidenza troviamo anche un display OLED 128×64.

Oltre a queste componenti, troviamo 5 resistori da 220Ω, 2 resistori da 10KΩ e una morsettiera a vite per collegare una fonte di alimentazione esterna compresa tra i 5V e i 12V che passeranno tramite il pin Vin. Non sono mancati ovviamente i pin header per fissare il PCB su Arduino UNO.

Lista componenti su Amazon:

Lista componenti su Aliexpress:



Collegamenti

Lo schema dei collegamenti della Learning Shield non è complesso, tuttavia merita una delucidazione, soprattutto perché questo articolo è rivolto ai meno esperti. Partiamo affermando che l’intero sistema è alimentato a 5V, senza escludere sensori e attuatori, chiarendo però che per alcuni di essi è richiesto necessariamente l’utilizzo di alcuni resistori per ridurre la tensione. Partiamo dai LED: il led verde è connesso al pin 13 e non necessita di resistore, mentre il led bianco e il led rosso, connessi rispettivamente ai pin 12 e 4, richiedono per ciascuno un resistore da 220Ω. Il LED RGB richiede anch’esso resistori da 220Ω; ben 3 resistori per il pin RED (9), GREEN(10), BLUE (11). I pin appena annoverati sono PWM, quindi modulari, esattamente come il pin 3 a cui è connesso il buzzer passivo, in modo da modularne il segnale e variare la frequenza del suono da emettere. L’ultimo pin digitale usato è il 2, a cui abbiamo collegato il sensore DHT11, adoperando un resistore da 10KΩ tra il pin del segnale del sensore e il suo pin di alimentazione. Un discorso a parte lo facciamo per il display OLED, che richiede due pin per il dati, ossia i pin SDA e SCL, adoperati per l’interfaccia I2C. Per il fotoresistore abbiamo usato il pin analogico A0, ponendo un resistore da 10KΩ in pull-up (ossia tra il Vcc e il pin in ingresso). In ultimo, il sensore LM35 viene connesso al pin analogico A1. Il Bluetooth richiede una minima attenzione nei collegamenti: il suo pin RX va al pin TX di Arduino, mentre il suo pin TX va al pin RX di Arduino.

Learning Shield

Una volta chiariti i collegamenti della Learning Shield, possiamo passare a saldare le componenti sul PCB, a tal proposito ecco lo schema dei collegamenti su PCB. Per la realizzazione del PCB, una volta entrati sul sito di PCBWay, sarà importante tenere segnate le misure (69,00 mm x 53,750 mm) e indicare che si tratta di un PCB a 2 layer (2 strati). Carichiamo a questo punto il file Gerber che potete scaricare QUI.

Learning Shield



Codice

I codici che adopereremo saranno piuttosto semplici, ma rammentiamo ancora una volta che questo è un progetto rivolto all’apprendimento. Gli sketch di prova sono disponibili, corredati dalle librerie necessarie, scaricandoli a questo LINK. Non li esamineremo tutti in questa sede, infatti lasceremo gli ultimi due per un altro articolo. Lo sketch code_1-1 vi permetterà di accendere e spegnere contemporaneamente il led verde, bianco e rosso ogni 2 secondi. Ricordiamo che la funzione pinMode indica la direzione del pin digitale, che sarà di OUTPUT poiché Arduino invia un segnale verso l’attuatore. Nel caso contrario, ossia quando Arduino riceve un segnale da un sensore, di parla di INPUT. Nella funzione di VOID LOOP, dove le istruzioni vengono ripetute, con la funzione digitalWrite inviamo un segnale digitale (HIGH) per accendere il led, indicando con il numero il pin su cui interagiamo.


void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(4, OUTPUT);

}

void loop() {
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(4, HIGH);

delay(2000);

digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(4, LOW);

delay(2000);

}

Nello sketch code_1-2 accenderemo i led in ordine alternato, quasi a simulare un semaforo. Quando detto pocanzi sulle funzioni pinMode e digitalWrite è ripreso anche qui.


void setup() {
pinMode(4, OUTPUT); // Impostiamo la direzione del PIN 4 su OUTPUT perchè emetta un segnale

pinMode(12, OUTPUT); // Impostiamo la direzione del PIN 12 su OUTPUT perchè emetta un segnale

pinMode(13, OUTPUT); // Impostiamo la direzione del PIN 13 su OUTPUT perchè emetta un segnale
}

// la funzione LOOP ripete all'infinito le operazioni
void loop() {

digitalWrite(13, HIGH); // Accende il LED verde
digitalWrite(12, LOW); // Spegne il LED bianco
digitalWrite(4, LOW); // Spegne il LED rosso
delay(5000); // attesa di 5 secondi

digitalWrite(13, LOW); // Spegne il LED verde
digitalWrite(12, HIGH); // Accende il LED bianco
digitalWrite(4, LOW); // Spegne il LED rosso
delay(2000); // attesa di 2 secondi

digitalWrite(13, LOW); // Spegne il LED verde
digitalWrite(12, LOW); // Spegne il LED bianco
digitalWrite(4, HIGH); // Accende il LED rosso
delay(5000); // attesa di 5 secondo
}

Nello sketch code_2-1 impareremo ad usare il monitor seriale, attivato dall’istruzione Serial.begin(9600), e a leggere i segnali provenienti dai pin analogici grazie alla funzione analogRead, seguita dal pin analogico che andiamo ad utilizzare. Siccome i valori analogici sono numeri interi compresi tra 0 e 1023, non sempre è facile leggerli in maniera chiara. Per questa ragione useremo la funzione di mappatura MAP, che preleverà i valori della variabile sensor e li riporterà in proporzione in valori compresi tra 0 e 100, trasformandoli in percentuale. Tramite poi Serial.print stamperemo i valori relativi. Tra virgolette va il testo che vogliamo stampare, mentre la variabili vanno semplicemente riportate tra le parentesi tonde. Quando utilizziamo Serial.println il valore va stampato e poi si va a capo.


void setup() {
Serial.begin(9600);

}

void loop() {
int sensor = analogRead(A0);
int luce = map (sensor, 0, 1023, 100, 0);

Serial.print("Analog: ");
Serial.print (sensor);
Serial.print("\tLuce: ");
Serial.print (luce);
Serial.println("%");

delay(3000);

}



Nello sketch code_2-2 impariamo invece ad adoperare quanto spiegato prima adoperandolo nell’istruzione di comando IF/ELSE, che verifica se una determinata condizione si verifica ed esegue una relativa istruzione. Nel nostro caso, quando il valore analogico di luce sarà superiore a 500, si accenderà il led collegato al pin 13; nel caso contrario resterà spento.

void setup() {

pinMode (13, OUTPUT); //LED
Serial.begin(9600); // avvio il monitor seriale
}

void loop () {
int luce = analogRead (A0); // Variabile luce che legge dal pin analogico A0

if (luce > 500){ // se il valore di luce è superiore a 500 accendi LED
digitalWrite (13, HIGH);
}
else{
digitalWrite (13, LOW);
}

Serial.println(luce); // stampo il valore di luce
delay (200);
}

Lo sketch code_3-1 ci permetterà di apprendere come utilizzare il buzzer passivo. Esso, come detto, necessita di essere collegato ad un pin PWM (Pulse Width Modulation), così da modulare la frequenza sonora che può eseguire. Per farlo, necessitiamo della funzione tone(), al cui interno fa specificato il pin a cui è connesso il buzzer, la frequenza sonora, la sua durata.


void setup() {
pinMode(3, OUTPUT);
}

void loop() {

tone(3,850,1000);
delay(150);
tone(3,650,1000);
delay(150);

}

Nello sketch code_3-2 mettiamo in pratica quanto visto finora, aggiungendo le istruzioni per programmare il sensore analogico di temperatura LM35, il cui valore analogico va moltiplicato per 0.48875, al fine di ottenere un valore in gradi Celsius. Quando la temperatura sarà superiore a 34 gradi, si attiverà il buzzer passivo e si accenderà il led al pin 13.

</pre>
const int limite = 34.00; // limite del sistema

void setup() {
pinMode (3, OUTPUT); // direzione del pin buzzer
pinMode (13, OUTPUT); // direzione del pin led
Serial.begin (9600); // avvio del monitor seriale
}

void loop() {
iint sensor = analogRead(A1); // rilevo il valore da A1

float t = sensor * 0.48875;
Serial.println(t); // stampo su monitor seriale

if (t > limite) { // se il valore luce supera il limite...

digitalWrite(13, HIGH); // accendo il led e faccio suonare il buzzer
tone(3,400,1000);
delay(500);
tone(3,650,1000);
delay(500);
}
else {

digitalWrite(13, LOW); // altrimenti non fa nulla
}

}
<pre>

Lo sketch code_4 ci permetterà di provare il led RGB a catodo comune. All’interno di questo codice troviamo la funzione analogWrite, il cui come trae in inganno. Difatti, essa è adoperata per modulare il segnale digitale dei pin digitali PWM, con valori compresi tra 0 e 255. La modulazione di questi valori permetterà al led RGB di cambiare colore. Per far cambiare i valori, però, ci servirà un’istruzione di comando molto diffusa: il ciclo FOR. All’interno di questo ciclo, le istruzioni vengono ripetute fin quando non si raggiunge una determinata condizione. Nel nostro caso, la variabile i, uguale a 0, viene incrementata di una unità finché non raggiunge il valore 255. Quindi, il ciclo varierà la luce del led RGB, da quando la variabile i ha valore 0, fino a quando non avrà raggiunto il valore 255, poi si interromperà ed il codice prosegue. Nel linguaggio C/C++ l’istruzione i+=1 o i++ significano letteralmente “incrementa i di una unità per volta“.

</pre>
#define BLUE 11
#define GREEN 10
#define RED 9

void setup()
{
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
digitalWrite(RED, HIGH);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
}

int redValue;
int greenValue;
int blueValue;

void loop()
{
#define delayTime 10

redValue = 255;
greenValue = 0;
blueValue = 0;

for (int i = 0; i < 255; i += 1)
{
redValue -= 1;
greenValue += 1;

analogWrite(RED, redValue);
analogWrite(GREEN, greenValue);
delay(delayTime);
}

redValue = 0;
greenValue = 255;
blueValue = 0;

for (int i = 0; i < 255; i += 1)
{
greenValue -= 1;
blueValue += 1;

analogWrite(GREEN, greenValue);
analogWrite(BLUE, blueValue);
delay(delayTime);
}

redValue = 0;
greenValue = 0;
blueValue = 255;

for (int i = 0; i < 255; i += 1)
{

blueValue -= 1;
redValue += 1;

analogWrite(BLUE, blueValue);
analogWrite(RED, redValue);
delay(delayTime);
}
}

Passiamo ora allo sketch code_5, all’interno del quale impariamo ad inizializzare e stampare valore su un display OLED con chip SSD1306. Abbiamo già visto come adoperare questo display in questo ARTICOLO. Il Display OLED 0.96″ è dotato di un chip SSD1306 ed ha una risoluzione di 128×64 pixel, il che lo rende un ottimo sostituto per il display LCD I2C. Questo display, oltre ai pin GND e VCC per collegarlo ai 3,3V o ai 5V, possiede i pin SDA (dati) e SCK (clock) per collegarlo alla dev-board tramite interfaccia I2C o SPI. La colorazione dei contenuti di questo modello è divisa in due sezioni, la superiore è gialla, mentre la parte inferiore è in blu. Non è possibile cambiare, invertire o utilizzare solo uno dei due colori. Nel nostro esempio, adopereremo anche il sensore LM35 e stamperemo la temperatura rilevata sul display OLED.

 

</pre>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RESET 18
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.display();
display.clearDisplay();
}

void loop() {
int sensor = analogRead(A1);

float t = sensor * 0.48875;

Serial.print("Temp = ");
Serial.print(t);
Serial.println("°C");

display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("LM35");

display.setTextSize(3);
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
display.setCursor(0, 25);
display.print(t);
display.println(" C");

display.display();

delay(1000);

}
<pre>

Proseguiamo vedendo come programmare il sensore digitale DHT11 con lo sketch code_6. Includiamo le librerie necessarie e definiamo a quale pin è collegato (2) e che tipo di DHT usiamo (nel nostro caso il DHT11). Nel VOID SETUP avviamo il sensore (dht.begin) e nel VOID LOOP tramite la funzione dht.readHumidity() e la funzione dht.readTemperature() leggiamo i valori di umidità e temperatura, stampati poi su monitor seriale.


#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
Serial.begin(9600);

dht.begin();

}

void loop() {
int h = dht.readHumidity();
int t = dht.readTemperature();

Serial.print("Temperatura: ");
Serial.print(t);
Serial.print("C, Umidità: ");
Serial.print(h);
Serial.println("%");

delay(1000);

}

Ora che abbiamo imparato a configurare il DHT11, arriviamo al code_7 per inviare allo smartphone i dati del sensore tramite Bluetooth. Lo sketch è praticamente identico al precedente, salvo che creiamo una stringa chiamata terminal su cui scriviamo i dati rilevati dal sensore. La stringa sarà inviata, tramite monitor seriale, al modulo HC-05. Prima di caricare lo sketch su Arduino UNO, assicuratevi che lo switch sia sulla posizione per spegnere il modulo HC-05 (il led integrato sul modulo non lampeggia). Caricato lo sketch, spostate lo switch sulla posizione di accensione del modulo per farlo funzionare.


#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

String terminal;

void setup() {
Serial.begin(9600);

dht.begin();
}

void loop() {
int h = dht.readHumidity();
int t = dht.readTemperature();

terminal = "Meteo: " + String (t) + "°C " + String (h) + "%" ;

Serial.println (terminal);

delay(2000);

}

Per leggere i valori in arrivo dalla nostra Learning Shield, associamo il modulo allo smartphone come qualsiasi dispositivo Bluetooth; il pin è 1234. Scarichiamo poi l’applicazione Serial Bluetooth Terminal disponibile su Google Play Store e installiamola.

Entriamo ora nell’app, connettiamo il dispositivo e iniziamo a ricevere i dati sul nostro smartphone.

Learning Shield




L’ultimo codice è il code_8, un progetto di stazione meteo con Bluetooth. Utilizzeremo tutti i sensori montati per rilevare luminosità, umidità e temperatura, facendo la media di quest’ultima tra i valori rilevati dal DHT11 e dal sensore LM35.


#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

String terminal;

void setup() {
Serial.begin(9600);

dht.begin();
}

void loop() {

int sensor1 = analogRead(A0);
int luce = map (sensor1, 0, 1023, 100, 0);

int sensor2 = analogRead(A1);
float t1 = sensor2 * 0.48875;

int h = dht.readHumidity();
int t2 = dht.readTemperature();

float tmed = (t1 + t2) / 2;

terminal = "Meteo: ";
terminal += "Temperatura " + String (tmed) + "°C ";
terminal += "Umidità " + String (h) + "% ";
terminal += "Luce " + String (luce) + "%";

Serial.println (terminal);

delay(2000);

}

Come nell’esempio di prima, adoperiamo l’app Serial Bluetooth Terminal per visualizzare i dati sullo smartphone.

Learning Shield