Archivi categoria: elettronica

Arduino: water sensor

Per le attività in programma per il corso sui laboratori green, spiegherò come controllare il livello d’acqua in una cisterna utilizzata per l’irrigazione. A livello prototipale svolgerò prima sperimentazioni su singola pianta utilizzando il “water sensor” che potete acquistare per pochi centesimi online. In una fase successiva impiegherò dei sensori di livello che vengono comunemente impiegati in cisterne e controlleremo il riempimento e lo svuotamento della cisterna.

Il “water sensor” misura il livello di conduttività elettrica del liquido, conduttività che sarà funzione della quantità di superficie del sensore immerso.
Nell’acqua ed in generale nei liquidi, il passaggio di corrente è dovuto alla presenza di sali, infatti l’acqua pura non risulta conduttiva.
Le piste parallele di rame presenti sul sensore sono connesse al potenziale positivo e al GND, quando il sensore viene immerso nel liquido viene misurata una differenza di potenziale tra i due poli, d.d.p. che dipenderà dalla quantità di superficie immersa, pertanto al variare della quantità d’acqua varierà il valore di resistenza tra i due potenziali.

Sottolineo che il sensore non è preciso e richiede una taratura iniziale che dipende prevalentemente dall’acqua, inoltre sensori diversi potrebbero fornirvi misure diverse.

Il segnale di uscita del sensore (pin S) verrà inviato su un pin analogico di Arduino e da esso convertito in un valore numerico che oscillerà tra ~ 0 e ~500, pertanto se il sensore non è immerso il valore misurato sarà di circa 0, mentre se sarà totalmente immerso raggiungerà il valore massimo rilevato.

Sul sensore sono presenti 10 piste di rame parallele, connesse in modo alternato, in modo che vi siano 5 piste connesse ad un potenziale alto e 5 piste connesse a GND. E’ presente inoltre un LED che indica quando il sensore viene alimentato.

  • S (Signal): uscita analogica da connettere ad un ingresso analogico di Arduino
  • +Vcc: potenziale positivo dell’alimentazione. Si consiglia di alimentare il sensore con una tensione compresa tra 3,3 V e 5V. Si ricorda che l’uscita analogica del sensore varierà in funzione della tensione di alimentazione del sensore.
  • – : da connettere al GND

Attenzione che il sensore non è progettato per essere completamente immerso, fate in modo che solo le tracce ramate parallele esposte sul PCB vengano a contatto con l’acqua.

Continua a leggere

Raspberry Pi Pico – Blink di un LED esterno

Nel primo post pubblicato sull’uso di Raspberry Pi Pico, avevo concluso il tutorial mostrando come controllare l’accensione del LED sulla scheda, quello connesso alla pin 25. Il passo successivo, molto semplice, in quanto riprende i medesimi passaggi dell’ultimo esempio mostrato, sarà quello di controllare un LED esterno alla scheda.
Ovviamente sappiamo già che in serie al LED dovrà essere inserita una resistenza per controllare la corrente che fluisce nel LED (per approfondimenti consultare il link). Poiché in questo caso la tensione di alimentazione del LED sarà quella disponibile sulla scheda, 3,3 Volt, considerando un LED rosso, con una corrente di funzionamento di 15 mA ed una tensione di soglia di 1,8V, usando la legge do Ohm il valore della resistenza serie dovrà essere di 100 Ohm. Nel caso non abbiate questo valore potrete utilizzare anche i classici valori, 220 Ohm o 330 Ohm, che trovate in un qualsiasi kit di sperimentazione, valori più grandi di resistenza ovviamente faranno emettere a parità di tensione, una luminosità inferiore.

Colleghiamo un reoforo del resistore al pin digitale 15 (GPIO 15), il restante reoforo all’anodo del LED ed il catodo del LED al GND. Di seguito le immagini del Pin Out del PiPico e schema di collegamento:

Prendendo a riferimento il programma in MicroPython del precedente tutorial, andiamo a variare alcune linee di codice. Bisognerà modificare solamente il numero del pin digitale utilizzato:

# Prof. Maffucci Michele
# Blink LED connesso al pin 15
# 10.09.2021

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

# per la gestione del tempo
import utime

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

# loop infinito, while sempre vero, che scrive, ad intervalli di 1 secondo
# sul pin 15 il valore 1 e 0
while True:
    ledEsterno.value(1)    # imposta il livello logico 1 sul pin 15
    utime.sleep(1)         # lo stato logico 1 viene mantenuto per 1 secondo
    ledEsterno.value(0)    # imposta il livello logico 0 sul pin 15
    utime.sleep(1)         # lo stato logico 0 viene mantenuto per 1 secondo

Buon coding a tutti 🙂

Supporto per PIR HC-SR501

