Arduino Nano 33 IoTで作るポータブルIoT気象ステーション
必要なパーツと用品
| パーツ | 数量 | 備考 |
|---|---|---|
| Arduino Nano 33 IoT | 1 | Wi-Fi/Bluetooth内蔵、3.3V動作 |
| BME280環境センサー(温度・湿度・気圧) | 1 | I2C接続 |
| 0.96インチ OLEDディスプレイ(128×64) | 1 | I2C接続、SSD1306等 |
| プラスチックケース(約10×7cm) | 1 | 透明フロント、RF透過性必要 |
| Micro USBケーブル | 1 | 電源・プログラミング兼用 |
| オス-メス ジャンパーワイヤー | 1式 | |
| USB ACアダプター | 1 | 常時電源用 |
必要な工具
- グルーガン(汎用) ※屋外設置ならエポキシ推奨
使用アプリ・オンラインサービス
- Arduino IDE
- Blynk(IoTダッシュボード、iOS/Androidアプリ)
プロジェクト概要
スマホをIoTデバイスと連携させるアプリはいくつも試しましたが、Blynkほど柔軟でUIが美しく、主要プラットフォーム対応、かつ趣味利用無料なものはありません。このプロジェクトは、Blynkを学ぶための比較的シンプルなIoT気象ステーションです。
ハードウェア
構成はシンプル:Arduino Nano 33 IoT(Wi-Fi担当)、BME280センサーボード(温湿度・気圧一体型)、1インチOLED表示器。すべて3.3V駆動で統一。OLEDは必須ではありませんが、スマホ連携前にローカル表示で動作確認するのに便利です。
配線(I2C):センサーとディスプレイは両方I2Cですが、ライブラリ競合のため別ポートを使用:
- BME280:デフォルトI2C(アナログピンA4=SDA、A5=SCL)
- OLED:セカンダリI2C(デジタルピン4=SCL、5=SDA)※SDA/SCLが逆なので注意
ケースは透明フロントのプラスチック製(Wi-Fi電波透過のため)。センサーは底面の1/2インチ穴から外気に露出させ、内側にホットグルーで固定。電源はMicro USBケーブル1本で、プログラミング時はPC、運用時はUSB ACアダプターに挿すだけ。
ソフトウェア
ライブラリ:
- Adafruit_BME280_Library(センサー)
- ss_oled(OLED表示)
- Blynk(IoT通信)
すべてArduinoライブラリマネージャからインストール可能。各ライブラリのサンプルで個別に動作確認してから統合するのがおすすめ。
Nano 33 IoTでBlynkを使うコツ:BlynkのサンプルはESP8266前提ですが、Nano 33 IoTはWiFiNINAライブラリを使用。以下2行で対応:
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
数値をOLED表示用文字列に変換するため<avr/dtostrf.h>が必要。Blynkへは数値のまま送るとグラフ機能が使えるが、文字列で送るとグラフが動かない点に注意(両方送るのが正解)。
気圧の海面補正:標高1000ft(約300m)ごとに約1 inHg(33.9 hPa)加算。コード内では標高1300ftとして+1.3補正。お住まいの標高に合わせて変更してください。
Blynkなしで動作させる場合
コード内のBlynk.begin()をコメントアウトすれば、OLED単体で気象ステーションとして動作します(コメントアウトしないとBlynk接続待ちで停止します)。
Blynkセットアップとダッシュボード構築
- Blynkアプリインストール・アカウント作成
- 新規プロジェクト作成 → 認証トークン取得
- まず「Blynk Blink」サンプル(examples.blynk.cc)でオンボードLED(ピン13)をスマホからON/OFFし、接続確認
- Nano 33 IoT用に
WiFiNINA.h/BlynkSimpleWiFiNINA.hへ書き換え、Wi-Fi認証情報とトークンを設定 - シリアルモニタでBlynkクラウド接続ログを確認
スマホ側ウィジェット配置:
- 「Labeled Value」×3:
- 温度:Virtual Pin V3、ラベル「Temp /pin.#/ deg.F」、緑、大文字
- 湿度:Virtual Pin V4、ラベル「Humid /pin.#/ %」、金、大文字
- 気圧:Virtual Pin V5、ラベル「Press /pin.##/ in Hg」、赤、大文字
- 「SuperChart」:全画面幅、X軸表示ON、解像度:live/1hr/6hr/1day/1wk/1mo/3mo
- データストリーム3つ:V3(温度、Y軸67-100、緑)、V4(湿度、Y軸34-66、金)、V5(気圧、Y軸0-33、赤)
- Y軸表示ON
編集モード終了でダッシュボード完成。グラフは少し待ってから表示されます。live/1hr解像度ならすぐ見えます。
共有機能:プロジェクト設定→Sharing ON→QRコード生成。相手はBlynkアプリ未登録でもQR読み取りで閲覧可能。複数端末で同じ気象データを監視できます。
Blynkは「エナジー」ポイント制(初期2500pt無料)。このプロジェクトは無料枠内。共有や拡張で足りなくなったら課金($6で5000pt等)も検討を。
コード
Tiny Internet Weather Station
/* Arduino Nano 33 IoT用
BME280センサー、0.96" 128x64 OLED、WiFi経由でBlynkクラウドへ送信 */
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BME280.h>
#include <avr/dtostrf.h> // 数値→文字列変換用
#include <ss_oled.h> // OLEDライブラリ
// Nano 33 IoTでBlynkを使うための2行
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
char auth[] = "YourBlynkProjectCode";
char ssid[] = "YourWifiID";
char pass[] = "YourWiFiPassword";
Adafruit_BME280 bme;
Adafruit_Sensor *bme_temp = bme.getTemperatureSensor();
Adafruit_Sensor *bme_pressure = bme.getPressureSensor();
Adafruit_Sensor *bme_humidity = bme.getHumiditySensor();
#define SDA_PIN 5
#define SCL_PIN 4
#define RESET_PIN -1
#define OLED_ADDR -1
#define FLIP180 0
#define INVERT 0
#define USE_HW_I2C 0
#define MY_OLED OLED_128x64
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
SSOLED ssoled;
BlynkTimer timer;
void setup() {
if (!bme.begin(0x76)) {
while (1) delay(10); // センサー検出まで待機
}
bme_temp->printSensorDetails();
bme_pressure->printSensorDetails();
bme_humidity->printSensorDetails();
oledInit(&ssoled, MY_OLED, OLED_ADDR, FLIP180, INVERT, USE_HW_I2C, SDA_PIN, SCL_PIN, RESET_PIN, 400000L);
oledFill(&ssoled, 0x0, 1);
Blynk.begin(auth, ssid, pass); // Blynkなしならこの行をコメントアウト
timer.setInterval(60000L, myupdate); // 1分ごとに更新
myupdate(); // 初回即時実行
}
void loop() {
Blynk.run();
timer.run();
}
void myupdate() {
sensors_event_t temp_event, pressure_event, humidity_event;
bme_temp->getEvent(&temp_event);
bme_pressure->getEvent(&pressure_event);
bme_humidity->getEvent(&humidity_event);
float ctemp = temp_event.temperature;
float ftemp = 32 + (9 * ctemp) / 5; // 華氏変換
float hum = humidity_event.relative_humidity;
float ppress = pressure_event.pressure; // hPa
float mpress = 1.3 + ppress / 33.8939; // inHg + 海面補正(標高に合わせて調整)
char mytemp[8], myhum[8], mypress[8];
dtostrf(ftemp, 6, 2, mytemp);
dtostrf(hum, 6, 2, myhum);
dtostrf(mpress, 6, 2, mypress);
// OLED表示更新
oledWriteString(&ssoled, 0, 2, 1, (char *)"Weather Station", FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 2, 3, (char *)"Temp = ", FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 50, 3, (char *)mytemp, FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 105, 3, (char *)"F", FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 2, 5, (char *)"Humid=", FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 50, 5, (char *)myhum, FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 105, 5, (char *)"%", FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 2, 7, (char *)"Press=", FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 50, 7, (char *)mypress, FONT_NORMAL, 0, 1);
oledWriteString(&ssoled, 0, 105, 7, (char *)"in", FONT_NORMAL, 0, 1);
// Blynkへプッシュ(Virtual Pins)
Blynk.virtualWrite(V3, ftemp);
Blynk.virtualWrite(V4, hum);
Blynk.virtualWrite(V5, mpress);
}
回路図
記事内の配線写真およびFritzing図参照。BME280はA4/A5、OLEDはD4/D5(SCL/SDA逆)に接続。
製造プロセス
- 集積回路(IC):現代エレクトロニクスを支える微小強力チップ
- Raspberry Pi搭載DIYソーラー駆動気象ステーション
- Raspberry Pi 2とADS-WS1で屋外気象観測ステーションを構築
- Raspberry Piで気象観測ステーションを構築し、日次天気データをメール送信
- 気象観測ステーションをCWOPと統合:実践ガイド
- 高度気象ステーション v2.0:温度・気圧・湿度・高度のリアルタイム監視
- Arduinoで作る模型鉄道DCCコマンドステーション 〜Bluetooth制御・無料アプリ付き〜
- Arduino制御の6連ショット・ドリンクミキシングステーション – 自作カクテル自動製造機
- MotionSense: ArduinoとESP8266で作るスマート侵入検知システム
- 高性能 Arduino 気象観測気球データロガーの製作ガイド
- ArduFarmBot Part 2:リモートIoT制御ステーションの構築