### 4.3.9 Micro:bit マルチセンサー OLED 監視プラットフォーム #### 4.3.9.1 概要 ![Img](./media/top1.png) このプロジェクトでは、Micro:bit ボードをコアの処理ユニットとして、内蔵センサー(光センサー、温度センサー、マイク)および外部センサー(PM2.5粉じんセンサー、蒸気センサー、太陽紫外線センサーなど)の値を読み取り、I2C インターフェースを通じて OLED にリアルタイムで表示します。 同時に、Micro:bit ボードのボタン A を押すことで 130 モジュールのファンの回転を制御し、ボタン B を押すことで加湿(atomization)モジュールからの水蒸気噴霧を制御できます。 ![Img](./media/bottom1.png) #### 4.3.9.2 必要な部品 | ![Img](./media/microbitV2.png)| ![Img](./media/ExpansionBoard.png) |![Img](./media/OLED.png)| | :--: | :--: | :--: | | micro:bit V2 ボード ×1 | micro:bit シールド ×1 | OLED ディスプレイ ×1 | |![Img](./media/PM2.5-1.png) |![Img](./media/motor.png)|![Img](./media/steam1.png)| | PM2.5 粉じんセンサー ×1 | モータ ×1 | 蒸気センサー ×1 | |![Img](./media/UV-sensor1.png)|![Img](./media/batterycase.png)| ![Img](./media/AAbattery.png)| | 紫外線センサー ×1 | 電池ホルダー ×1 | AA電池(**別途用意**) ×6 | |![Img](./media/usb.png) |![Img](./media/4pin.png)|![Img](./media/3pin.png)| | micro USB ケーブル ×1 | 4ピンワイヤ ×3 | 3ピンワイヤ ×3 | |![Img](./media/Atomization1.png) | ![Img](./media/fan.png) | | | 加湿モジュール ×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 | ![Img](./media/couj11.png) #### 4.3.9.4 コードフロー ![Img](./media/flow-chart-011.png) #### 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)” 。 ![Img](./media/WPSA1.png) ⚠️ **Tip 2: もしライブラリファイル "XHT11\.py" が既に Micro:bit ボードにインポートされている場合は、Micro:bit 本体のメモリ不足を招き、サンプルコードのダウンロードに失敗することがあるため、Micro:bit 本体から削除する必要があります。** 「Files」ボタンをクリックし、左側のボックスにあるライブラリファイル「XHT11\.py」を右クリックすると「Delete (cannot be undone)」オプションが表示されます。表示された「Delete (cannot be undone)」をクリックすると、ライブラリファイル「XHT11\.py」が削除されます。 ![Img](./media/WPSA3.png) **完全なコード:** ```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) ``` ![Img](./media/line1.png) **簡単な説明:** ① microbit、oled_ssd1306、math、time のライブラリをインポートします。 ```Python from microbit import * from oled_ssd1306 import * import math import time ``` ② 5×5 LED マトリクスに ![Img](./media/ab3.png) を表示します。 ```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 テスト結果 ![Img](./media/4top.png) 配線と micro USB ケーブルでの給電を行い、外部電源(AA×6)を接続して十分な電力供給を確保した後、“Flash” をクリックしてコードを Micro:bit ボードにダウンロードしてください。 ![Img](./media/A133.png) テストコードをアップロードした後、Micro:bit の背面にあるリセットボタンを押してください。 ![Img](./media/A455.png) 内蔵センサー(光センサー、温度センサー、マイク)および外部センサー(PM2.5 粉じんセンサー、蒸気センサー、太陽紫外線センサーなど)の値を読み取り、I2C インターフェースの OLED 表示画面を通じて、光強度、温度、騒音強度、降雨強度(湿潤度)、日光の紫外線強度、PM2.5 粉じん濃度をリアルタイムかつ直感的に表示できます。 Micro:bit 本体のマイクに向かって息を吹きかける(または非常に大きな音を発する)と(⚠️ **特別リマインダー: 息を吹きかける方がより顕著な効果があります**)、OLED 表示にその風量(または音量)が表示されます。 Micro:bit ボードのボタン A を押すとモジュール上のファンが回転し、ボタン B を押すと加湿(atomization)モジュールがミストを噴霧します。 ⚠️ 特別リマインダー: 外部電源の電圧が不十分な場合があります。その場合は、ファンが回転を開始したり噴霧モジュールが動作を開始したりするまで、Micro:bit のボタンを 2 回押す必要があることがあります。 ![Img](./media/dongtu-9.gif) ⚠️ **注意: 実験で使用しているブロック(building blocks)は本キットに含まれていません。** (**Tip:** 結果が表示されない場合は、Micro:bit ボードのリセットボタンを押してください。) ![Img](./media/4bottom.png)