### 4.3.9 Micro:bit Multi-sensor OLED Monitoring Platform
#### 4.3.9.1 Panoramica

In questo progetto utilizziamo la scheda micro:bit come unità di elaborazione principale per leggere i valori dei suoi sensori integrati (inclusi sensore di luce, sensore di temperatura, microfono) e dei sensori esterni (come il sensore di polveri PM2.5, il sensore di pioggia e il sensore solare ultravioletti). Questi valori vengono poi visualizzati in tempo reale sull'OLED tramite l'interfaccia I2C.
Allo stesso tempo, la rotazione della ventola sul modulo motore 130 può essere controllata premendo il tasto A sulla scheda Micro:bit, mentre la nebulizzazione dall'atomizer può essere attivata premendo il tasto B sulla scheda Micro:bit.

#### 4.3.9.2 Componenti necessari
| |  ||
| :--: | :--: | :--: |
| micro:bit V2 board ×1 | micro:bit shield ×1 |OLED display ×1 |
| |||
| sensore di polveri PM2.5 ×1 | motore ×1 | sensore di pioggia ×1 |
||| |
| sensore solare UV ×1 | portabatterie ×1 | Batterie AA(**da procurare**) ×6 |
| |||
| cavo micro USB ×1 | cavo 4 pin ×3 | cavo 3 pin ×3 |
| |  | |
| modulo di atomizzazione ×1 | ventola ×1 | |
#### 4.3.9.3 Schema di collegamento
⚠️ **Quando si eseguono i collegamenti, prestare attenzione al colore dei fili.**
| sensore ultravioletti | colore filo | pin micro:bit shield | pin scheda micro:bit |
| :----------------: | :--------: | :------------------: | :-----------------: |
| G | nero | G | G |
| V | rosso | V2 | V |
| S | giallo | 0 | P0 |
| sensore di pioggia | colore filo | pin micro:bit shield | pin scheda micro:bit |
| :----------: | :--------: | :------------------: | :-----------------: |
| G | nero | G | G |
| V | rosso | V1 | V |
| S | giallo | 1 | P1 |
| sensore polveri PM2.5 | colore filo | pin micro:bit shield | pin scheda micro:bit |
| :---------------: | :--------: | :------------------: | :-----------------: |
| GND | nero | G | G |
| VCC | rosso | V2 | V |
| LED | blu | 9 | P9 |
| OUT | verde | 2 | P2 |
| modulo di atomizzazione | colore filo | pin micro:bit shield | pin scheda micro:bit |
| :----------------: | :--------: | :------------------: | :-----------------: |
| G | nero | G | G |
| V | rosso | V2 | V |
| S | giallo | 16 | P16 |
| motore | colore filo | pin micro:bit shield | pin scheda micro:bit |
| :---: | :--------: | :------------------: | :-----------------: |
| G | nero | G | G |
| V | rosso | V2 | V |
| IN+ | blu | 13 | P13 |
| IN- | verde | 15 | P15 |
| display OLED | colore filo | pin micro:bit shield | pin scheda micro:bit |
| :----------: | :--------: | :------------------: | :-----------------: |
| GND | nero | G | G |
| VCC | rosso | V2 | V |
| SDA | blu | 20 | P20 |
| SCL | verde | 19 | P19 |

#### 4.3.9.4 Flusso del codice

