Easy-IoTシステム構築
この記事では、(できるだけ)お手軽にIoTシステムを構築してみます。
以下、自分の環境で試す場合には、自己責任でお願いします。
また、GoogleのAIモード(Gemini)の回答が異なる場合もあります。
ご留意ください。
- やってみること
- (できるだけ)お手軽に
- はんだ付け→なし
- サーバの準備(構築)→なし
- コーディング→できるだけ自分では書かない(GoogleのAIモードに聞いてみる)
- IoTシステム
- 温度センサから読み取った値をロギングするシステム
- (できるだけ)お手軽に
システム構成
構成図
使用ハードウェア
- Raspberry Pi Pico 2 WH
- 温度センサ(DS18B20)
-
Amazon | DROK 防水 高精度 DS18B20 温度センサー プローブ 5本セット アダプターボード & 4.7K抵抗器 & ジャンパワイヤ(5セット)付き
- 1-Wire(ワンワイヤ)インターフェース
- マイコンのデジタルピン1本だけでデータの送受信が可能
- センサ1つ1つに固有のアドレスが割り振られているため、同じ1本の信号線に複数のDS18B20を並列に接続して個別に温度を取得することが可能
- 防水仕様
- センサ部がステンレス製の管に収められ、長いケーブルと一体化して防水処理されている
- 水槽の水温測定や、屋外・配管内の温度測定によく利用される
- 測定温度範囲: -55[℃] ~ +125[℃] (ケーブル耐熱目安: ~85[℃])
- 精度: ±0.5[℃] (-10[℃] ~ +85[℃] 範囲内)
- 1-Wire(ワンワイヤ)インターフェース
-
Amazon | DROK 防水 高精度 DS18B20 温度センサー プローブ 5本セット アダプターボード & 4.7K抵抗器 & ジャンパワイヤ(5セット)付き
- マイクロUSBケーブル(Type-A ⇔ Micro USB)
使用AI
- Google検索のAIモード
- Google検索の検索バー横にあるAIモードをクリックする
温度センサのセットアップ
1. 温度センサをRaspberry Pi Pico 2 WHに接続します
センサ(防水プローブ)から、3本(3色)のケーブルが伸びています。それぞれの色によって、機能が分かるようになっています。
| 色 | 機能 |
|---|---|
| 黄 | DAT(データ) |
| 赤 | VDD(電源) |
| 黒 | GND(グランド) |
また、DS18B20は安定した通信・計測をおこなうためにプルアップ抵抗を電源とマイコンのピンの接続の間にいれることが必要です。
今回使用するアダプタボート上には、4.7[kΩ]のプルアップ抵抗が既に内蔵されています。
アダプターボードを使わない場合は、忘れずにプルアップ抵抗を回路に組み込みましょう。
ジャンパワイヤの接続
アダプターボードにジャンパワイヤを接続します。
配線時のミスを防止するためにも、色に気をつけて接続しましょう。
赤系統 → 電源
黒系統 → GND
それ以外の色 → DAT
Raspberry Pi Pico 2 WHと接続
ジャンパワイヤを使って、Raspberry Pi Pico 2 WHと接続します。
接続には、GPIOピンを使用します。
GPIOピン:Pico 2 WHの基板の外周には合計40本のピンが並んでおり、そのうち26個の汎用GPIOピン(GP0〜GP22およびGP26〜GP28)がセンサやLEDなどの接続に利用できます。
Pico 2 WHのピン配置(ピンアウト)を示します。