Per la realizzazione della lezione sull’uso del PIR HC-SR501 pubblicato alcuni giorni fa, per lavorare agevolmente con il sensore ho creato un semplice supporto che poi ho stampato in più copie per le sperimentazioni di laboratorio di Sistemi a scuola. Non appena ho pubblicato il post ho ricevuto alcune mail da parte di colleghi e studenti che mi hanno chiesto i sorgenti grafici del supporto.
Potete prelevare i file per la stampa 3D direttamente dalla mia pagina su Thingiverse: PIR HC-SR501 support

Buon makimg a tutti. 🙂

PCTO A.S. 2020 – 2021 – SumoBot – lezione 2

In questa lezione vedremo come collegare e controllare i servomotori a rotazione continua di SumoBot.
Fate riferimento allo schema di collegamento che segue, in cui i servomotori vengono connessi ai pin 4 e 5 della Sensor Shield per Arduino Uno Nano V3, come si nota a fianco di ogni pin è disponibile l’alimentazione, infatti troviamo sempre il positivo, indicato con la lettera V e il GND indicato con la lettera G. Come ribadito nella lezione 1 utilizziamo una Sensor Shield perchè permette rapidamente di realizzare tutti i collegamenti senza la necessità i dover ricorrere ad una breadboard oppure alla saldatura dei cavi.

Per questa lezione vengono indicati solo i collegamenti ai motori, non verranno collegati ne il sensore ad ultrasuoni e ne i sensori ad infrarossi.

Per quanto riguarda l’utilizzo dei servomotori a rotazione continua fare riferimento alla slide: Alfabeto di Arduino – Lezione 6, ma per completezza riporto di seguito la spiegazione adattandola all’utilizzo con SumoBot.

Il servomotore è costituito in genere da tre cavi connessi ad un connettore femmina con passo standard tra i fori di 2,54 mm quindi facilmente utilizzabile con qualsiasi strip che ne permette il collegamento ad esempio su una breadboard oppure ai pin maschio della Sensor Shield che utilizziamo per SumoBot.

I fili di connessione possono assumere colori diversi in funzione della marca del servo.

Pinout del servomotore

  • Filo ROSSO: +V
  • Filo NERO o MARRONE: GND
  • Filo BIANCO o ARANCIO o BIANCO o BLU: Segnale

Nel servomotori adottati per questa esperienza i fili di connessione sono:

  • Filo ROSSO: +V
  • Filo MARRONE: GND
  • Filo ARANCIO: Segnale

Collegamenti

Guardando SumoBot frontalmente, collegheremo il motore di destra al pin 4 e il motore di sinistra al pin 5.

Principio di funzionamento del servomotore a rotazione continua

Notoriamente i servomotori possono effettuare una rotazione che oscilla tipicamente da 0 a 180, esistono inoltre modelli che consentono una rotazione inferiore tra 0 e 120 gradi, questi tipi di servomotori possono essere modificati facendo in modo che possano effettuare una rotazione continua, ovvero tra 0 e 360 gradi, ma in commercio sono disponibili servomotori di diverse dimensioni che funzionano in questa modalità. Nel kit utilizzato per la realizzazione di SumoBot utilizziamo due servomotori FS90R.

Sul servomotore a rotazione continua possiamo controllare da programma il senso di rotazione e in modo non molto preciso anche la velocità.

Il funzionamento di un servomotore a rotazione continua è simile a quella di un motore in corrente continua con la differenza che non necessitano di appositi shield per poter funzionare.
Rispetto ad altri tipi di motori in CC offrono scelte limitate per il controllo della velocità e limitazioni di alimentazione.

L’alimentazione potrà avvenire direttamente Attraverso Arduino o mediante alimentazione esterna. L’alimentazione dei motori di SumoBot avverrà direttamente dalla scheda Arduino.

Caratteristiche tecniche

  • Velocità di funzionamento a 4,8V: 110RPM
  • Velocità di funzionamento a 6V: 130RPM
  • Coppia di stallo a 4,8V: 1.3kg.cm/18.09oz.in
  • Coppia di stallo a 6V: 1.5kg.cm/20.86oz.in
  • Tensione operativa: 4.8-6V
  • Sistema di controllo: Analogico
  • Angolo di rotazione: 360 gradi
  • Impulso richiesto: 900-2100us
  • Materiale ingranaggi: Plastica
  • Dimensioni: 2,32×1,25×2,2 cm
  • Peso: 9g

Programmazione

/*
 * Prof. Maffucci Michele
 * SumoRobot
 * Data: 26.01.2021
 *
 * Sketch 01: rotazione oraria e antioraria continua
 *
 * Note:
 *          Per l'orientamento del robot
 *          guardare SumoBot anteriormente
 *
 *          180: max velocità in senso antiorario
 *          90 : servomotori fermi
 *          0  : max velocità in senso orario
 *
 */

// inclusione della libreria servo.h per il controllo dei servomotori
#include <Servo.h>

// Creazione oggetti servo
Servo motoreDX;  // Inizializzazione del servomotore destro
Servo motoreSX;  // Inizializzazione del servomotore sinistro

