Errori comuni nell’uso di Arduino – inserire void davanti alla funzione chiamata

Ho rilevato che alcune volte alcuni allievi nella chiamata di una funzione inseriscono il tipo restituito dalla funzione davanti alla funzione chiamata, ciò può essere fatto solamente nella dichiarazione del prototipo di funzione.
Il prototipo di una funzione costituisce una dichiarazione della funzione e fornisce al compilatore le informazioni indispensabili per gestire la funzione.
Nella definizione di una funzione, viene indicato anche ciò che deve fare la funzione quando viene invocata, specificato nel corpo della funzione.

Lo sketch che segue non chiama la funzione miSentoFortunato()

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

void loop() {

  // inserendo void nella chiamata di funzione
  // NON verrà chiamata la funzione miSentoFortunato() 
  void miSentoFortunato();
}

void miSentoFortunato() {
  Serial.println("Oggi mi sento fortunato :-)");
}

Attenzione che in fase di compilazione e trasferimento non verrà restituito nessuno errore da parte del compilatore quindi l’individuazione dell’errore in un codice più esteso potrebbe essere di difficile individuazione.

Codice corretto

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

void loop() {

  // eliminando void nella chiamata di funzione
  // verrà chiamata la funzione miSentoFortunato() 
  miSentoFortunato();
}

void miSentoFortunato() {
  Serial.println("Oggi mi sento fortunato :-)");
}

Esercizio 1

Perché il codice che segue non restituisce errore?

void setup() {
  Serial.begin(9600);
}
void loop() {
  void miSentoFortunato();
}

Esercizio 2

Perché il codice che segue non restituisce errore?

void setup() {
  Serial.begin(9600);
}
void loop() {
  // :-)
}
void miSentoFortunato();

Esercizio 3

Perché il codice che segue restituisce errore?

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

  void miSentoFortunato() {
  // :-)
  }
}

Per i miei allievi: il primo che risponde correttamente vince una scheda Arduino (non è uno scherzo) 😉

Microlearning con Instagram a supporto della didattica a distanza

E’ da tempo che stavo pensando di sviluppare soluzioni per realizzare del microlearning, attività che vorrei utilizzare per rafforzare competenze fornite durante videolezioni proposte in modalità sincrona ed asincrona e durante le lezioni in presenza (quando ci saranno).

Ma perché sto pensando al microlearning?
Il sistema microlearning trova largo impiego nella formazione a distanza aziendale, ma è possibile, secondo me modificarlo anche per supportare la didattica che normalmente svolgiamo con i nostri studenti a scuola o online.

In queste settimane come appunti in disordine sul mio Evernote in un blocco che ho chiamato “rinnovamento didattico” sto scrivendo una serie di frasi che spero andranno a strutturare poi un progetto più preciso:

“il prossimo anno scolastico sarà complicato, bisognerà recuperare e far fronte ai problemi legati al mantenimento della distanza sociale… quindi bisogna costruire qualcosa che affianchi la didattica online ed in presenza come la intendiamo adesso, bisogna costruire strumenti che permettano di atomizzare il progetto educativo al fine di facilitare la personalizzazione in funzione delle necessità dello studente soprattutto in questo periodo di crisi”.

Progetto che credo poi verrà strutturato applicando il metodo iterativo: “imparare facendo”

NON imparo ad usare prima lo strumento
e POI lo uso
ma lo uso SUBITO per spiegare
e usandolo IMPARO

… e quindi alla fine preso tra i mille lavori applicherò il metodo “imparare facendo” 🙂

Ma come opererò?

L’idea è quella di creare brevi contenuti, testuali o video, dedicati ad un singolo argomento.
Nel caso di contenuti testuali banalmente anche fotografie di appunti, disegni fatti a mano o video brevissimi non più lunghi di 3-5 minuti.

Quindi la parola chiave è: “atomizzare”, concetto che per altro avevo utilizzato anni fa per la progettazione della didattica laboratoriale della robotica.