Raspberry Pi Pico 2 Datasheet: An RP2350-based microcontroller board. [P.4]
↑ 画像をクリックすると拡大します。
ピン配置をよく確認しながら、以下のように接続してください。
| 色 | 機能 | GPIO |
|---|---|---|
| 黄 | DAT(データ) | 34番ピン(GP28) 右の上から7番目 |
| 赤 | VDD(電源) | 36番ピン(3V3(OUT)) 右の上から5番目 |
| 黒 | GND(グランド) | 33番ピン(GND) 右の上から8番目 |
1. PCにThonny(開発環境)をインストールしてください。
2. Raspberry Pi Pico 2 WHにMicroPython用のファームウェアをインストールしてください
温度センサの動作確認
プログラミング言語:MicroPython
AI(Google検索のAIモード)を利用して、プログラムを開発していきます。
まず、デバイスの動作チェックを行うために、以下の検索文で、温度を取得して表示するプログラムを作ってもらいます。
検索文(温度センサチェック)
[検索文]
次のデバイスを使って温度を計測するシステムを構築したいと考えています。
Raspberry Pi Pico 2 W
温度センサ(DS18B20)
言語はMicroPythonです。
温度センサのDATは34番ピン(GP28)に接続します。
温度を取得して表示するMicroPythonプログラムを作成してください。
検索結果(温度センサチェック)
まったく同じ質問をしても、毎回違う答えになる場合があります。これはAIの仕組みによる正常な挙動ではありますが、注意が必要です。
次のコードと補足などが提案されました。
Raspberry Pi Pico 2 WとDS18B20センサを使用し、MicroPythonで温度を計測して表示するプログラムは以下の通りです。
必要な配線
プログラムを動かす前に、ピンの接続が正しく行われているか確認してください。
DS18B20のデータ(DAT)ピンと3.3V電源ピンの間には、4.7 kΩ程度のプルアップ抵抗を挟む必要があります。
- VCC (電源) → Pico 2 W の 3.3V (36番ピン)
- GND (地気) → Pico 2 W の GND (38番ピンなど)
- DAT (データ) → Pico 2 W の GP28 (34番ピン)
- 抵抗 → VCC と DAT の間に接続
MicroPythonサンプルプログラム
MicroPythonには標準で onewire と ds18x20 ライブラリが組み込まれているため、追加のライブラリインストールは不要です。pythonimport machine[micropyhon] import onewire import ds18x20 import time # 1. 接続ピン(GP28)の設定 dat_pin = machine.Pin(28) # 2. OneWireバスとDS18B20センサの初期化 ow = onewire.OneWire(dat_pin) ds = ds18x20.DS18X20(ow) # 3. バス上のDS18B20デバイスをスキャン roms = ds.scan() print("見つかったデバイスのROMコード:", roms) # デバイスが見つからない場合の処理 if not roms: print("DS18B20センサが見つかりません。配線を確認してください。") # 4. 定期的に温度を取得して表示するメインループ while True: if roms: try: # 温度変換を指示 ds.convert_temp() # 変換完了まで少し待つ(DS18B20の仕様上、最大750ms必要) time.sleep_ms(750) # スキャンされたすべてのセンサから温度を読み取る for rom in roms: temp = ds.read_temp(rom) # 読み取りに失敗すると値が 85.0 になることがあるための簡易チェック if temp == 85.0: print("センサの初期値(85.0℃)が検出されました。再試行します。") else: print(f"現在の温度: {temp:.2f} ℃") except Exception as e: print("温度の取得中にエラーが発生しました:", e) # 2秒ごとに計測 time.sleep(2) コードは注意してご使用ください。プログラムの解説
- ピンの設定: 指定された34番ピン(GP28)を machine.Pin(28) として定義しています。
- スキャン処理: ds.scan() を実行することで、OneWireバスに接続されているDS18B20固有の識別アドレス(ROMコード)を自動で取得します。
- 温度変換 (convert_temp): DS18B20は指示を出してから実際に温度を測定するまでに時間がかかります。そのため、計測命令のあとに time.sleep_ms(750) で待機時間を> 入れています。
- 温度読み出し (read_temp): 取得したROMコードを渡すことで、特定のセンサから正確な温度(摂氏)数値を読み出します。
✅ 動作確認プログラムを実行すると、Thonnyなどの開発環境のコンソール(Shell)に、2秒ごとに現在の温度が 現在の温度: 25.34 ℃ のように表示されます。
さらにシステムを発展させたい場合は、以下のような拡張も可能です。お気軽にご相談ください!
- 取得した温度データをWi-Fi経由でサーバー(AmbientやLINEなど)に送信する
- 温度が一定以上になったらLEDを点灯させたりブザーを鳴らしたりする
- データを一定時間ごとに内蔵フラッシュメモリに保存(ロギング)する
ThonnyやVS Codeでこのプログラムを実行し、シェルやターミナルに以下のような表示が出力されれば、デバイスは正常に動作しています。
では、提案されたコード(test_sensor.py)をThonnyで作成して、実行してみましょう。
import machine
import onewire
import ds18x20
import time
# 1. 接続ピン(GP28)の設定
dat_pin = machine.Pin(28)
# 2. OneWireバスとDS18B20センサの初期化
ow = onewire.OneWire(dat_pin)
ds = ds18x20.DS18X20(ow)
# 3. バス上のDS18B20デバイスをスキャン
roms = ds.scan()
print("見つかったデバイスのROMコード:", roms)
# デバイスが見つからない場合の処理
if not roms:
print("DS18B20センサが見つかりません。配線を確認してください。")
# 4. 定期的に温度を取得して表示するメインループ
while True:
if roms:
try:
# 温度変換を指示
ds.convert_temp()
# 変換完了まで少し待つ(DS18B20の仕様上、最大750ms必要)
time.sleep_ms(750)
# スキャンされたすべてのセンサから温度を読み取る
for rom in roms:
temp = ds.read_temp(rom)
# 読み取りに失敗すると値が 85.0 になることがあるための簡易チェック
if temp == 85.0:
print("センサの初期値(85.0℃)が検出されました。再試行します。")
else:
print(f"現在の温度: {temp:.2f} ℃")
except Exception as e:
print("温度の取得中にエラーが発生しました:", e)
# 2秒ごとに計測
time.sleep(2)
センサからの情報を正しく取得できていれば、下のようにThonnyのコンソールに表示(2秒ごと)されます。
------------------------------
見つかったデバイスのROMコード: [bytearray(b'(f\xca \x00\x00\x00\x80')]
現在の温度: 25.13 ℃
現在の温度: 25.13 ℃
現在の温度: 25.13 ℃
現在の温度: 25.13 ℃
・・・
------------------------------
データ送信
今回のシステムのコンセプトは「お手軽」ですので、サーバの構築やレンタルは行いません。
Raspberry Pi Pico 2 WH(MicroPython)からWi-Fi経由でGoogleスプレッドシートに温度データを書き込みます(Googleスプレッドシートをデータ保管サーバとします)。
ただし、Pico 2 WH単体ではGoogleのOAuth認証を直接扱えないので、Google Apps Script(GAS)を中継サーバとして利用します。
Google Apps Script(GAS)は、Google が提供するクラウド上で動作するスクリプト環境で、JavaScript によく似た言語で Google サービスを自動化・拡張できるツール
これも「お手軽」にAI(Google検索)に聞いてみます。
先ほど、AIモードで検索した続きから検索してください。
こうすることで、センサの情報や接続情報、作成したプログラムなどが共有された状態で、次の検索が行われます。
検索文(データ送信)
[検索文]
Wi-Fi経由で計測したデータをGoogleスプレッドシートに書き込みたいです。
セキュリティ強化のため、以下の項目にしたがってください。
・Wi-Fiの接続情報とGoogleスプレッドシートへのアクセスに必要な情報は別ファイル(json形式)としてください。
・Googleスプレッドシートへのアクセスには、任意のAPIキーを使うようにしてください。
・POSTを使ってください。
検索結果(データ送信)
まったく同じ質問をしても、毎回違う答えになる場合があります。これはAIの仕組みによる正常な挙動ではありますが、注意が必要です。
Googleスプレッドシートへの直接的なデータ書き込み(POST)において、純粋な「APIキー」のみによる認証は、Googleの仕様により読み取り(GET)しか許可されていません。
マイコン(MicroPython)から暗号化キーをハンドリングするサービスアカウント(OAuth2認証)を実装するのは非常に負荷が高いため、セキュリティと簡便性を両立させる標準> 的な手段として、Google Apps Script (GAS) を間に挟む方法を採用します。
GASを「Webアプリ」として公開し、発行されたURLに対して独自のAPIキー(任意の文字列)を付与したPOSTリクエストを送ることで、ご提示いただいた条件を完全に満たすセキュ> リィに配慮したシステムが構築できます。1.接続情報を管理する別ファイル(config.json)
Wi-FiのSSIDや、GASのURL、独自に決めたAPIキーは、メインプログラムとは別に config.json という名前のファイルで保存し、Pico 2 W 内にアップロードしておきます。{ "wifi_ssid": "YOUR_WIFI_SSID", "wifi_password": "YOUR_WIFI_PASSWORD", "gas_url": "https://google.com", "my_api_key": "YOUR_SECRET_API_KEY_HERE" } コードは注意してご使用ください。※ YOUR_SECRET_API_KEY_HERE には、ご自身で決めた任意のパスワード(英数字の文字列)を設定してください。
2.MicroPythonプログラム(main.py)
プログラム起動時に config.json を読み込み、Wi-Fi接続とデータ送信(POST)を行います。[micropython] import machine import onewire import ds18x20 import time import network import urequests import ujson # 1. json設定ファイルの読み込み try: with open("config.json", "r") as f: config = ujson.load(f) except Exception as e: print("config.jsonの読み込みに失敗しました:", e) while True: time.sleep(1) # 2. Wi-Fi接続処理 wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print("Wi-Fiに接続中...", config["wifi_ssid"]) wlan.connect(config["wifi_ssid"], config["wifi_password"]) while not wlan.isconnected(): time.sleep(1) print("Wi-Fi接続成功! IPアドレス:", wlan.ifconfig()[0]) # 3. センサ(GP28)の初期化 dat_pin = machine.Pin(28) ow = onewire.OneWire(dat_pin) ds = ds18x20.DS18X20(ow) roms = ds.scan() # 4. メインループ(10秒ごとにデータをPOST) while True: if roms: try: ds.convert_temp() time.sleep_ms(750) for rom in roms: temp = ds.read_temp(rom) if temp == 85.0: continue print(f"計測温度: {temp:.2f} ℃") # 送信データの作成 payload = { "api_key": config["my_api_key"], "temperature": temp } headers = {"Content-Type": "application/json"} # Google Apps Script へ POST送信 print("データをスプレッドシートへ送信中...") response = urequests.post( config["gas_url"], json=payload, headers=headers ) # 結果の確認 print("ステータスコード:", response.status_code) print("サーバー返答:", response.text) response.close() except Exception as e: print("エラーが発生しました:", e) time.sleep(10) # 10秒ごとに繰り返し コードは注意してご使用ください。3.Google Apps Script(受け手側)の設定
Googleスプレッドシートのメニュー「拡張機能」>「Apps Script」を開き、以下のコードを貼り付けます。
このスクリプト側で、Picoから送られてきたAPIキーの照合を行います。[javascript] function doPost(e) { // 1. 独自に決めたAPIキーを設定(config.jsonに書いたものと同じ文字列にする) const VALID_API_KEY = "YOUR_SECRET_API_KEY_HERE"; try { // 2. 送信されてきたJSONデータを解析 const data = JSON.parse(e.postData.contents); // 3. セキュリティチェック(APIキーの検証) if (!data.api_key || data.api_key !== VALID_API_KEY) { return ContentService.createTextOutput(JSON.stringify({"status": "error", "message": "Unauthorized: Invalid API Key"})) .setMimeType(ContentService.MimeType.JSON); } // 4. スプレッドシートへデータの書き込み const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const timestamp = new Date(); const temperature = data.temperature; // [日時, 温度] の順で行を追加 sheet.appendRow([timestamp, temperature]); return ContentService.createTextOutput(JSON.stringify({"status": "success"})) .setMimeType(ContentService.MimeType.JSON); } catch(error) { return ContentService.createTextOutput(JSON.stringify({"status": "error", "message": error.toString()})) .setMimeType(ContentService.MimeType.JSON); } } コードは注意してご使用ください。💡 GASのデプロイ手順(超重要)
- GASのエディタ右上にある「デプロイ」ボタン >「新しいデプロイ」をクリックします。
- 種類の選択(歯車アイコン)で「ウェブアプリ」を選択します。
- 次のように設定してデプロイします:
- 次のユーザーとして実行: 「自分」
- アクセスできるユーザー: 「全員」(※APIキーで認証するため、受け口は全員にします)
- 発行された「ウェブアプリのURL」をコピーし、Pico 2 W の config.json 内の gas_url に貼り付けます。
これを行うことで、万が一GASのURLが他人に漏洩して不正なPOSTリクエストを送信されても、config.json 内のAPIキーを知らない限りスプレッドシートに書き込まれることはありません。
次のステップとして、GASの具体的な設置手順で不明な点や、送信エラーが発生した際のエラーハンドリング(再試行処理など)についてさらに詳しく解説が必要でしょうか?
実装
それでは、AI(Google検索)からの回答をベースにして、実装(実際にプログラミングを行う)していきましょう。
config.jsonの準備
次の情報(ネットワーク接続や認証情報)を記録したJSONファイルをRaspberry Pi Pico 2 WW上に作成、保存します。
{
"wifi_ssid": "YOUR_WIFI_SSID",
"wifi_password": "YOUR_WIFI_PASSWORD",
"gas_url": "https://google.com",
"my_api_key": "YOUR_SECRET_API_KEY_HERE"
}
-
YOUR_WIFI_SSID:接続したいWi-Fiアクセスポイント(SSID)の名前 -
YOUR_WIFI_PASSWORD:Wi-Fiアクセスポイントのパスワード -
https://google.com:Google Apps Script(GAS)のWebアプリとして公開したURL-
https://script.google.com/macros/s/XXXXX/execのような形式 - Googleスプレッドシートの作成と設定が必要です
- 次の項目で説明します
-
-
YOUR_SECRET_API_KEY_HERE:GAS側で設定した任意の認証キー(秘密鍵)- このapi_keyはGoogleが発行する公式APIキーではありません。PicoW(送信側)とGAS(受信側)で共有する任意の秘密鍵です
- GASを「誰でもPOSTできるWebAPI」として公開するため、不正なアクセスを防ぐためのパスワードのようなものです
- 要件
- 英数字+記号(-:ハイフン、_:アンダースコア)を組み合わせたランダム文字列が望ましい
- 最低16文字以上
- 可能なら32〜64文字程度
- 作成サービス
それぞれの項目は"(ダブルクォーテーション)の中に記載してください。
- YOUR_WIFI_PASSWORD:Wi-Fiアクセスポイントのパスワード
- YOUR_SECRET_KEY_HERE:GAS側で設定した任意の認証キー(秘密鍵)
この2つは絶対に漏えいなどしないよう厳重に取り扱ってください。
誰かに知られると、スプレッドシートなどを勝手に操作されてしまう可能性があります。
Googleスプレッドシート(データ保管サーバ)の準備
Googleドライブで作業します。
Googleアカウントでログインしてから、Googleドライブにアクセスしてください。
Googleスプレッドシートの作成とGASの入力
もともと入力されているコードは削除してかまいません。
削除してから貼りてつけてください。
function doPost(e) {
// 1. 独自に決めたAPIキーを設定(config.jsonに書いたものと同じ文字列にする)
const VALID_API_KEY = "YOUR_SECRET_API_KEY_HERE";
try {
// 2. 送信されてきたJSONデータを解析
const data = JSON.parse(e.postData.contents);
// 3. セキュリティチェック(APIキーの検証)
if (!data.api_key || data.api_key !== VALID_API_KEY) {
return ContentService.createTextOutput(JSON.stringify({"status": "error", "message": "Unauthorized: Invalid API Key"}))
.setMimeType(ContentService.MimeType.JSON);
}
// 4. スプレッドシートへデータの書き込み
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const timestamp = new Date();
const temperature = data.temperature;
// [日時, 温度] の順で行を追加
sheet.appendRow([timestamp, temperature]);
return ContentService.createTextOutput(JSON.stringify({"status": "success"}))
.setMimeType(ContentService.MimeType.JSON);
} catch(error) {
return ContentService.createTextOutput(JSON.stringify({"status": "error", "message": error.toString()}))
.setMimeType(ContentService.MimeType.JSON);
}
}
1行目のAPI_KEYは、Raspberry Pi Picoで設定したものと同じYOUR_SECRET_KEYを入力してください。
デプロイ(Googleスプレッドシート+GASをWebアプリとして公開)
以下の作業はセキュリティ上の脆弱性となる可能性があります。作業を進める場合には、自己責任でお願いします。
[メッセージ]
Google hasn’t verified this app
The app is requesting access to sensitive info in your Google Account. Until the developer (xxxxxxx@gmail.com) verifies this app ※with Google, you shouldn't use it.
[日本語訳]
Googleはこのアプリを認証していません。
このアプリはGoogleアカウントの機密情報へのアクセスを求めています。
開発者(xxxxxxx@gmail.com)がGoogleによる認証を完了するまで※、このアプリを使用しないでください。
- 左下の「Advanced」をクリック
- 「Go to 無題のプロジェクト」をクリック
- スクロールして
- 「Continue」をクリック
- ウェブアプリにあるURLをコピーする(このURLがRaspberry Pi Pico 2 WHで設定するgas_urlとなる)
- 「完了」をクリック
データ送信の準備[Raspberry Pi Pico 2 WH]
config.jsonの確認
GAS[Googleスプレッドシート]とconfig.json[Raspberry Pi Pico 2 WH]の
- my_api_key → "YOUR_SECRET_KEY_HERE"
- gas_url → "https://script.google.com/macros/s/XXXXX/exec"
が一致しているか確認してください。
Micro Pythonプログラムの実行
次のプログラムをThonnyなどで記述し、実行します。
import machine
import onewire
import ds18x20
import time
import network
import urequests
import ujson
# 1. json設定ファイルの読み込み
try:
with open("config.json", "r") as f:
config = ujson.load(f)
except Exception as e:
print("config.jsonの読み込みに失敗しました:", e)
while True: time.sleep(1)
# 2. Wi-Fi接続処理
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print("Wi-Fiに接続中...", config["wifi_ssid"])
wlan.connect(config["wifi_ssid"], config["wifi_password"])
while not wlan.isconnected():
time.sleep(1)
print("Wi-Fi接続成功! IPアドレス:", wlan.ifconfig()[0])
# 3. センサ(GP28)の初期化
dat_pin = machine.Pin(28)
ow = onewire.OneWire(dat_pin)
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
# 4. メインループ(10秒ごとにデータをPOST)
while True:
if roms:
try:
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
temp = ds.read_temp(rom)
if temp == 85.0:
continue
print(f"計測温度: {temp:.2f} ℃")
# 送信データの作成
payload = {
"api_key": config["my_api_key"],
"temperature": temp
}
headers = {"Content-Type": "application/json"}
# Google Apps Script へ POST送信
print("データをスプレッドシートへ送信中...")
response = urequests.post(
config["gas_url"],
json=payload,
headers=headers
)
# 結果の確認
print("ステータスコード:", response.status_code)
print("サーバー返答:", response.text)
response.close()
except Exception as e:
print("エラーが発生しました:", e)
time.sleep(10) # 10秒ごとに繰り返し
プログラムを実行して、以下の結果が表示されれば、取得した温度がGoogleスプレッドシートに入力されています。
Wi-Fiに接続中... IWAKEN-PC12 9493
Wi-Fi接続成功! IPアドレス: 192.168.137.39
計測温度: 24.44 ℃
データをスプレッドシートへ送信中...
ステータスコード: 400
サーバー返答: <!DOCTYPE html>
・・・
計測温度: 24.44 ℃
データをスプレッドシートへ送信中...
ステータスコード: 400
サーバー返答: <!DOCTYPE html>
・・・
Googleスプレッドシートには日時も記録されていますが、これはデータがスプレッドシートに書き込まれた時間です。
データを取得した時間ではないので、注意してください。
センサの値を表示した後、エラーメッセージが表示されます。これは、通信のやり取り(Googleスプレッドシート → Pico 2 WH)において、エラーが発生しているからです(Google Geminiに聞いてみたところ)。
データをロギング(書き込み)する通信(Pico 2 WH → Googleスプレッドシート)は、正常に行われているので、データを記録することに差し支えないかと思いますので、そのままにしておきます。
以上で、温度データを取得して、ロギングするシステムは構築できたかと思います。
DS18B20は、1-wireで複数のセンサをつなげることができるようになっていますので、複数センサからのデータ取得やロギング、データが蓄積されるGoogleスプレッドシートを使ったダッシュボードの作成(Looker Studio)などもGoogleのAI検索を使って、チャレンジしてみてください。
時間ができたら、それらも記事にしたいとは考えています。
作成したら、ここにリンクを貼ろうと思いますので、あまり期待せずに、お待ちください。















