ARD002 – Contatore con Sensore LDR e Arduino

Questo progetto nasce con la necessità di realizzare un contapezzi, per rendere il progetto più accattivante abbiamo deciso di utilizzare Arduino Nano ed un Display LCD 16x2.

Come sappiamo tutti la fotoresistenza (LDR) aumenta la sua resistenza all'aumentare della luminosità e diminuisce il suo valore ohmico al diminuire della luminosità ricevuta.

Arduino Nano ha 8  PIN analogici [A0 - A7] ogniuno dei quali può leggere e scrivere "valori", in particolare quando impostati in modalità INPUT, Arduino "sente" le variazioni di tensione applicata [da 0 a 5 V] ed è possibile campionare gli stessi attribuendone un valore che va da 0 a 1023.

Arduino Nano ha anche vari ingressi digitali [D2 - D12] alcuni dei quali possono ricevere in ingresso valori discreti che vengono interpretati da Arduino come 0 (LOW) e 1 (HIGH).
In particolare su 6 di questi PIN digitali [D3, D5, D6, D9-D11 ] è possibile applicare delle tensioni variabili in ingresso che verranno però comunque convertiti da analogico a digitale e trattati come tali da Arduino.

In particolare la conversione da segnale analogico a digitale del ATMega328 segue una logica di soglie simile a quella TTL, ma a valori di riferimento diversi:
- da 3 a 5 V             --> HIGH
- da 0 a 1,5              --> LOW
- 1.5 < valore < 3   -->  INDETERMINATO

Ricordiamoci inoltre che la corrente di lavoro MAX di Arduino è 200 mA, fanno eccezione i PIN A6 e A7 sui quali la corrente massima è solo di 40 mA, raccomandiamo quindi di utilizzare questi PIN con molta attenzione!

In linea generale, quando possibile, vi consigliamo di calcolare le correnti di lavoro su tutti i PIN di Arduino inferiori ai 40 mA, idealmente 20 mA.

Per quanto riguarda la gestione dei bottoni potremmo operare in maniera semplice (logica pull-up), inserite quindi il bottone in serie tra il PIN Digitale e GND oppure nel modo più generale e più sicuro (logica pull-down), che vedremo tra poco.

Voglio ricordare che nella logica pull-up sarebbe più corretto inizializzare il PIN nella sezione SETUP del programma come INPUT_PULLUP (Es: pinMode(2,INPUT_PULLUP);), questo attiverà la resistenza interna di pull-up di Arduino (che è circa 20 KOhm), avremo in questa situazione una logica "invertita" nel senso che riceveremo, ad esempio sul PIN 2, HIGH quando l'interruttore è aperto e LOW quando è chiuso.

Usiamo però in questo caso il metodo più lineare, che ci può venir utile in mille altre situazioni, la logica di pull-down.
Nel caso di tensione di input sul bottone sarebbe stata sufficiente una resistenza da 10 KOhm in serie tra l'interruttore e la massa, ma vogliamo qui esporvi un caso generico, riutilizzabile in mille altre occasioni con tensioni diverse.

A bassi amperaggi e carichi stabili , per ridurre la tensione da 5V o dai 12V ai 3V possiamo usare un semplice circuito partitore di tensione:

La funzione di trasferimento del partitore risulta:  e di conseguenza: , con  .

L'idea è quella di ricevere in input 5V e trasferirne 3.3V a interruttore chiuso utilizzando la logica di pull-down.
L'inserimento di un ulteriore resistenza a monte dell'interruttore ha la funzione di evitare un picco di corrente alla chiusura dell'interruttore evitando così di bruciare le resistenze interne ad Arduino Nano.

Usiamo un approccio inverso per definire le due resistenze, come tensione di riferimento prendiamo quella erogata di 5V erogata dal piedino 4 di Arduino Nano, chiuderemo il circuito con il piedino 2, quello della massa GND. In questo modo avremo sicuramente una corrente coerente con Arduino stesso, pertanto non pericolosa per il sistema.