Tutto ciò inoltre credo sia utile perché sfrutta di più la memoria di lavoro, faccio riferimento al “modello tripartito” di Baddeley ed Hitch.

Quando dico “atomizzare” intendo lo sviluppo di mattoncini cognitivi che si aggiungono ai mattoni che vengono “posati” durante le lezioni normali e con lo studio degli studenti a casa.

Tutto ciò però non deve, da parte dello studente, essere di difficile fruizione, non deve dipendere dal dispositivo utilizzato o dal sistema operativo. Inoltre se possibile non deve richiedere una formazione all’uso dello strumento tecnologico.

Ho analizzato per mesi la modalità ed i tempi di utilizzo da parte degli studenti di: smartphone, computer desktop e portatili, ma la cosa che ho analizzato più di tutte è il modo con cui condividono appunti e i momenti in cui leggono gli appunti che tra di loro si condividono, condivisione che in moltissimi casi avviene mediante fotografie di appunti scambiati attraverso gruppi WhatsApp.

Durante i miei corsi, quando parlo di organizzazione del lavoro didattico e della progettazione di contenuti, parlo di atteggiamento minimalista nella scelta dei metodi e degli strumenti e quindi per sviluppare un’azione didattica in cui è presente anche il microlearning, ho pensato di concentrarmi su strumenti usabili da tutti, anche se questi non presentano le funzionalità utili per coprire tutte le necessità di progetto del docente.

Cosa usare? Ho sperimentato di tutto, ma dopo tanto peregrinare sono ritornato sullo strumento che in origine avevo selezionato, Instagram, alcuni diranno: “bella scoperta!”, o ancora “ma vuoi fare didattica con Instagram?” attenzione che ciò che voglio fare non è fare didattica SOLO CON Instagram, ma utilizzare ANCHE Instagram per aggiungere qualcosa di più alla didattica che svolgo.

… e poi… sto osservando come molti colleghi che stimo e che lavorano in altre nazioni stanno operando con le loro classi e mi sono convinto che è essenziale provarci.

Quindi da cosa inizio?
Senza ansia e con i giusti tempi inizio a sintetizzare appunti cartacei sull’elettronica: Arduino, elettrotecnica, elettronica, uso di applicativi ecc… e li propongo ai miei studenti sul mio canale Instagram e pian pianino costruisco.

Inizio oggi! Funzionerà? Non so, ma voglio provarci.

Buon Making didattico a tutti.

Errori comuni nell’uso di Arduino – usare troppa memoria RAM

Nella collezione degli errori nell’uso di Arduino aggiungo l’uso improprio della memoria Flash (RAM) disponibile all’interno del microcontrollore. La dimensione della memoria RAM differisce sulle varie schede Arduino, nell’esempio prendo in considerazione la scheda Arduino UNO R3.

Nell’esempio che segue, un semplice Blink, viene dichiarato un array di interi che in fase di compilazione provocherà un errore di dimensione troppo grande dell’array:

// laMiaCollezione è un array di interi che ha una dimensione di:
// (20000x16)/8=40kB
// superiore alla RAM disponibile in un Arduino UNO R3 che è di 32kB 
// si faccia riferimento al seguente link:
// https://www.arduino.cc/en/tutorial/memory

int laMiaCollezione[20000];

void setup() {
  Serial.begin (9600);
  Serial.println ("Avvio programma");
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000); 
}

Dovreste rilevare l’errore indicato nell’immagine che segue:

Se non vedete il led L (connesso al pin13) lampeggiare o rilevate un errore simile a quello indicato nell’immagine sopra, vuol dire che state utilizzando troppa memoria RAM. Fate attenzione che molte librerie utilizzano la RAM (ad es. Libreria di schede SD, librerie LCD, ecc.).

Nel link allegato nello sketch di esempio potete consultare la pagina specifica di Arduino.cc in cui viene spiegato come viene usata la memoria sull’Arduino UNO R3:

  • Flash 32k byte (di cui 0.5k usato per il bootloader)
  • SRAM 2k byte
  • EEPROM 1k byte

