### 4.3.9 Micro:bit マルチセンサー OLED 監視プラットフォーム
#### 4.3.9.1 概要

このプロジェクトでは、Micro:bit ボードをコアの処理ユニットとして、内蔵センサー(光センサー、温度センサー、マイク)および外部センサー(PM2.5粉じんセンサー、蒸気センサー、太陽紫外線センサーなど)の値を読み取り、I2C インターフェースを通じて OLED にリアルタイムで表示します。
同時に、Micro:bit ボードのボタン A を押すことで 130 モジュールのファンの回転を制御し、ボタン B を押すことで加湿(atomization)モジュールからの水蒸気噴霧を制御できます。

#### 4.3.9.2 必要な部品
| |  ||
| :--: | :--: | :--: |
| micro:bit V2 ボード ×1 | micro:bit シールド ×1 | OLED ディスプレイ ×1 |
| |||
| PM2.5 粉じんセンサー ×1 | モータ ×1 | 蒸気センサー ×1 |
||| |
| 紫外線センサー ×1 | 電池ホルダー ×1 | AA電池(**別途用意**) ×6 |
| |||
| micro USB ケーブル ×1 | 4ピンワイヤ ×3 | 3ピンワイヤ ×3 |
| |  | |
| 加湿モジュール ×1 | ファン ×1 | |
#### 4.3.9.3 配線図
⚠️ **配線する際は、必ず配線の色に注意してください。**
| 紫外線センサー | 配線色 | micro:bit シールドのピン | micro:bit ボードのピン |
| :------------: | :----: | :----------------------: | :--------------------: |
| G | 黒 | G | G |
| V | 赤 | V2 | V |
| S | 黄 | 0 | P0 |
| 蒸気センサー | 配線色 | micro:bit シールドのピン | micro:bit ボードのピン |
| :----------: | :----: | :----------------------: | :--------------------: |
| G | 黒 | G | G |
| V | 赤 | V1 | V |
| S | 黄 | 1 | P1 |
| PM2.5 粉じんセンサー | 配線色 | micro:bit シールドのピン | micro:bit ボードのピン |
| :-------------------: | :----: | :----------------------: | :--------------------: |
| GND | 黒 | G | G |
| VCC | 赤 | V2 | V |
| LED | 青 | 9 | P9 |
| OUT | 緑 | 2 | P2 |
| 加湿(atomization)モジュール | 配線色 | micro:bit シールドのピン | micro:bit ボードのピン |
| :--------------------------: | :----: | :----------------------: | :--------------------: |
| G | 黒 | G | G |
| V | 赤 | V2 | V |
| S | 黄 | 16 | P16 |
| モータ | 配線色 | micro:bit シールドのピン | micro:bit ボードのピン |
| :----: | :----: | :----------------------: | :--------------------: |
| G | 黒 | G | G |
| V | 赤 | V2 | V |
| IN+ | 青 | 13 | P13 |
| IN- | 緑 | 15 | P15 |
| OLED 表示 | 配線色 | micro:bit シールドのピン | micro:bit ボードのピン |
| :-------: | :----: | :----------------------: | :--------------------: |
| GND | 黒 | G | G |
| VCC | 赤 | V2 | V |
| SDA | 青 | 20 | P20 |
| SCL | 緑 | 19 | P19 |

#### 4.3.9.4 コードフロー

