0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

環境系のセンサーを複数持っているのに、使っていないからそれを活用するために有機ELを使った環境モニターを作ります。

使用部品

部品 用途
Raspberry Pi Pico W メイン制御
SSD1306 OLED (128x64) 表示
DHT11 温湿度測定
ADC入力 アナログ電圧測定
タクトスイッチ×3 操作
ADC入力に付けたセンサー
ADC入力につないだセンサー
ガスセンサー
明るさセンサー

機能

  • Wi-Fi接続
  • NTPによる時刻同期
  • デジタル時計表示
  • DHT11温湿度表示
  • アナログ入力3ch表示
  • リアルタイムグラフ表示
  • ボタン操作メニュー
  • 自動スリープ・復帰

ライブラリ

import time
import machine
import ssd1306
import dht
import network
import ntptime

使用している主なライブラリです。

  • ssd1306

    • OLED制御
  • dht

    • DHT11センサー制御
  • network

    • Wi-Fi接続
  • ntptime

    • NTP時刻取得

Wi-Fi接続処理

接続リトライ

def wifi_connect():

Wi-Fi接続は起動時に行います。

ただし、組み込み機器では電波状況によって失敗することがあります。

そのため、

  • 20回接続確認
  • 失敗したら再試行
  • 最大3回

という仕組みにしています。

OLEDにも状態表示します。

例:

TRY 1

BOOT 10/20

BOOT OK

起動中でも現在状態が分かります。

NTPによる時計合わせ

def ntp_sync():
    ntptime.settime()

PicoにはRTCがありますが、電源OFFで時刻が消えます。

そこでネットワーク上のNTPサーバーから現在時刻を取得します。

日本時間へは、

JST = 9 * 3600

として9時間追加しています。

OLED初期化

i2c = machine.I2C(
    0,
    sda=Pin(0),
    scl=Pin(1)
)

I2C接続でOLEDを制御しています。

解像度は、

SSD1306_I2C(128,64,i2c)

なので128×64ドットです。

センサー処理

DHT11

sensor = dht.DHT11(Pin(16))

GPIO16にDHT11を接続。

読み取りは、

sensor.measure()

t_now = sensor.temperature()
h_now = sensor.humidity()

で取得できます。

ADC入力

PicoのADCは16bit値で返ります。

raw = adc.read_u16()

そのため、

voltage = raw * 3.3 / 65535

で電圧へ変換しています。

今回は、

ADC26
ADC27
ADC28

の3チャンネルを使用しています。

ボタン処理

使用しているボタン:

ボタン 役割
UP 上移動
DOWN 下移動
OK 決定

プルアップ入力なので、

押していない

1

押す

0

になります。

長押し処理

OKボタンを1.5秒押すと、

sleep_request=True

になります。

画面に、

SLEEP

を表示してスリープします。

モード管理

画面状態は変数で管理しています。

MODE_CLOCK = 0
MODE_MENU  = 1
MODE_TEMP  = 2
MODE_HUM   = 3

現在モード:

mode = MODE_CLOCK

例えば、

時計
 ↓ OK
メニュー
 ↓ OK
温度グラフ

という状態遷移になります。

メニュー表示

メニュー配列:

menu=[
"CLOCK",
"TEMP",
"HUM",
"analog1",
"analog2",
"analog3"
]

画面に表示できる行数は、

MENU_VISIBLE = 4

なのでスクロール表示しています。

カーソルは、

>

で表示します。

温湿度グラフ

取得した値を配列へ保存します。

temps.append(t_now)
hums.append(h_now)

最大110点まで保持。

MAX_POINTS = 110

古いデータは削除します。

グラフ変換

OLEDは座標なので、

値 → Y座標

へ変換します。

value_to_y()

例えば、

温度

20℃
|
|
30℃

を画面上の

0~63pixel

へ変換します。

自動スリープ

最後の操作時間を保存しています。

last_action

5分経過すると、

mode = MODE_SLEEP

になります。

消費電力削減のためです。

復帰処理

スリープ中にOKボタンを押すと、

wake()

を実行。

内容:

  • OLED復帰
  • Wi-Fi再接続
  • NTP同期

を行います。

メインループ

中心部分です。

while True:

    button()

    sensor()

    display()

実際にはタイマー管理して、

  • センサー → 2秒周期
  • 時計 → 1秒周期
  • グラフ → 2秒周期

で更新しています。

工夫したポイント

1. delayを使いすぎない

組み込みでは、

time.sleep()

を大量に使うと操作不能になります。

そのため、

time.ticks_ms()

で時間管理しています。

2. OLEDを無駄に更新しない

毎回描画すると、

  • 遅い
  • 消費電力増加

になります。

必要な時だけ、

oled.show()

しています。

3. グラフの自動スケール

温度や湿度が変化すると、

T_MIN
T_MAX

を変更して表示範囲を調整します。

まとめ

次は外部から環境モニターの情報を習得できるようにしたい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?