Nel dettaglio:

  • 32kB (1024×32=32768bit) di memoria Flash di cui 0,5 kB (equivalenti a 512 bit) sono dedicati al bootloader.
    Il microcontrollore presente sull’Arduino UNO R3 è un ATmega328P. All’interno della memoria Flash (RAM) del microcontrollore è presente una zona di memoria riservata in cui viene allocato il Bootloader, un programma che ha il compito di controllare se dopo il reset della scheda vie è la possibilità di caricare in memoria, tramite la USB, un nuovo programma creato dall’utente. Se non è presente nessun nuovo programma il controllo passa all’inizio del programma presente in memoria, quello precedentemente caricato e viene eseguito e il controllo non ritorna più al Bootloader fino a quando non si esegue un nuovo reset della scheda, reset che avviene quando viene caricato una nuovo programma dell’utente.
  • 2 KB di SRAM (2048 bit), è una RAM statica volatile utilizzata per gestire le variabili contenute nel programma (sketch) creato dall’utente e i dati che servono al microcontrollore per funzionare.
  • 1KB di EEPROM (1024 bit) memoria i cui valori vengono mantenuti anche quando la scheda viene spenta.

Esercizio

Nello sketch riportato sopra quel è il numero massimo di interi che può ospitare l’array laMiaCollezione affinché non si incorri nell’errore di memoria RAM piena?

5 min al giorno di sperimentazione con M5Stack mini – Sensore TOF

Buoni propositi: utilizzare 5 minuti della mia giornata di lavoro per sperimentare alcuni utilizzi di M5Stick Mini, ma anche per sollecitare la curiosità e voglia di sperimentazione da parte dei miei studenti… pillole tecnologiche 🙂
Recentemente ho acquistato un sensore ToF (Time of Flight: tempo di volo) VL53L0X con connettore GROVE per effettuare misure precise sulla della distanza di ostacoli con M5Stick mini.

Un sensore ToF effettua un conteggio del tempo totale di volo dei fotoni dal momento in cui vengono emessi da un piccolissimo raggio laser al momento in cui viene rilevata la riflessione su un fotodiodo collocato sul sensore.
In generale il tempo di volo (spesso indicato con TOF, dall’inglese Time Of Flight) indica la misura del tempo impiegato da un oggetto, una particella o un’onda (elettromagnetica, acustica, elettromagnetica o di altro tipo) per percorrere una certa distanza in un mezzo determinato. (fonte: Wikipedia)
Il sensore è in grado di fornire una misura molto precisa della distanza, indipendentemente dalla riflettanza della superficie incidente.

Il sensore ToF di cui dispongo è un VL53L0X che incorporato un emettitore Laser VCSEL ed un fotodiodiodo ricevitore SPAD. Il laser è in grado di emettere impulsi a 940 nm (prossimi al campo infrarosso). Il fotodiodiodo SPAD è estremamente sensibile al singolo fotone e grazie alla schermatura di cui è costituito riceve soltanto la lunghezza d’onda di 940 nm del laser.

Il sensore che sto utilizzando sul mio M5Stick mini connesso in I2C, è in grado di misurare la distanza di oggetti dai 30mm a 800 mm, ma in commercio è possibile trovare sensori che sono in grado di misurare con precisione distanze fino a 2m. Campi di impiego: telecamere, macchine fotografiche, smartphone e sensoristica industriale.

L’integrato elettronico VL53L0 viene prodotto dalla ST Microelettronics, seguendo il link trovate maggiori informazioni tecniche.

Durante le nostre sperimentazioni elettroniche a scuola, spesso usiamo sensori basati sull’uso di un diodo LED emettitore di infrarossi ed un fotodiodi ad infrarossi ricevente  che sono influenzati dalla luce ambiente e dall’assorbimento della luce rilevata. Stessa cosa capita nel caso si utilizzi sensori ad ultrasuoni, dove la misura della distanza è fortemente dipendente dall’angolo di incidenza dell’onda ultrasonica e dalla fonoassobenza degli ostacoli di cui si vuole misurare la distanza.