Vin = 5V, Vout = 3.3 --> alfa ≈ 0,66 (circa uguale)

Supponiamo che R2 = 22 Ohm, avremo che  R1 = (R2 / alfa) - R2, pertanto R1 = 11,3 Ohm, sostituita dal valore commerciale più vicino per difetto 10 Ohm (vogliamo una tensione superiore o uguale a 3.3V) quindi otterremo ad interruttore chiuso circa 3,44 Volt, sicuramente un valore HIGH.

Attenzione: nel caso di amperaggi superiori, oppure carichi variabili in impedenza, è necessario ricorrere ad altri artefici; se le correnti in gioco sono inferiori ad 1 Ampere, è sufficiente un circuito stabilizzatore come ad esempio al 7805, in casi di potenze più elevate si può ricorrere ad un opto-isolatore o a un relay o altre tecniche più complesse.

Monteremo 3 pulsanti utilizzando la logica finora esposta, uno per set/reset e gli altri due per incrementare e diminuire la frequenza di campionamento.
Leggeremo HIGH ad ogni pressione dei suddetti pulsanti.

Quando decidiamo che una fotoresistenza in un circuito fa da pilota per l'innesco di un comportamento è sempre una buona idea inserire un un trimmer o un potenziometro utile alla taratura del circuito.

Nel nostro caso specifico abbiamo utilizzato la stessa logica prima descritta riguardo il partitore di tensione, dove però R1 = Rldr + 4,7 K Ohm ed R2 = Rpot con Rpot = potenziometro lineare da 10 KOhm.
Abbiamo ottenuto così un circuito di taratura semplice ed efficace che ci evita corto circuiti e ci restituisce un range di valori moderabile attraverso il potenziometro.

Direttamente dal circuito di alimentazione andremo a montare un diodo LED rosso con opportuna resistenza limitatrice da 220 Ohm, questa illuminerà direttamente la fotoresistenza e sarà il nostro riferimento quando il circuito è a riposo.

Dal PIN Digitale piloteremo un LED blue (con opportuna resistenza limitatrice da 100 Ohm) che verrà illuminato ad ogni lettura "valida", quando cioè il microcontrollore sta attivamente contando.

Il circuito finora ottenuto effettuerà un controllo costante sull'intensità luminosa ricevuta dalla fotoresistenza, se l'intensità luminosa sarà inferiore di una certa soglia impostata via software (nel caso specifico 0,50), il LED Blue lampeggerà e un contatore interno verrà incrementato di una unità.
La sensibilità rispetto alla soglia fissa dell'intensità luminosa verrà impostata attraverso il potenziometro prima descritto.
Aumentando la sensibilità, le variazioni, anche minime, vengono massimizzate, al contrario riducendo la sensibilità si tende al funzionamento normale dell'LDR.

Il Display LCD 16x2 verrà pilotato usando il protocollo I2C, come già descritto nel progetto ARD001.
Nel nostro caso specifico abbiamo deciso di utilizzare un Display LCD Blue, questo ha specifiche leggermente differenti dal verde utilizzato in ARD001.
Il codice che verrà usato per questo display copre l'altro caso più comune di interfacciamento con i display LCD 16x2; tra ARD001 e questo progetto vengono coperti la stragrande maggioranza delle casistiche in cui viene utilizzato il display 16x2 con interfaccia I2C.

Di seguito vediamo il montaggio su breadboard:

 

 

 

Ecco a voi la visione di montaggio:

 

 

 

 

 

 

 

 

Nelle guaine termorestringenti gialle sono state inserite le resistenze di limitazione dei led, nelle nere quelle di pull-down.

Ecco il codice da caricare su Arduino Nano:

#include <Wire.h>
#define BACKLIGHT_PIN 3
#define LED_BLUE 
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 0x27 is the I2C bus address for an unmodified backpack


// D7 out LED Blue
// A0 in valore fotocellula

