Archivi tag: led

BBC microbit – Pixel per Pixel – uso dell’Istruzione plot

Nel corso delle nostre avventure creative durante il corso “Carta, Cartone e Coding”, abbiamo esplorato attività in cui la creatività e l’arte incontra la tecnologia, trasformando idee astratte in realtà tangibili. Uno degli strumenti che abbiamo utilizzato per dare vita alle nostre creazioni è il BBC micro:bit.

Tra le numerose domande che mi avete inviato via mail alcune fanno riferimento all’uso dell’istruzione “plot”. Capisco che, per chi si avvicina per la prima volta a questi concetti, ci possano essere alcuni dubbi su come funzioni esattamente e su come possa essere applicata in modo efficace nelle nostre attività didattiche e in questo breve post voglio fornirvi una possibile soluzione che sfrutto molto spesso per mostrare il comportamento di istruzioni for nidificate.

L’istruzione “plot” è estremamente utile quando lavoriamo con il display LED del micro:bit, che come sapete è costituito da una matrice composto da 25 LED disposti in una griglia 5×5. L’istruzione plot ci permette di accendere un singolo LED sulla griglia, specificando le sue coordinate (x, y).

Come funziona?

  • x rappresenta la posizione orizzontale del LED, partendo da 0 (il lato più a sinistra) fino a 4 (il lato più a destra).
  • y indica la posizione verticale, anch’essa partendo da 0 (in alto) fino a 4 (in basso).

Utilizzando “plot(x, y)”, possiamo quindi selezionare esattamente quale LED accendere, permettendoci di creare disegni, lettere, numeri o qualsiasi altro tipo di segnale visivo che possiamo immaginare.

Vediamo alcuni semplici esempi.

Esempio 01

Accensione sequenziale di tutti i LED sul display del micro:bit dall’alto verso il basso, un colonna alla volta partendo dall’angolo in alto a sinistra del display.

Link al programma.

Esempio 02

Movimento di una pallina sul display. Accensione sequenziale dei LED sul display del micro:bit dall’alto verso il basso, un colonna alla volta partendo dall’angolo in alto a sinistra del display. Il ciclo si ripete all’infinito.

Link al programma.

Esempio 03

Accensione sequenziale di tutti i LED sul display del micro:bit dall’alto verso il basso, un colonna alla volta partendo dall’angolo in alto a sinistra del display, con cancellazione finale del display e ripartenza sequenza.

Link al programma.

Per tutti gli esercizi invertendo nei cicli for le variabili “x” e “y” si avrà un movimento da destra verso sinistra.

Buon Coding a tutti 🙂

Usare la matrice LED di Arduino UNO R4 WiFi

L’elemento caratterizzante più evidente di Arduino R4 è senza alcun dubbio la matrice di LED, che potremo utilizzare come sistema di output immediato, ma anche per creare animazioni o giochi, o ancora mettere in evidenza lo stato di un sensore. La matrice LED è costituita da 12×8 LED.

La matrice e la sua API sono sviluppate per essere programmate in diversi modi, ciascuno adatto per diverse applicazioni. Questa breve lezione vi guiderà attraverso i concetti di base per gestire la matrice di LED aiutandovi a creare le vostre animazioni, mostrando tre diversi metodi di gestione dei LED che potrete scegliere in funzione del progetto che desiderate implementare.

Per lo svolgimento di questa lezione avete necessità solamente della scheda Arduino UNO R4 e di un cavo USB C.

Inizializzare la matrice

L’inizializzazione della matrice di LED avviene in 3 passi:

  1. inclusione nel vostro sketch della libreria:
#include "Arduino_LED_Matrix.h"
  1. creazione dell’oggetto matrix aggiungendo la seguente riga:
ArduinoLEDMatrix matrix;

L’oggetto ovviamente potrà avere un nome a vostro piacimento nell’esempio è stato scelto: “matrix”

  1. avviare la matrice aggiungendo nel setup():
matrix.begin();

Il codice di avvio sarà il seguente:

#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;

void setup() {
  Serial.begin(115200);
  matrix.begin();
}

Come realizzare un frame

Il principio di funzionamento della libreria di gestione della matrice di LED è quello basato sulla creazione di un frame (fotogramma) memorizzato in un buffer di memoria e poi visualizzato.