Per maggiori informazioni sulle nozioni di base sull’utilizzo dei sensori ToF vi rimando al breve articolo di digikey dove oltre a presentare la tecnologia ToF, trovate dettagli interessanti su altre tecnologie utilizzate per la rilevazione della distanza degli ostacoli.
Nell’articolo si ripercorre la storia della sensistica per la misurazione degli ostacoli:

  • sensori di prossimità delle prime macchine fotografiche della Polaroid
  • sensori ad ultrasuoni come gli SR-HC04 che utilizziamo nelle sperimentazioni con Arduino
  • sensori ad infrarossi della Sharp
  • sensori ToF

Trovate il sensore ToF VL53L0X su schede che possono essere comodamente connessi in I2C ad Arduino a costi estremamente contenuti.

L’utilizzo del sensore ToF con M5Stick mini è estremamente semplice.

E’ sufficiente aggiungere tra i sensori disponibili il ToF, così come indicato nell’immagine che segue ed utilizzare così l’istruzione che permette di misurare la distanza dell’ostacolo.

Nel programma indicato di seguito viene misurate la distanza dell’ostacolo è nel caso in cui la misura sia inferiore ai 50 mm viene acceso il LED rosso disposto sull’M5Stick mini.

Ovviamente sviluppare ora un sistema per valutare il tempo necessario per lavarsi le mani, così come indicato nell’articolo: Arduino – Esercizio: Realizzare un timer per il lavaggio delle mani risulta semplicissimo.

Buona sperimentazione a tutti 🙂

Arduino – Esercizio: Realizzare un timer per il lavaggio delle mani

Di seguito mostro parte della soluzione agli esercizi assegnati ai miei studenti negli scorsi giorni in riferimento alla progettazione di un semplice dispositivo di automazione da collocare in bagno in prossimità del lavandino, in grado di rilevare ad una distanza minima fissata la presenza delle mani e l’avvio di un timer che mostra il trascorrere del tempo. L’indicazione del tempo che trascorre viene realizzata con un servomotore a cui dovrà poi essere fissata una lancetta e che mostra il trascorrere del tempo su una scala graduata. Il tempo di lavaggio viene fissato a 30 secondi. Sulla serial monitor dovrà essere indicato lo stato di avvio del sistema ed il tempo.

Soluzione

Controllo servomotore

// Prof. Maffucci Michele
// gestione servomotore

#include <Servo.h>

int pos = 0;

Servo mioServo;

// scrivere pos +=1 è la stessa cosa che scrivere pos = pos + 1

void setup()
{
  mioServo.attach(9);
}

void loop()
{
  // muove il servo da 0 a 180 gradi
  // con passi di 1 grado
  
 for (pos = 0; pos <= 180; pos += 1) {
    // viene detto al servo di posizionarsi
    // nella posizione inserita nella variabile 'pos'
    mioServo.write(pos);
    // attende 15 ms wait 15 ms
	// per far raggiungere il sevo la posizione
    delay(15); // attesa di 15 millisecondi
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    // viene detto al servo di posizionarsi
    // nella posizione inserita nella variabile 'pos'
    mioServo.write(pos);
    // attende 15 ms wait 15 ms
	// per far raggiungere il sevo la posizione
    delay(15); // attesa di 15 millisecondi
  }  
}

Controllo sensore ultrasuoni

// Prof. Maffucci Michele
// Impostazione sensore ultrasuoni

// distanza minima dell'ostacolo (in cm)

const int distanzaMinima = 20;
int misuraDistanza = 0;

long durata;          // durata dell'impulso
long distanza;        // distanza dell'oggetto
int pin_segnale = 7;  // pin Arduino a cui è collegato il sensore SR04
int pin_trig = 10;    // pin Arduino a cui è collegato il sensore SR04


