Vai al contenuto
QuinciSoft

Luxmetro con Seeeduino XIAO

Un luxmetro economico con scheda XIAO, sensore TSL2591 e display a colori.

  • Hardware
  • Codice
Il luxmetro in un contenitore nero, con display a colori e sensore luminoso.

L’idea

Dovendo misurare la luminosità di alcuni ambienti, e dato che gli strumenti per farlo non sono molto economici, ho deciso di realizzarlo io. Per curiosità ho usato la scheda Seeeduino XIAO di Seeed Studio (la documentazione è nei link in fondo alla pagina) e, come sensore, un TSL2591: a mio parere tra i sensori ottici per hobbisti è uno dei più efficienti, con un buon rapporto qualità prezzo.

Il luxmetro mostra su un display a colori i valori letti dal sensore (infrarosso, spettro completo, luce visibile e lux) e dà un giudizio sulla luminosità con una scritta e con due LED.

Hardware

Un difetto da conoscere: il bootloader

La Seeeduino XIAO è molto valida, ma ha un piccolo neo: a volte non si riescono a caricare i programmi perché la scheda non entra in modalità bootloader. Se succede, dopo aver collegato la scheda al computer basta mettere in cortocircuito i due pin siglati RST che si trovano a fianco del connettore USB. Se, collegandola, non compare nessuna porta COM, vuol dire che la scheda non è entrata in modalità bootloader.

I collegamenti

I due LED segnalano la luminosità: il LED rosso acceso indica luminosità insufficiente oppure illuminazione alta, fuori scala.

LED
FunzionePin della XIAO
LED rosso3
LED verde2

Il display

Display TFT 240×240 IPS con controller ST7789.

Collegamenti del display
Pin del displayPin della Seeeduino XIAO
GNDGND
VCC3V3
SCL8
SDA10
RES0
DC1
BLKnon collegato

Il display parla con la scheda attraverso il bus SPI: SCL è il segnale di clock e SDA quello dei dati. Il modulo non ha un pin CS: nel codice la costante TFT_CS vale 10, lo stesso pin collegato a SDA.

Il sensore TSL2591

Collegamenti del sensore
Pin del sensorePin della Seeeduino XIAO
GNDGND
VCC3V3
SDA4
SCL5

Il sensore usa il bus I²C (libreria Wire), che sulla XIAO ha proprio i pin 4 (SDA) e 5 (SCL).

Codice

Il sorgente

Il codice completo è nel file luxmetro2591.ino, da scaricare in fondo alla pagina: si apre direttamente con l’Arduino IDE. Io l’ho sviluppato con PlatformIO, dove lo stesso programma sta nel file src/main.cpp; la configurazione del progetto è questa:

[env:seeed_xiao]
platform = atmelsam
board = seeed_xiao
framework = arduino
lib_deps =
    adafruit/Adafruit ST7735 and ST7789 Library@^1.8.0
    adafruit/Adafruit GFX Library@^1.11.2
    adafruit/Adafruit TSL2591 Library@^1.4.2
    adafruit/Adafruit BusIO@^1.11.6

Con l’Arduino IDE le stesse librerie si installano dal gestore librerie, scegliendo come scheda la Seeeduino XIAO (il pacchetto di schede si trova nella documentazione di Seeed Studio, nei link in fondo alla pagina).

La struttura del programma

I numeri delle righe sono quelli del file luxmetro2591.ino.

I blocchi del sorgente
RigheChe cosa contengono
1-7Le librerie: grafica (Adafruit_GFX), SPI, display ST7789, Wire (I²C), supporto ai sensori Adafruit e libreria del TSL2591.
9-15I pin (TFT_CS 10, TFT_RST 0, TFT_DC 1, LED_ROSSO 3, LED_VERDE 2) e i due oggetti: tft (display) e tsl (sensore).
24-25Le variabili: prova (0 per usare il display, diverso da 0 per stampare i valori sul monitor seriale) e due stringhe di appoggio per i testi.
27-72setup(): avvia seriale, LED, display e sensore, mostra la schermata iniziale.
74-118loop(): legge la luminosità, scrive il giudizio e accende i LED, poi aspetta 4 secondi.
121-161configureSensor(): imposta guadagno e tempo di integrazione del sensore.
163-220advancedRead(): legge il sensore, calcola i lux, scrive i valori sul display e restituisce la categoria di luminosità.
223-268simpleRead(): una lettura più semplice, della sola luce visibile. Nel loop() è disattivata (commentata).
273-311displaySensorDetails() e unifiedSensorAPIRead(): funzioni di esempio della libreria, per il monitor seriale. Non sono usate.