#### 4.3.9.5 テスト用コード
⚠️ **Tip 1: Microbit ボードにコードをダウンロードする前に、ライブラリファイル “oled_ssd1306\.py” をインポートしてください。参照: ** “[Import Library on MU](https://docs.keyestudio.com/projects/KS4050/en/latest/docs/MicroPython/MU_development_environment.html#import-library-on-mu)” 。

⚠️ **Tip 2: もしライブラリファイル "XHT11\.py" が既に Micro:bit ボードにインポートされている場合は、Micro:bit 本体のメモリ不足を招き、サンプルコードのダウンロードに失敗することがあるため、Micro:bit 本体から削除する必要があります。**
「Files」ボタンをクリックし、左側のボックスにあるライブラリファイル「XHT11\.py」を右クリックすると「Delete (cannot be undone)」オプションが表示されます。表示された「Delete (cannot be undone)」をクリックすると、ライブラリファイル「XHT11\.py」が削除されます。

**完全なコード:**
```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) # LED matrix displays a happy pattern
# 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 OFF
microsecond_delay(delayTime) # 280μs
dustVal = out_Pin.read_analog() # Read the PM2.5 dust sensor
microsecond_delay(delayTime2) # 40μs
led_Pin.write_digital(1) # LED ON
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(): # if button_a.is pressed
sleep(200)
pin13.write_digital(1) # the fan is rotating.
pin15.write_digital(0)
sleep(200)
else: # or
pin13.write_digital(0) # the fan does not rotate.
pin15.write_digital(0)
if button_b.is_pressed(): # if button_b.is pressed
pin16.write_digital(0) # the atomization module sprays water mist.
sleep(200)
pin16.write_digital(1)
sleep(3000)
pin16.write_digital(0)
sleep(200)
pin16.write_digital(1)
sleep(1000)
else: # or
pin16.write_digital(1) # the atomization module does not spray water mist.
add_text(0, 0, "Temper:")
add_text(7, 0, str(int(Temperature)) + "C") # Display the Temperature value on the OLED
add_text(0, 2, "UV:")
add_text(3, 2, str(int(uv))) # Display the UV value on the OLED
add_text(5, 2, " | Rain:")
add_text(13, 2, str(int(rain_percent)) + "%") # Display the percentage of rainfall on the OLED
add_text(0, 4, "Light:")
add_text(6, 4, str(Lightintensity)) # Display the light intensity on the OLED
add_text(9, 4, " | Sound:")
add_text(18, 4, str(soundLevel)) # Display the noise intensity on the 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)
```

**簡単な説明:**
① microbit、oled_ssd1306、math、time のライブラリをインポートします。
```Python
from microbit import *
from oled_ssd1306 import *
import math
import time
```
② 5×5 LED マトリクスに  を表示します。
```Python
display.show(Image.HAPPY)
```
③ OLED を初期化し、OLED をクリアします。
```Python
initialize()
clear_oled()
```
④ PM2.5 粉じんセンサーのピンを初期化します。
```Python
out_Pin = pin2
led_Pin = pin9
```
⑤ 蒸気センサーのピンと変数を初期化します。
```Python
Steam_PIN = pin1
WET_VALUE = 1023
DRY_VALUE = 0
```
⑥ 太陽紫外線センサーのピンを初期化します。
```Python
uv_sensor = pin0
```
⑦ 時間変数の初期値を設定します。
```Python
delayTime = 280
delayTime2 = 40
offTime = 9680
```
⑧ 任意の数値範囲を別の範囲へマッピングするサブ関数を定義します。
```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
```
⑨ 降雨量(雨量)パーセンテージを取得するサブ関数を定義します。
```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))
```
⑩ 太陽紫外線センサーで検出した紫外線強度(UV指数)を取得するサブ関数を定義します。
```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)
```
⑪ マイクロ秒単位の遅延を行うサブ関数を定義します。
```Python
def microsecond_delay(us):
"""Precise microsecond delay"""
start = time.ticks_us()
while time.ticks_diff(time.ticks_us(), start) < us:
pass
```
⑫ PM2.5 粉じんセンサーの測定タイミング制御を設定します。これは主に空気中の粉じん濃度を検出するために使用します。
```Python
led_Pin.write_digital(0) # LED OFF
microsecond_delay(delayTime) # 280μs
dustVal = out_Pin.read_analog() # Read the PM2.5 dust sensor
microsecond_delay(delayTime2) # 40μs
led_Pin.write_digital(1) # LED ON
microsecond_delay(offTime) # 9680μs
```
⑬ 光強度、温度、音量、降雨量、紫外線の値を読み取ります。
```Python
Lightintensity = display.read_light_level()
Temperature = temperature()
soundLevel = microphone.sound_level()
rain_percent = get_rain_percentage()
uv = read_uv_index()
```
⑭ 条件判定 if()...else...
Micro:bit ボードのボタン A を押すと、モータがファンを駆動して回転します。押さない場合はファンは回転しません。
```Python
if button_a.is_pressed(): # if button_a.is pressed
sleep(200)
pin13.write_digital(1) # the fan is rotating.
pin15.write_digital(0)
sleep(200)
else: # or
pin13.write_digital(0) # the fan does not rotate.
pin15.write_digital(0)
```
⑮ 条件判定 if()...else...
Micro:bit ボードのボタン B を押すと、加湿(atomization)モジュールがミストを噴霧します。押さない場合は噴霧しません。
```Python
if button_b.is_pressed(): # if button_b.is pressed
pin16.write_digital(0) # the atomization module sprays water mist.
sleep(200)
pin16.write_digital(1)
sleep(3000)
pin16.write_digital(0)
sleep(200)
pin16.write_digital(1)
sleep(1000)
else: # or
pin16.write_digital(1) # the atomization module does not spray water mist.
```
⑯ 紫外線、温度、降雨量、光強度、音量の値を OLED に表示します。
```Python
add_text(0, 0, "Temper:")
add_text(7, 0, str(int(Temperature)) + "C") # Display the Temperature value on the OLED
add_text(0, 2, "UV:")
add_text(3, 2, str(int(uv))) # Display the UV value on the OLED
add_text(5, 2, " | Rain:")
add_text(13, 2, str(int(rain_percent)) + "%") # Display the percentage of rainfall on the OLED
add_text(0, 4, "Light:")
add_text(6, 4, str(Lightintensity)) # Display the light intensity on the OLED
add_text(9, 4, " | Sound:")
add_text(18, 4, str(soundLevel)) # Display the noise intensity on the OLED
```
⑰ PM2.5 粉じんのアナログ値が 36.455 を超えた場合、その濃度値を計算して OLED に表示します。超えない場合はシリアルモニタに該当する粉じんアナログ値を出力します。
```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 テスト結果

配線と micro USB ケーブルでの給電を行い、外部電源(AA×6)を接続して十分な電力供給を確保した後、“Flash” をクリックしてコードを Micro:bit ボードにダウンロードしてください。

テストコードをアップロードした後、Micro:bit の背面にあるリセットボタンを押してください。

内蔵センサー(光センサー、温度センサー、マイク)および外部センサー(PM2.5 粉じんセンサー、蒸気センサー、太陽紫外線センサーなど)の値を読み取り、I2C インターフェースの OLED 表示画面を通じて、光強度、温度、騒音強度、降雨強度(湿潤度)、日光の紫外線強度、PM2.5 粉じん濃度をリアルタイムかつ直感的に表示できます。
Micro:bit 本体のマイクに向かって息を吹きかける(または非常に大きな音を発する)と(⚠️ **特別リマインダー: 息を吹きかける方がより顕著な効果があります**)、OLED 表示にその風量(または音量)が表示されます。
Micro:bit ボードのボタン A を押すとモジュール上のファンが回転し、ボタン B を押すと加湿(atomization)モジュールがミストを噴霧します。
⚠️ 特別リマインダー: 外部電源の電圧が不十分な場合があります。その場合は、ファンが回転を開始したり噴霧モジュールが動作を開始したりするまで、Micro:bit のボタンを 2 回押す必要があることがあります。

⚠️ **注意: 実験で使用しているブロック(building blocks)は本キットに含まれていません。**
(**Tip:** 結果が表示されない場合は、Micro:bit ボードのリセットボタンを押してください。)