void setup()
{
    Serial.begin(9600);
	pinMode(pin_trig, OUTPUT);
  	pinMode(pin_segnale, INPUT);
  	Serial.println("Sensore ad ultrasuini");
}

void loop()
{
  Serial.print("Distanza ostacolo: ");
  Serial.println(distanzaOstacolo());
  delay(100);
}

// rilevazione distanza ostacolo

// misura la distanza dell'ostacolo
long distanzaOstacolo()
{
  digitalWrite(pin_trig, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin_trig, LOW);
  durata = pulseIn(pin_segnale, HIGH);
  distanza = (durata / 2) / 29.1;
  delay(100);
  return distanza;
}

Timer lavaggio mani

// Prof. Maffucci Michele
// realizzazione di un timer
// per il lavaggio delle mani
// in un tempo di 30 secondi

#include <Servo.h>

// Impostazione servomotore
int pos = 0;

Servo mioServo;

// Impostazione sensore ultrasuoni

// distanza minima dell'ostacolo (in cm)

const int distanzaOstacolo = 20;
int misuraDistanza = 0;

long durata;          // durata dell'impulso
long distanza;        // distanza dell'oggetto
int pin_echo = 7;     // pin Arduino a cui è collegato il sensore SR04
int pin_trig = 10;    // pin Arduino a cui è collegato il sensore SR04

void setup() {
    Serial.begin(9600);
    mioServo.attach(9);
	pinMode(pin_trig, OUTPUT);
  	pinMode(pin_echo, INPUT);
  	
// Posizionamento iniziale del servo
  
  mioServo.write(180);
  delay(500);
  mioServo.write(0);
  delay(500);
  mioServo.write(180);

// Avvio alla partenza
  
  Serial.println("Avvio programma lavaggio mani"); 
}

void loop() {
  
  // Se la distanza delle mani dal rubinetto è
  // inferiore alla distanzaOstacolo si avvia il timer
  
    if (misuraDistanzaOstacolo() < distanzaOstacolo) {
    	contoAllaRovesciaServo();
  }
  delay(100);
}


// Conto alla rovescia
// sposta il servo di 6 gradi ogni secondo

void contoAllaRovesciaServo() {
  Serial.println("Conto alla rovescia: ");
  int passi = 30;
  
  for (int i = passi; i >= 0; i--) {

    mioServo.write(i * 6);
    delay(1000);
    Serial.print(i);
    Serial.println(" sec");

  }

  // azzeramento del servo.
  // Le mani sono pulite
  mioServo.write(180);
  delay(500);
}

// misura la distanza dell'ostacolo
long misuraDistanzaOstacolo()
{
  digitalWrite(pin_trig, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin_trig, LOW);
  durata = pulseIn(pin_echo, HIGH);
  distanza = (durata / 2) / 29.1;
  delay(100);
  return distanza;
}

Esercizio 1

Modificare lo sketch precedente aggiungendo due LED, verde e rosso. Lo stato di riposo, timer non funzionante, deve essere indicato dal LED verde acceso e Led rosso spento, mentre lo stato di funzionamento del timer deve essere evidenziato dal LED verde spento e LED rosso acceso.

Esercizio 2

Modificare lo sketch precedente aggiungendo due LED, verde e rosso e un buzzer. Lo stato di riposo, timer non funzionante, deve essere indicato dal LED verde acceso e Led rosso spento, all’avvio del timer il buzzer deve emettere una nota ad una frequenza fissata per un tempo di  1 secondo. Lo stato di funzionamento del timer deve essere evidenziato dal LED verde spento e LED rosso acceso, allo scadere del tempo di lavaggio deve essere emessa una nota di durata 1 secondo ad una frequenza diversa dalla nota di avvio.

Esercizio 3

Realizzare l’esercizio 2 con le medesime caratteristiche e componenti, però sostituendo il servomotore usato come indicatore, con un display LCD 16×2 che indichi il trascorrere del tempo.

Buon lavoro 🙂