byte pinDx = 4;     // Inizializza del pin 4 a cui è connesso il pin segnale del servo destro
byte pinSx = 5;     // Inizializza del pin 5 a cui è connesso il pin segnale del servo sinistro
int  durata = 250;  // Durata movimento (orario/antiorario)
int  ferma = 3000;  // Durata dello stop

void setup() {

  // attach() consente di definire a quale pin viene connesso il servomotore
  // e lo collega all'oggetto che gestisce il servomotore

  motoreDX.attach(pinDx); // pinDx collegato al motore destro
  motoreSX.attach(pinSx); // pinSxcollega to al motore sinistro
}

void loop() {
  orarioRobot();     // Rotazione in senso orario del robot
  stopRobot();       // Stop rotazione per un tempo fissato (vedere variabile ferma)
  antiorarioRobot(); // Rotazione in senso antiorario del robot
  stopRobot();       // Stop rotazione per un tempo fissato (vedere variabile ferma)
}

// rotazione del robot in senso antiorario
void antiorarioRobot(void) {
  motoreDX.write(150);  // Rotazione oraria del motore DX
  motoreSX.write(150);  // Rotazione antioraria del motore SX
  delay(durata);        // durata: durata della rotazione
}

// rotazione del robot in senso orario
void orarioRobot(void) {
  motoreDX.write(30);    // Rotazione antioraria del motore DX
  motoreSX.write(30);    // Rotazione oraria del motore SX
  delay(durata);         // durata: durata della rotazione
}

// stop del robot
void stopRobot(void) {
  motoreDX.write(90);   // Ferma il motore DX
  motoreSX.write(90);   // Ferma il motore SX
  delay(ferma);         // Durata dello stop
}

Per quanto riguarda il controllo dei servomotori seguire la spiegazione inserita come commento all’interno del codice, ricordo comunque che per controllare i servomotori sono necessarie  4 operazioni:

  1. includere la libreria Servo.h
  2. creazione dell’oggetto Servo. motoreDx e motoreSx saranno i due oggetti su cui opererete
  3. assegnare un nome al pin di controllo del servomotore (filo arancione nello schema)
  4. indicare nel setup il metodo attach() che permette di legare gli oggetti motoreDx e motoreSx ai pin su Arduino nell’esempio 4 e 5 a cui abbiamo assegnato i nomi pinDx e pinSx.

All’interno del codice utilizziamo il metodo write() che per i servomotori a rotazione continua permette il passaggio, all’oggetto motoreDx e motoreSx, la direzione e la velocità di rotazione del motore:

  • passando il valore 0 gradi al metodo write() il servo ruota alla massima velocità in una direzione.
  • passando il valore 90 gradi al metodo write() poniamo il servo in stop (posizione “neutra”)
  • passando il valore 180 gradi al metodo write() il servo di ruotare in senso opposto alla massima velocità.

Nel codice che segue SumoBot ripeterà continuamente una rotazione oraria di 250 millisecondi, si fermerà per 3 secondi e riprenderà la rotazione in senso antiorario per 250 millisecondi.

Per effettuare questa operazione vengono definite 3 funzioni:

  • orarioRobot()
  • stopRobot()
  • antiorarioRobot()

Nel codice si può notare che nella funzione antiorarioRobot() viene passato al metodo write() non il valore 180 che farebbe ruotare il robot alla massima velocità, ma un valore inferiore, nel nostro caso 150, ciò ridurrà la velocità di rotazione.

In  modo analogo accade per la funzione orarioRobot() in cui invece di passare il valore 0 alla metodo write(), che lo farebbe ruotare alla massima velocità in senso orario, passiamo un valore maggiore, 30, che lo farà ruotare ad una velocità inferiore.

La fermata del robot avviene utilizzando la funzione stopRobot() in cui viene passato il valore 90 al metodo write(), ciò fermerà i motori.

Si noti che i motori potranno ruoteranno in un senso o in un altro, oppure potranno essere fermati non solo invocando il metodo write, ma bisognerà sempre inserire un delay() in cui viene specificato per quanto tempo il metodo deve agire.

Esercizio 01

Far compiere a SumoBot rotazioni continue di 90 gradi in senso orario inserendo un intervallo di 3 secondi ad ogni quarto di giro

Esercizio 02

Far compiere a SumoBot una rotazione continua di 360° con intervalli di 3 secondi ad ogni quarto di giro, raggiunti i 360° far cambiare il senso di rotazione ripetendo le fermate di 3 secondi ad ogni quarto di giro.

Esercizio 03

Individuare quanto tempo necessita per far effettuare una rotazione di 45° in senso orario a SumoBot e realizzare un programma che permetta di fare le seguenti operazioni:

  1. rotazione di 45° in senso orario
  2. fermate di 3 secondi
  3. rotazione in senso antiorario di 90°
  4. fermata

Buon Making 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 🙂