Un frame è ciò che viene chiamato anche “immagine” visualizzata in un dato momento sulla matrice di LED. Un’animazione è costituita da una serie di immagini pertanto possiamo dire in altro modo che un’animazione è costituita da una sequenza di frame .

Per controllare la matrice LED 12×8 è indispensabile utilizzare uno spazio in memoria che sia di almeno 96 bit e la libreria fornisce due modi per farlo.

Modo n. 1

Il primo è quello di creare un array bidimensionale di byte nel modo che segue:

byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

La prima modalità è molto semplice da capire, la struttura frame rappresenta la matrice di LED e la serie di 1 indicherà quali LED saranno accesi, mentre quelli a 0 rappresentano i LED spenti. L’array sopra permetterà di visualizzare sulla matrice un cuore.

Suggerimento: Potete vedere il cuore più facilmente se evidenziate tutti gli “1” sulla pagina premendo CTRL/command + F e cercando “1”.

Per fare riferimento ad un pixel specifico ricordare che l’origine degli assi si trova in alto a sinistra ed avrà coordinate (0, 0) pertanto il codice che segue permette di porre ad 1 (on) il terzo pixel da sinistra e secondo dall’alto:

frame[2][1] = 1;
matrix.renderBitmap(frame, 8, 12);

Questo metodo però richiede più memoria di quella necessaria. Anche se ogni LED ha bisogno solo di un singolo bit per memorizzare il suo stato, vengono usati per ognuno di esse otto bit (un byte). Il metodo più efficiente, in termini di memoria per memorizzare un fotogramma è utilizzare un array di interi a 32 bit, descritto di seguito.

Vedremo ora come realizzare uno o più fotogrammi, realizzazione che può anche essere svolta con il LED Matrix tool messo a disposizione da Arduino, ma al fine di comprenderne a pieno il funzionamento, consiglio di seguire le indicazioni che trovate di seguito.

La parte di programma che utilizza codici esadecimali e rappresenta l’immagine del cuore indicata sopra è:

unsigned long frame[] = {
  0x3184a444,
  0x42081100,
  0xa0040000
};

Una variabile long senza segno contiene 32 bit, quindi per gestire 92 LED (bit) avremo necessità di 96/32 che corrisponde a 3 variabili long in grado di rappresentare ogni immagine che appare sulla matrice di LED, pertanto un array di tre variabili long senza segno è un modo efficiente per contenere tutti i bit necessari per rappresentare un’immagine sulla matrice di LED.

Ma come sono relazionate la serie dei 3 valori esadecimali con la posizione di ogni songolo pixel?

Ciò dovrà essere fatto convertendo i valori esadecimali in binario utilizzando il codice che segue:

for (int b = 0; b < 3; b++) {
    Serial.println(frame[b], BIN);
  }

Che permetterà di stampare tutti i valori dei bit dell’array. L’output sarà il seguente:

110001100001001010010001000100
1000010000010000001000100000000
10100000000001000000000000000000

Questo metodo, però, non mostra tutti i bit. Ogni elemento dell’array deve avere 32 bit. Se completiamo correttamente, aggiungendo gli zeri mancanti alla fine avremo i 32 bit di ogni elemento:

00110001100001001010010001000100
01000010000010000001000100000000
10100000000001000000000000000000

Ora suddividiamo il blocco precedente in gruppi da 12 bit ed otterremo nuovamente l’immagine del cuore:

001100011000
010010100100
010001000100
001000001000
000100010000
000010100000
000001000000
000000000000

Se si hanno diversi fotogrammi, è possibile caricarli e visualizzarli in questo modo:

const uint32_t felice[] = {
    0x19819,
    0x80000001,
    0x81f8000
};

const uint32_t cuore[] = {
    0x3184a444,
    0x44042081,
    0x100a0040
};

  matrix.loadFrame(felice);
  delay(500);

  matrix.loadFrame(cuore);
  delay(500);

Proviamo il codice

Applichiamo questi concetti con due sketch che visualizzano fotogrammi diversi sulla tua scheda.

Esempio 01

Creiamo prima 3 fotogrammi interi a 32 bit e carichiamoli sulla scheda uno alla volta.

#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;

void setup() {
  Serial.begin(115200);
  matrix.begin();
}

const uint32_t felice[] = {
    0x19819,
    0x80000001,
    0x81f8000
};
const uint32_t cuore[] = {
    0x3184a444,
    0x44042081,
    0x100a0040
};
  