#### 4.3.9.5 Codice di test
⚠️ **Suggerimento 1: Prima di scaricare il codice sulla scheda Microbit, importare il file di libreria “oled_ssd1306\.py” facendo riferimento a ** “[Import Library on MU](https://docs.keyestudio.com/projects/KS4050/en/latest/docs/MicroPython/MU_development_environment.html#import-library-on-mu)” .

⚠️ **Suggerimento 2: Se il file di libreria "XHT11\.py" è già stato importato sulla scheda micro:bit in precedenza, è necessario rimuoverlo dalla scheda micro:bit. Altrimenti, potrebbe causare memoria insufficiente sulla scheda Microbit, impedendo il corretto download del codice di esempio sulla scheda Microbit. **
Fare clic sul pulsante "Files", quindi fare clic con il tasto destro sul file di libreria "XHT11\.py" nella casella a sinistra, appare l'opzione "Delete (cannot be undone)", fare clic sull'opzione "Delete (cannot be undone)". In questo modo, il file di libreria "XHT11\.py" verrà eliminato.

**Codice completo:**
```Python
'''
Theme: A multi-sensor OLED monitoring platform based on Micro:bit
Function: OLED displays the values of multiple sensors
Compiling IDE: MU 1.2.0
Author: https://docs.keyestudio.com
'''
# import related libraries
from microbit import *
from oled_ssd1306 import *
import math
import time
display.show(Image.HAPPY) # La matrice LED mostra un pattern felice
# initialize and clear oled
initialize()
clear_oled()
# Hardware connection: PM2.5 dust sensor
out_Pin = pin2
led_Pin = pin9
# Hardware connection: steam sensor
Steam_PIN = pin1
WET_VALUE = 1023
DRY_VALUE = 0
# Initialize the ADC pin (the ultraviolet sensor is connected to pin0)
uv_sensor = pin0
# Time parameter
delayTime = 280
delayTime2 = 40
offTime = 9680
def map_value(value, in_min, in_max, out_min, out_max):
"""Linearly map the input values to the output range"""
if in_max - in_min == 0:
return out_min
return (value - in_min) * (out_max - out_min) // (in_max - in_min) + out_min
def get_rain_percentage():
"""Read the sensor and return the percentage of rainfall"""
raw_value = Steam_PIN.read_analog()
percentage = map_value(raw_value, DRY_VALUE, WET_VALUE, 0, 100)
return max(0, min(100, percentage))
def read_uv_index():
raw_value = uv_sensor.read_analog()
if raw_value > 1023:
raw_value = 1023
elif raw_value < 0:
raw_value = 0
uvi = raw_value * (15.0 / 1023)
return round(uvi, 1)
def microsecond_delay(us):
"""Precise microsecond delay"""
start = time.ticks_us()
while time.ticks_diff(time.ticks_us(), start) < us:
pass
while True:
# Measurement sequence
led_Pin.write_digital(0) # LED SPENTO
microsecond_delay(delayTime) # 280μs
dustVal = out_Pin.read_analog() # Legge il sensore polveri PM2.5
microsecond_delay(delayTime2) # 40μs
led_Pin.write_digital(1) # LED ACCESO
microsecond_delay(offTime) # 9680μs
Lightintensity = display.read_light_level()
Temperature = temperature()
soundLevel = microphone.sound_level()
rain_percent = get_rain_percentage()
uv = read_uv_index()
clear_oled()
if button_a.is_pressed(): # se button_a è premuto
sleep(200)
pin13.write_digital(1) # la ventola è in rotazione.
pin15.write_digital(0)
sleep(200)
else: # altrimenti
pin13.write_digital(0) # la ventola non ruota.
pin15.write_digital(0)
if button_b.is_pressed(): # se button_b è premuto
pin16.write_digital(0) # il modulo di atomizzazione spruzza nebbia d'acqua.
sleep(200)
pin16.write_digital(1)
sleep(3000)
pin16.write_digital(0)
sleep(200)
pin16.write_digital(1)
sleep(1000)
else: # altrimenti
pin16.write_digital(1) # il modulo di atomizzazione non spruzza nebbia d'acqua.
add_text(0, 0, "Temper:")
add_text(7, 0, str(int(Temperature)) + "C") # Visualizza il valore della temperatura sull'OLED
add_text(0, 2, "UV:")
add_text(3, 2, str(int(uv))) # Visualizza il valore UV sull'OLED
add_text(5, 2, " | Rain:")
add_text(13, 2, str(int(rain_percent)) + "%") # Visualizza la percentuale di pioggia sull'OLED
add_text(0, 4, "Light:")
add_text(6, 4, str(Lightintensity)) # Visualizza l'intensità luminosa sull'OLED
add_text(9, 4, " | Sound:")
add_text(18, 4, str(soundLevel)) # Visualizza l'intensità sonora sull'OLED
# Calculation and display
if dustVal > 36.455:
# The exact same calculation formula
voltage = dustVal / 1024.0
pm25 = (voltage - 0.0356) * 120000 * 0.035
# OLED displays detailed PM2.5dust value information.
add_text(0, 6, "PM2.5dust:")
add_text(10, 6, str(round(pm25)) + "ug/m3")
else:
print("Low value:", dustVal)
sleep(500)
```

**Breve spiegazione:**
① Importare le librerie microbit, oled_ssd1306, math e time.
```Python
from microbit import *
from oled_ssd1306 import *
import math
import time
```
② La matrice LED 5×5 mostra .
```Python
display.show(Image.HAPPY)
```
③ Inizializzare i pixel dell'OLED e pulire l'OLED.
```Python
initialize()
clear_oled()
```
④ Inizializzare i pin del sensore di polveri PM2.5.
```Python
out_Pin = pin2
led_Pin = pin9
```
⑤ Inizializzare il pin e le variabili del sensore di pioggia.
```Python
Steam_PIN = pin1
WET_VALUE = 1023
DRY_VALUE = 0
```
⑥ Inizializzare il pin del sensore solare ultravioletti.
```Python
uv_sensor = pin0
```
⑦ Impostare i valori iniziali delle variabili temporali.
```Python
delayTime = 280
delayTime2 = 40
offTime = 9680
```
⑧ Definire una funzione di mapping (per mappare un intervallo di numeri in un altro).
```Python
def map_value(value, in_min, in_max, out_min, out_max):
"""Linearly map the input values to the output range"""
if in_max - in_min == 0:
return out_min
return (value - in_min) * (out_max - out_min) // (in_max - in_min) + out_min
```
⑨ Definire una funzione per ottenere la percentuale di pioggia.
```Python
def get_rain_percentage():
"""Read the sensor and return the percentage of rainfall"""
raw_value = Steam_PIN.read_analog()
percentage = map_value(raw_value, DRY_VALUE, WET_VALUE, 0, 100)
return max(0, min(100, percentage))
```
⑩ Definire una funzione per ottenere l'indice UV rilevato dal sensore solare ultravioletti.
```Python
def read_uv_index():
raw_value = uv_sensor.read_analog()
if raw_value > 1023:
raw_value = 1023
elif raw_value < 0:
raw_value = 0
uvi = raw_value * (15.0 / 1023)
return round(uvi, 1)
```
⑪ Definire una funzione per il ritardo in microsecondi.
```Python
def microsecond_delay(us):
"""Precise microsecond delay"""
start = time.ticks_us()
while time.ticks_diff(time.ticks_us(), start) < us:
pass
```
⑫ Impostare il controllo del timing di misura del sensore di polveri PM2.5, utilizzato principalmente per rilevare la concentrazione di polveri nell'aria.
```Python
led_Pin.write_digital(0) # LED SPENTO
microsecond_delay(delayTime) # 280μs
dustVal = out_Pin.read_analog() # Legge il sensore polveri PM2.5
microsecond_delay(delayTime2) # 40μs
led_Pin.write_digital(1) # LED ACCESO
microsecond_delay(offTime) # 9680μs
```
⑬ Leggere i valori di intensità luminosa, temperatura, livello sonoro, percentuale di pioggia e ultravioletti.
```Python
Lightintensity = display.read_light_level()
Temperature = temperature()
soundLevel = microphone.sound_level()
rain_percent = get_rain_percentage()
uv = read_uv_index()
```
⑭ Istruzione di controllo: if()...else...
Premere il tasto A sulla scheda micro:bit farà avviare la ventola mediante il motore. Altrimenti, la ventola non ruoterà.
```Python
if button_a.is_pressed(): # se button_a è premuto
sleep(200)
pin13.write_digital(1) # la ventola è in rotazione.
pin15.write_digital(0)
sleep(200)
else: # altrimenti
pin13.write_digital(0) # la ventola non ruota.
pin15.write_digital(0)
```
⑮ Istruzione di controllo: if()...else...
Premere il tasto B sulla scheda micro:bit farà attivare il modulo di atomizzazione per spruzzare la nebbia d'acqua. Altrimenti, non funzionerà.
```Python
if button_b.is_pressed(): # se button_b è premuto
pin16.write_digital(0) # il modulo di atomizzazione spruzza nebbia d'acqua.
sleep(200)
pin16.write_digital(1)
sleep(3000)
pin16.write_digital(0)
sleep(200)
pin16.write_digital(1)
sleep(1000)
else: # altrimenti
pin16.write_digital(1) # il modulo di atomizzazione non spruzza nebbia d'acqua.
```
⑯ Visualizzare i valori di ultravioletti, temperatura, percentuale di pioggia, intensità luminosa e livello sonoro sull'OLED.
```Python
add_text(0, 0, "Temper:")
add_text(7, 0, str(int(Temperature)) + "C") # Visualizza il valore della temperatura sull'OLED
add_text(0, 2, "UV:")
add_text(3, 2, str(int(uv))) # Visualizza il valore UV sull'OLED
add_text(5, 2, " | Rain:")
add_text(13, 2, str(int(rain_percent)) + "%") # Visualizza la percentuale di pioggia sull'OLED
add_text(0, 4, "Light:")
add_text(6, 4, str(Lightintensity)) # Visualizza l'intensità luminosa sull'OLED
add_text(9, 4, " | Sound:")
add_text(18, 4, str(soundLevel)) # Visualizza l'intensità sonora sull'OLED
```
⑰ Quando il valore analogico delle polveri PM2.5 supera 36.455, è possibile calcolare la concentrazione e visualizzarla sull'OLED. Altrimenti, il monitor seriale stampa i corrispondenti valori analogici delle polveri.
```Python
if dustVal > 36.455:
# The exact same calculation formula
voltage = dustVal / 1024.0
pm25 = (voltage - 0.0356) * 120000 * 0.035
# OLED displays detailed PM2.5dust value information.
add_text(0, 6, "PM2.5dust:")
add_text(10, 6, str(round(pm25)) + "ug/m3")
else:
print("Low value:", dustVal)
```
#### 4.3.9.6 Risultato del test

Dopo aver eseguito i collegamenti e aver alimentato tramite cavo micro USB, collegare anche l'alimentazione esterna (6 batterie AA) per assicurare una fornitura adeguata di energia, quindi cliccare su “Flash” per scaricare il codice sulla scheda micro:bit.

Dopo aver caricato il codice di test, premere il pulsante di reset sul retro del micro:bit.

Legge i valori dei suoi sensori integrati (inclusi sensore di luce, sensore di temperatura, microfono) e dei sensori esterni (come sensore di polveri PM2.5, sensore di pioggia e sensore solare ultravioletti), e può visualizzare in modo intuitivo e in tempo reale l'intensità luminosa, la temperatura, il livello di rumore, l'intensità di pioggia, l'intensità ultravioletta del sole e la concentrazione di polveri PM2.5 sullo schermo OLED con interfaccia I2C.
Soffiare aria (o fare un rumore molto forte) nel microfono sulla scheda Microbit (⚠️ **promemoria speciale: Soffiare aria ha un effetto più evidente**), e l'OLED mostrerà l'intensità dell'aria soffiata (o del rumore).
Quando si preme il tasto A sulla scheda micro:bit, la ventola sul modulo motore ruota. Quando si preme il tasto B sulla scheda, il modulo di atomizzazione spruzza la nebbia d'acqua.
⚠️ Promemoria speciale: A volte la tensione dell'alimentazione esterna potrebbe non essere sufficiente. In tali casi, potrebbe essere necessario premere il tasto due volte sulla scheda micro:bit prima che la ventola inizi a ruotare o che il modulo di nebulizzazione inizi a spruzzare.

⚠️ **Nota: I mattoncini (building blocks) usati nell'esperimento non sono inclusi in questo kit.**
(**Suggerimento:** Se non si osservano risultati, premere il pulsante di reset della scheda micro:bit.)