int LEDBLUE = 7;
int strTest = 0;

int iCounter = 0;
int iDelay = 500;

int inReset = 9; 
int inValReset = 0;

int inMinus = 10; 
int inValMinus = 0;

int inPlus = 11; 
int inValPlus = 0;

int iStatus = 0;

void setup() {

// inizializzo modulo LCD 
lcd.begin (16,2); // for 16 x 2 LCD module
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);

// Inizializzo IN / OUT
pinMode(LEDBLUE, OUTPUT);
pinMode(inReset, INPUT);


Serial.begin(9600);

lcd.home (); // riposizione il cursore del display a 0,0
lcd.print("Elettronica"); 
lcd.setCursor (0,1); // riposizione il cursore in seconda linea
lcd.print("Club.eu"); 
delay(5000);

iCounter = 0;
iDelay = 500;
iStatus = 0;

}

void loop() {

digitalWrite(LEDBLUE, LOW); // LED off = LOW
strTest = 0;

inValReset = digitalRead(inReset); // lettura valore di input
if ((inValReset == HIGH) && (iStatus == 0)) { // verifica se input è HIGH (button released)
Serial.println("Reset Premuto");
iStatus=1;

digitalWrite(LEDBLUE, LOW); // LED off = LOW
strTest = 0;
iCounter = 0;

// Pulisco il display
lcd.setCursor (0,0); 
lcd.print("---- RESET -----"); 
lcd.setCursor (0,1); 
lcd.print("--- RICEVUTO ---"); 
delay(1000);
// Pulisco il display
lcd.setCursor (0,0); 
lcd.print(" RESET "); 
lcd.setCursor (0,1); 
lcd.print(" ");

}


while (iStatus == 1) { // mentre input è HIGH (button released)

inValMinus = digitalRead(inMinus); // leggi valore di input
if (inValMinus == HIGH) { // controlla se bottone HIGH (button released)
if (iDelay > 150) iDelay=iDelay-150;
}

inValPlus = digitalRead(inPlus); // leggi valore di input
if (inValPlus == HIGH) { // controlla se bottone HIGH (button released)
iDelay=iDelay+150;
}

// Pulisco il display
lcd.setCursor (0,0); 
lcd.print("---- RITARDO -----"); 
lcd.setCursor (0,1); 
lcd.print(String(iDelay)+" ");

inValReset = digitalRead(inReset); // leggi valore di input
if ((inValReset == HIGH) && (iStatus == 1)) { // controlla se bottone HIGH (button released)

// Pulisco il display
lcd.setCursor (0,0); 
lcd.print("IMPOSTAZIONE "); 
lcd.setCursor (0,1); 
lcd.print("TERMINATA ");

Serial.println("Reset Premuto Seconda Volta");
iStatus=0;

delay(1500);
}

Serial.println("Valore Delay "+String(iDelay));

}

Serial.println("Stato "+String(iStatus));

if (iStatus==0){

// Legge in alore della fotoresistenza dal PIN analogico 0:
int sensorValue = analogRead(A0);
// Conversione da valore analogico (da 0 - 1023) a valore di tensione discreta (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// scrive in debug il valore convertito:
//Serial.println(voltage);

lcd.setCursor (0,0); // riposizione il cursore del display a 0,0
lcd.print("Valore: "+String(voltage)); 

if (voltage<0.5) {
strTest=1;
digitalWrite(LEDBLUE, HIGH); // LED on
iCounter++;
delay(iDelay);
}

lcd.setCursor (0,1); 
lcd.print(">"+String(strTest)+"<TOT: "+String(iCounter));

}

}

Buon Divertimento!

Ti è piaciuto questo progetto?
Iscrivite oggi stesso alla nostra newsletter e ricevi gli aggiornamenti su tutti i nostri nuovi progetti direttamente nella tua email!
I agree to have my personal information transfered to MailChimp ( more information )

Lascia una Risposta

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.