void loop(){
  matrix.loadFrame(felice);
  delay(500);

  matrix.loadFrame(cuore);
  delay(500);
}

Lo sketch è molto semplice è permette di mostrate due stati diversi.

Esempio 02

Cambiamo ora approccio è creiamo un’immagine che cambia durante l’esecuzione del programma. Il programma include diverse funzioni che concorrono alla costruzione del volto e modificano alcuni pixel che permettono di fare l’occhiolino dall’occhio sinistro.

#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;

void setup() {
  Serial.begin(115200);
  matrix.begin();
}

uint8_t frame[8][12] = {
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

void occhioSinistro() {
  //Occhio sinistro
  frame[1][3] = 1;
  frame[1][4] = 1;
  frame[2][3] = 1;
  frame[2][4] = 1;
}

void occhiolino() {
  //Fare un occhiolino con occhio sinistro
  frame[1][3] = 0;
  frame[1][4] = 0;
  frame[2][3] = 1;
  frame[2][4] = 1;
}

void occhioDestro() {
  //Occhio destro
  frame[1][8] = 1;
  frame[1][9] = 1;
  frame[2][8] = 1;
  frame[2][9] = 1;
}

void bocca() {
  //Bocca
  frame[5][3] = 1;
  frame[5][9] = 1;
  frame[6][3] = 1;
  frame[6][4] = 1;
  frame[6][5] = 1;
  frame[6][6] = 1;
  frame[6][7] = 1;
  frame[6][8] = 1;
  frame[6][9] = 1;
}

void loop() {
  occhioSinistro();
  occhioDestro();
  bocca();

  matrix.renderBitmap(frame, 8, 12);

  delay(1000);
  occhiolino();

  matrix.renderBitmap(frame, 8, 12);
  delay(1000);
}

Esempio 03

Vediamo ora come, usando il LED Matrix tool, possono essere realizzati due visi sorridenti di cui uno che fa l’occhiolino.
Lascio a voi capire come usare gli strumenti da disegno, essenziale però descrivervi come effettuare il download dei frame.
Costruire due immagini una che riporta un viso con sorriso e l’altra un viso con sorriso che fa l’occhiolino:

Esportare il codice:

aprire il file scaricato: animazione.h ed includerlo all’interno del codice:

#include "Arduino_LED_Matrix.h"
#include <stdint.h>

ArduinoLEDMatrix matrix;

const uint32_t animazione[][4] = {
	// viso sorridente - frame n. 0
  {
		0x18c18,
		0xc0000000,
		0x1041fc,
		66
	},
  // viso sorridente con occhiolino - frame n. 1
	{
		0xc18,
		0xc0000000,
		0x1041fc,
		66
	}
};

void setup() {
  // inizializzazione della seriale
  Serial.begin(115200);
  // avvio della matrice di LED
  matrix.begin();
}

void loop() {
  // caricamento dalla prima animazione e visualizzazione su display
  matrix.loadFrame(animazione[0]);
  // attesa di 1 secondo
  delay(1000);

  // caricamento dalla seconda animazione e visualizzazione su display
  matrix.loadFrame(animazione[1]);
  // attesa di 1 secondo
  delay(1000);
}

Esempio 04

Vediamo ora come sincronizzare la visualizzazione alternata delle due immagini con il lampeggio del LED L. Nel setup() bisognerà impostare il pin a cui è connesso il LED L ad output, dopo di che richiamare accensione e spegnimento eattamente nella stessa posizione in cui viene richiamata la funzione matrix.loadFrame():

#include "Arduino_LED_Matrix.h"
#include <stdint.h>

ArduinoLEDMatrix matrix;

const uint32_t animazione[][4] = {
	// viso sorridente - frame n. 0
  {
		0x18c18,
		0xc0000000,
		0x1041fc,
		66
	},
  // viso sorridente con occhiolino - frame n. 1
	{
		0xc18,
		0xc0000000,
		0x1041fc,
		66
	}
};

void setup() {
  // inizializzazione della seriale
  Serial.begin(115200);
  // avvio della matrice di LED
  matrix.begin();
  // pin a cui collegato il LED L (pin 13) impostato come output
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // caricamento dalla prima animazione e visualizzazione su display
  matrix.loadFrame(animazione[0]);
  // accensione del LED L
  digitalWrite(LED_BUILTIN, HIGH);
  // attesa di 1 secondo
  delay(1000);

  // caricamento dalla seconda animazione e visualizzazione su display
  matrix.loadFrame(animazione[1]);
  // spegnimento del LED L
  digitalWrite(LED_BUILTIN, LOW);
  // attesa di 1 secondo
  delay(1000);
}

Buon Making a tutti 🙂

Esercitazioni di base di Arduino – visualizzazione luminosità LED mediante una barra di avanzamento su display 16×2


Continuo nell’aggiornamento delle esercitazioni di base per gli studenti di 3′ dell’ITIS (Elettronica ed Automazione) e per gli utenti che iniziano con Arduino.
Utilizzeremo un display LCD 16×2 di tipo I2C su cui visualizzeremo mediante una barra di avanzamento, la quantità di luminosità impostata per il LED, mediante un potenziometro.

Per la gestione di un display LCD di tipo I2C rimando alla mia lezione: Utilizzo dell’LCD 16×2 Hitachi HD44780 1602 con modulo I2C PCF8574T.

Per la creazione di caratteri personalizzati rimando alla mia lezione: Disegnare caratteri personalizzati con Arduino per un LCD 16×2.

Lista componenti

  • N.1 Arduino UNO
  • N.1 Breadboard
  • N.1 LCD 16×2 I2C
  • N.1 Potenziometri da 10 KOhm
  • N.1 LED da 5 mm
  • N.1 Resistore da 220 Ohm
  • jumper

Schema di collegamento

Scketch

Di seguito viene indicato il codice i base, all’interno i commenti che ne dettagliano il funzionamento di ogni parte:

/*
   Prof. Maffucci Michele
   https://www.maffucci.it
   Ver.1 - 27.12.21
   Controllo di luminosità LED con
   visualizzazione intensità mediante una
   barra di avanzamento su display 16x2
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

byte pinPot = A0;           // pin analogico 0 a cui connettere il potenziometro per controllare la luminosità
byte pinLed = 3;            // pin PWM a cui connettere il LED
int  analogVal = 0;         // variabile in cui memorizzare il valore impostato dal potenziometro
int  luminosita = 0;        // variabile in cui memorizzare la luminosità 
byte barraAvanzamento = 0;  // indice barra avanzamento

// Per maggiori informazioni sulla realizzazione di caratteri speciali:
// https://www.maffucci.it/2020/01/18/disegnare-caratteri-personalizzati-con-arduino-per-un-lcd-16x2/

// Carattere personalizzato per disegnare la barraAvanzamento di avanzamento
byte iconaBarra[8] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};

// inizializzazione della libreria in cui è descritta la modalità di utilizzo dei pin
// impostazione dell'indirizzo dell'LCD 0x27 di 16 caratteri e 2 linee
LiquidCrystal_I2C lcd(0x27, 16, 2);
//-----------------------------

void setup()
{
  lcd.begin();      // inizializzazione dell'LCD
  lcd.backlight();  // attivazione della retroilluminazione

  // Inpostazione ad OUTPUT del pin a cui connettiamo il LED
  pinMode(pinLed, OUTPUT);

  // Cancella il display
  lcd.clear();

  // Stampa il messaggio sulla prima riga del display
  lcd.print("Luminosita' LED");

  //Creazione del carattere per la barra di avanzamento
  lcd.createChar(0, iconaBarra);
}

// Per maggiori informazioni sull'uso del display 16x2 I2C:
// https://www.maffucci.it/2019/01/25/utilizzo-delllcd-16x2-hitachi-hd44780-1602-con-modulo-i2c-pcf8574t/
//-----------------------------

void loop() {
  // Cancella il display
  lcd.clear();
  
  // Stampa il messsaggio sulla prima riga
  lcd.print("Luminosita' LED");
  
  //Posiziona il cursore nella seconda riga, prima colonna
  lcd.setCursor(0,1);
  
  // Lettura del valore impostato dal potenziometro
  analogVal = analogRead(pinPot);
          
  // Conversione del valore analogico impostato con il potenziometro
  // in Duty Cicle per impostare la luminosità del LED
  luminosita=map(analogVal, 0, 1024, 0, 255); 
  
  // Impostazione della luminosità del LED
  analogWrite(pinLed, luminosita); 
  
  // Conversione della luminosità in quantità di caratteri della barra da stampare 
  barraAvanzamento=map(luminosita, 0, 255, 0, 15);
  
  // Stampa la barra di avanzamento
  for (byte i = 0; i < barraAvanzamento; i++)
  {
    lcd.setCursor(i, 1);   
    lcd.write(byte(0));  
  }
  // leggero ritardo di 500 ms per visualizzare la barra
  delay(500);        
}

Proposta esercizi

Esercizio 1
Nell’esempio proposto viene utilizzato un delay() finale per permettere la visualizzazione dei caratteri sul display. Sostituire il delay() ed utilizzare l’istruzione millis() per valutare il tempo trascorso e controllare la stampa dei caratteri sul display.

Esercizio 2
Modificare il programma precedente raddoppiando il numero di caratteri che rappresenta la barra di avanzamento.

Esercizio 3
Modificare l’esercizio proposto variando la barra di avanzamento in funzione dell’approssimarsi al valore massimo o minimo della luminosità.

Esercizio 4
Modificare l’esercizio proposte inserendo un buzzer che emette un suono la cui frequenza varia in funzione dell’intensità luminosa del LED.

Buon Making a tutti 🙂

Raspberry Pi Pico – controllare lo stato di un pin digitale

Propongo in questa breve lezione due esempi di base sull’uso del Raspberry Pi Pico: identificare lo stato di un pulsante e realizzazione di un interruttore mediante un pulsante.

Per questo esempio utilizzeremo il pin 14 a cui connetteremo un pin del pulsante, così come rappresentato nell’immagine che segue. Come sapete molti dei pulsanti disponibili nei kit elettronici sono costituiti da 4 pin, connessi frontalmente a due a due.
Proseguiamo connettendo il secondo pin del pulsante al positivo sulla breadboard (3,3V). Ricordiamoci inoltre la connessione del 3,3V del PiPico al positivo della breadboard.

E’ molto importante ricordare che una simile connessione del pulsante con il PiPico potrebbe causare problemi di cortocircuito alla pressione del pulsante, perché non presente una resistore di PULL-UP o di PULL-DOWN fisico. Per evitare di utilizzare un resistore, attiviamo la resistenza di PULL-DOWN sul pin 14, ATTENZIONE ricordate di fare questa operazione altrimenti rischiate di distruggere irrimediabilmente  il vostro microcontrollore.

Aprite l’editor Thonny e digitate il seguente programma:

# Prof. Maffucci Michele
# Controllo dello stato sul pin 14 (una sola volta)
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

# la lettura del pulante viene fatta usando l'API machine
# usando la funzione value

print(button.value())

Salvate il programma sulla vostra scheda, assegnate ad esempio il nome pulsante1.py
Se mandate in esecuzione il programma lo stato del pin verrà mostrato immediatamente sulla Shell una sola volta.

Se non premete il pulsante verrà mostrato sulla Shell il valore logico 0 in quanto abbiamo utilizzato una resistenza di PULL-DOWN, nel momento in cui, all’avvio premete il pulsante lo stato logico visualizzato sulla Shell sarà 1.

Per leggere lo stato del pulsante in modo continuo bisognerà aggiungere un loop all’interno del programma che segue che chiameremo pulsante2.py

# Prof. Maffucci Michele
# Controllo dello stato sul pin 14 (in modo continuo)
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

# la lettura del pulante viene fatta usando l'API machine
# usando la funzione value

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    # se la condizione è vera viene stampato
    # il messaggio mediante la print
    # e fermato il programma per 1 secondi
    if pulsante.value() == 1:
        print("Hai premuto il pulsante")
        utime.sleep(1)

Premete sul pulsante di Run nell’IDE, vedrete che fino a quando non premete il pulsante non accade nulla. Non appena il pulsante viene premuto viene stampata sulla Shell la strina “Hai premuto il pulsante”.

Attenzione che senza la brevissima pausa di 1 secondo verrebbe stampato continuamente il messaggio “Hai premuto il pulsante”.

Vedrete quindi la stampa del messaggio ogni secondo. Se mantenete premuto il pulsante per un tempo superiore a 1 secondi verrà stampato nuovamente il messaggio e ciò si ripeterà ogni secondo fino a quando non rilasciamo il pulsante.

Vediamo ora un programma che, oltre ad inviare un messaggio sulla Shell, accende un LED esterno connesso al pin 15 ogni volta che premiamo il pulsante, chiamiamo il programma pulsante3.py.

# Prof. Maffucci Michele
# Controllo dello stato sul pin 14 (in modo continuo)
# eaccensione di un led alla pressione del pulsante
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

#pin 15 dichiarato come OUTPUT
ledEsterno = machine.Pin(15, machine.Pin.OUT)

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    # se la condizione è vera viene stampato
    # il messaggio mediante la print
    # e fermato il programma per 1 secondi
    if pulsante.value() == 1:
        ledEsterno.value(1)    # imposta il livello logico 1 sul pin 15
        print("Hai premuto il pulsante")
        utime.sleep(0.5)       # imposta una pausa di mezzo secondo
        ledEsterno.value(0)    # imposta il livello logico 0 sul pin 15

Vediamo ora come realizzare un programma che realizza la funzione di un interruttore, cioè il mantenimento dello stato al rilascio del pulsante. Chiamiamo il programma interruttore1.py. Il circuito è il medesimo dell’esempio al passo precedente.

# Prof. Maffucci Michele
# realizzazione di un interruttore 
# mediante pulsante connesso al Pin 14 con antirimbalzo software
# con accensione di un LED connesso al pin 15
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

#pin 15 dichiarato come OUTPUT
ledEsterno = machine.Pin(15, machine.Pin.OUT)

# val usato per conservare lo stato del pulsante
val = 0

# vecchio_val per conservare lo stato del pulsante al passo precedente
vecchio_val = 0

# ricorda lo stato in cui si trova il LED,
# stato = 0 led spento, stato = 1 led acceso
stato = 0

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    val = pulsante.value()                   # legge il valore del pulsante e lo conserva
    if (val == 1) and (vecchio_val == 0):    # controlla se è accaduto qualcosa
        stato = 1 - stato
        utime.sleep(0.15)	             # attesa di 15 millisecondi
    vecchio_val = val;
    if (stato == 1):
        ledEsterno.value(1)    # imposta il livello logico 1 sul pin 15
    else:
        ledEsterno.value(0)    # imposta il livello logico 0 sul pin 15

Modifichiamo ora il programma precedente inviando sulla Shell il messaggio che indica lo stato del LED, chiamiamo il programma interruttire2.py. Il circuito è il medesimo dell’esempio al passo precedente.

# Prof. Maffucci Michele
# realizzazione di un interruttore 
# mediante pulsante connesso al Pin 14 con antirimbalzo software
# con accensione di un LED connesso al pin 15
# e stampa dello stato del LED sulla Shell
# 18.09.2021

# libreria che permette di utilizzare MicroPython con il RaspyMicro
import machine

# per la gestione del tempo
import utime

# creazione dell'oggetto pulsante che include il pin 14 impostato come input
# su cui viene attivata il resistore di PULL-DOWN
pulsante = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)

#pin 15 dichiarato come OUTPUT
ledEsterno = machine.Pin(15, machine.Pin.OUT)

# val usato per conservare lo stato del pulsante
val = 0

# vecchio_val per conservare lo stato del pulsante al passo precedente
vecchio_val = 0

# ricorda lo stato in cui si trova il LED,
# stato = 0 led spento, stato = 1 led acceso
stato = 0

# stampare una sola volta il messaggio 'LED acceso' o 'LED spento' sulla Shell
abilitaMessaggio = 0

# while True definisce un loop infinito al cui interno
# troviamo il controllo dello stato del pulsante
while True:
    val = pulsante.value()                    # legge il valore del pulsante e lo conserva
    if (val == 1) and (vecchio_val == 0):     # controlla se è accaduto qualcosa
        stato = 1 - stato
        utime.sleep(0.15)		      # attesa di 15 millisecondi
    vecchio_val = val;
    if (stato == 1) and (abilitaMessaggio == 0):
        ledEsterno.value(1)                   # imposta il livello logico 1 sul pin 15
        abilitaMessaggio = 1
        print("LED acceso")                   # stampa il messaggio
        utime.sleep(1)
    elif (stato == 0) and (abilitaMessaggio == 1):
        ledEsterno.value(0)                   # imposta il livello logico 0 sul pin 15
        abilitaMessaggio = 0
        print("LED spento")                   # stampa il messaggio
        utime.sleep(1)

Buon Coding a tutti 🙂

Arduino – realizzare un sensore di seduta a pressione con un tubo di gomma

Questa mattina, durante la realizzazione e l’analisi dei problemi per il progetto di PCTO: “misura di sedentarietà delle persone sedute alla scrivania” che stanno realizzando i miei studenti di 3′ Elettronica, è nata l’esigenza di associare un doppio controllo per la valutazione della presenza della persona seduta alla scrivania, un controllo effettuato con PIR HC-SR501 ed un sensore di forza resistivo (FSR) inserito all’interno del cuscino della seduta.

Per evitare l’acquisto di un sensore di forza resistivo e non pesare sulle finanze dei ragazzi le modalità sono tre:

  • richiesta alla scuola
  • compra il Prof.
  • farlo costruire ai ragazzi

l’acquisto da parte della scuola o mia non è un problema, ma la terza soluzione è quella che in questo momento prediligo, perché può essere realizzata in 5 minuti, credo che possa gratificare di più lo studente Maker in erba 🙂 , inoltre ritengo importante che gli allievi assumano la capacità di costruire il sensore perché ne dovranno ottimizzare l’uso, scontrandosi inevitabilmente con una serie di variabili fisiche che dovranno gestire.

Ma come si costruisce il sensore?

E’ indispensabile piccolo tubo cilindrico non trasparente, preferibilmente nero che possa essere compresso e al termine della compressioni ritorni abbastanza velocemente nella sua posizione di riposo. Possiamo ricavare il tubo sguainando un cavo elettrico o cavo di rete, oppure come ho fatto in questo tutorial, prendendo una guaina termorestingente.

Inserire un diodo LED ad un’estremità del cilindro e dalla parte opposta inserire un LDR.
Collegare il sistema nella solita modalità, inserendo in serie al LED un resistore da 220 Ohm e creando un partitore di tensione tra l’LDR e un resistore da 10KOhm, così come indicato nel circuito indicato di seguito.

Come test di funzionamento utilizzare il semplice sketch che trovate di seguito, nei commenti la spiegazione di tutte le parti del codice.

Aprite la Serial Monitor e premete e rilasciate il tubo

/*
 * Prof. Michele Maffucci
 * Data 01.03.2021
 * 
 * Oggetto: sensore di seduta a pressione
 * 
*/

// variabile in cui verrà memorizzato il valore presente sul pin A0
const int misura = A0;

// valore restituito dall'analogRead
int val = 0;

// pin a cui è connesso il LED del sensore di seduta
int pinLed = 2;

// LED che segnala la seduta della persona
int pinLedAlert = 13;

void setup() {
  // Inizializzazione della Serial Monitor
  Serial.begin(9600);

  // ledPin è il pin a cui è connesso il LED del sensore di seduta
  pinMode(pinLed, OUTPUT);

  // pinLedAlert è il pin a cui è connesso il LED che segnala la seduta della persona
  pinMode(pinLedAlert, OUTPUT);

  // Attivazione del LED del sensore di seduta
  digitalWrite(pinLed, HIGH);

  // Messaggio di avvio
  Serial.println("Sistema di rilevazione seduta");
  Serial.println("-----------------------------");
  Serial.println(""); 
  delay(1000);
}

void loop() {
  // analogRead leggerà il valore su A0 restituendo un valore tra 0 e 1023
  val = analogRead(misura);

  // il valore di controllo nell'if deve essere sperimentato in funzione
  // delle necessità costruttive (ad es. la lunghezza del tubo)

  // se vero la persona è seduta
  if (val >= 100) {
    digitalWrite(pinLedAlert, HIGH);                      // accensione del LED di avviso
    Serial.println("Persona NON seduta alla scrivania");  // segnalazione di assenza persona
    Serial.print("Valore letto dal sensore = ");          // Stringa di stampa 
    Serial.println(val);                                  // Valore restituito dall'AnalogRead
    Serial.println("");                                   // Stampa linea vuota di separazione
    delay(1000);                                          // Intervallo di 1 secondo tra ogni stampa
  }
  else
  {
    digitalWrite(pinLedAlert, LOW);                       // spegnimento del LED di avviso
    Serial.println("Persona seduta alla scrivania");      // segnalazione di presenza persona
    Serial.print("Valore letto dal sensore = ");          // Stringa di stampa 
    Serial.println(val);                                  // Valore restituito dall'AnalogRead
    Serial.println("");                                   // Stampa linea vuota di separazione
    delay(1000);                                          // Intervallo di 1 secondo tra ogni stampa
  }
}

Il risultato sulla Serial Monitor è il seguente

Il valore di soglia scelto deve essere ricavato sperimentalmente in funzione della lunghezza e della trasparenza del tubo.

Buon Making a tutti 🙂