setup(): avvio

All’accensione il programma avvia la seriale a 9600 baud, imposta i due pin dei LED come uscite e inizializza il display a 240×240 punti (tft.init(240, 240, SPI_MODE2), rotazione 3). Mostra per 3,5 secondi la schermata di presentazione, un riquadro verde con la scritta «QuinciSoft LuxTsl2591» in rosso, poi spegne i LED, avvia il sensore con tsl.begin() e chiama configureSensor().

configureSensor(): guadagno e tempo

tsl.setGain(TSL2591_GAIN_MED);                  // guadagno 25x
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);   // tempo di integrazione: 100 ms

Il TSL2591 può adattarsi a luci diverse cambiando il guadagno (quanto amplifica il segnale: 1×, 25×, 428× o 9876×) e il tempo di integrazione (per quanto tempo raccoglie la luce: da 100 a 600 ms). Un tempo lungo e un guadagno alto servono con poca luce; un tempo breve e un guadagno basso con tanta luce. Nel programma sono scelti guadagno medio e 100 ms; le altre combinazioni sono lasciate come commenti da attivare. La funzione scrive poi sul monitor seriale i valori impostati.

advancedRead(): la lettura

uint32_t lum = tsl.getFullLuminosity();
uint16_t ir, full;
ir   = lum >> 16;          // 16 bit alti: infrarosso
full = lum & 0xFFFF;       // 16 bit bassi: spettro completo
double lux = tsl.calculateLux(full, ir);

Il sensore ha due fotodiodi, uno sensibile a tutto lo spettro e uno all’infrarosso. La libreria restituisce i due valori in un unico numero a 32 bit: il programma li separa con uno spostamento di bit e una maschera. La luce visibile è la differenza tra i due (full - ir), e i lux li calcola la libreria a partire da entrambi. Sul display i quattro valori compaiono su quattro righe, in colori diversi (IR rosso, Full bianco, Vis. giallo, Lux blu). Prima di riscrivere ogni valore il programma cancella con un rettangolo nero (fillRect) quello precedente, altrimenti le cifre si sovrapporrebbero.

La funzione restituisce anche una categoria, in base ai lux:

Giudizio sulla luminosità
LuxCategoriaScrittaLED
fino a 1000«Insuff.»solo il rosso
da 100 a 2001«Scarsa.»rosso e verde
oltre 2002«Ok.»solo il verde

Luce troppo intensa (fuori scala). Se il sensore satura, la libreria restituisce per i lux il valore −1 (accanto a «Lux:» il display scrive -1.00). Il programma lo tratta come la categoria 0: compare «Insuff.» e si accende il LED rosso. Per questo il LED rosso segnala sia la luminosità insufficiente sia l’illuminazione alta fuori scala: per distinguere i due casi basta guardare il valore dei lux.

loop(): giudizio e LED

scelta = advancedRead();
switch (scelta) {
  case 0: /* "Insuff." - LED rosso */ break;
  case 1: /* "Scarsa." - LED rosso e verde */ break;
  default:
  case 2: /* "Ok." - LED verde */ break;
}
delay(4000);               // una misura ogni 4 secondi

A ogni giro il programma legge il sensore, scrive in basso la scritta corrispondente alla categoria (dopo aver cancellato quella precedente) e imposta i due LED. Poi attende 4 secondi: la misura si aggiorna quindi circa ogni quattro secondi.

Altre note sul codice

  • Per leggere i valori sul monitor seriale invece che sul display, basta mettere prova a un valore diverso da 0.
  • Nel codice, accanto alla definizione del LED verde, c’è il commento «prima 4»: in una versione precedente il LED era collegato al pin 4.

Prova

Nella foto il luxmetro, in un contenitore nero, misura circa 54 lux: essendo sotto i 100 lux, il display mostra «Insuff.» e si accende il LED rosso.

Scarica

Questi link portano a siti esterni, che si aprono in una nuova scheda.

Hai domande su questo progetto?

Scrivimi dalla pagina Contatti: ti rispondo appena possibile.

← Tutti i progetti di «Microcontrollori»