MicroCat.1でIoT温度監視システムを構築してみた

1. はじめに
今回は、MicroCat.1というRaspberry Pi Pico 2互換のIoTボードを使って、モバイルネットワーク経由で温度データをクラウドに送信するシステムを構築する実験を行いました。センサーからデータを取得し、LTE回線を使って通常のレンタルサーバーに送信するまでの一連の流れを実装し、実際に動作させることができました。
2. 実験の目的
- MicroCat.1の機能を理解する
- I2Cセンサー(ADT7410)との通信を実装する
- SIM7672モデムを使ったモバイルネットワーク接続を確立する
- 1NCEのIoT SIMカードを使ってデータを送信する
- エラーハンドリングと再接続機能を実装する
3. 使用したハードウェア
3.1. MicroCat.1
- CPU: Raspberry Pi Pico 2互換(RP2040)
- 通信: SIM7672モデム内蔵(LTE通信対応)
- 開発環境: MicroPython
- GPIO: I2C0バス(GPIO4: SDA, GPIO5: SCL)
3.2. ADT7410 温度センサー
- 精度: ±0.5℃(-10℃~+85℃)
- 分解能: 0.0078℃(16ビットモード)
- 測定範囲: -55℃~+150℃
- インターフェース: I2C(アドレス: 0x48)
- 動作電圧: 2.7V~5.5V
4. システム構成
flowchart TD
A[ADT7410温度センサー] -->|I2C通信| B[MicroCat.1<br/>RP2040]
B -->|SIM7672モデム| C[1NCE LTEネットワーク]
C -->|HTTP POST| D[Webサーバー<br/>PHP]
D -->|ログ保存| E[temp_log.txt]
style A fill:#e1f5ff
style B fill:#fff4e1
style C fill:#e8f5e9
style D fill:#f3e5f5
style E fill:#fce4ec
注意: 本実験では、1NCEのLTEネットワークを使用して通常のレンタルサーバー(PHPが動作するWebサーバー)にデータを送信しています。1NCEの専用サーバーやサービスは使用していません。
5. 実装の詳細
5.1. I2Cセンサーとの通信
ADT7410はI2Cインターフェースで通信します。MicroPythonのmachine.I2Cモジュールを使用して実装しました。
from machine import I2C, Pin
# I2Cバスの初期化
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
# ADT7410の初期化
sensor = ADT7410(i2c, address=0x48)
# 温度読み取り
temperature = sensor.read_temperature()
ポイント:
- ADT7410の初期化には最大240msの待機時間が必要
- 16ビットモードに設定することで高精度な測定が可能
5.2. ADT7410ドライバーの実装
ADT7410のレジスタを直接操作するドライバークラスを実装しました。
class ADT7410:
def __init__(self, i2c, address=0x48):
self.i2c = i2c
self.address = address
# デバイスの存在確認
if address not in i2c.scan():
raise ValueError(f"ADT7410が見つかりません")
# 16ビットモードに設定
self.set_config(ADT7410_CONFIG_16BIT)
time.sleep_ms(250) # 初期化待機
def read_temperature(self):
"""温度を摂氏で読み取る"""
raw_value = self.read_temperature_raw()
# 16ビットモード: 分解能0.0078℃
temperature = raw_value / 128.0
return temperature
実装のポイント:
- デバイスの存在確認を初期化時に実施
- 16ビット符号付き整数として読み取り、符号拡張を適切に処理
- エラーハンドリングを各メソッドに実装
5.3. モバイルネットワーク接続
SIM7672モデムを使って1NCEネットワークに接続します。
import SIM7672
def init_modem():
"""モデムを起動し、1NCEネットワークに接続する"""
# モデムオブジェクトの作成
m = SIM7672.modem()
# モデムをアクティブ化
m.active(True)
time.sleep(10) # モデムの起動待機
# 1NCEネットワークに接続
result = m.connect(
apn="iot.1nce.net",
user='', # ユーザー名は不要(空欄)
key='', # パスワードは不要(空欄)
pdp='IP', # IPv4のみサポート
security=1 # PAP認証方式(ユーザー名/パスワードは不要)
)
# 接続確認(リトライロジック付き)
retry = 0
max_retries = 30
while retry < max_retries:
if m.isconnected() and m.ifconfig()[0] != '0.0.0.0':
print(f"接続成功! IP: {m.ifconfig()[0]}")
return m
retry += 1
time.sleep(2)
raise RuntimeError("ネットワーク接続に失敗しました")
接続パラメータの説明:
- APN:
iot.1nce.net- 1NCEのIoT専用APN(必須設定) - PDP:
IP- IPv4プロトコルを使用(1NCEはIPv4のみサポート) - Security:
1- PAP(Password Authentication Protocol)認証方式 - Username/Password: 空欄 - 1NCEは認証方式としてPAPを指定するが、ユーザー名/パスワードは不要
参考: 1NCE APN Setup Documentation
実装のポイント:
- モデムの起動には10秒の待機時間を設けた
- 接続確立まで最大60秒(2秒×30回)リトライ
- IPアドレスが
0.0.0.0でないことを確認して接続成功を判定
5.4. HTTP通信の実装
MicroPythonのrequestsライブラリを使用してHTTP POSTリクエストを送信します。
import requests
def send_data_to_server(temperature, modem=None):
"""サーバーへ温度データをPOST送信する"""
payload = {
"device_id": DEVICE_ID,
"temperature": temperature,
"unit": "Celsius"
}
try:
response = requests.post(
SERVER_URL,
json=payload,
timeout=30 # モバイル回線の遅延を考慮
)
print(f"送信完了。ステータスコード: {response.status_code}")
response.close() # メモリ解放
return True
except Exception as e:
print(f"送信エラー: {e}")
return False
実装のポイント:
- タイムアウトを30秒に設定(モバイル回線の遅延を考慮)
- レスポンスは必ず
close()してメモリを解放 - エラー時は再接続を試みる仕組みを実装
5.5. 再接続機能の実装
ネットワーク接続が切断された場合に自動的に再接続する機能を実装しました。
while True:
try:
# 接続状態を確認
is_connected = modem.isconnected()
ip_info = modem.ifconfig()
if not is_connected or ip_info[0] == '0.0.0.0':
print("警告: ネットワーク接続が切断されました。再接続を試みます...")
try:
modem.active(False)
time.sleep(2)
modem = init_modem()
print("再接続成功")
except Exception as e:
print(f"再接続失敗: {e}")
time.sleep(10)
continue
# 温度読み取りと送信
temp_c = sensor.read_temperature()
send_data_to_server(temp_c, modem)
time.sleep(60) # 1分待機
except KeyboardInterrupt:
break
except Exception as e:
print(f"ループ内エラー: {e}")
time.sleep(10)
実装のポイント:
- メインループで定期的に接続状態を確認
- 切断検出時はモデムを一度無効化してから再接続
- エラー時は10秒待機してから再試行
6. サーバー側の実装
本実験では、通常のレンタルサーバー上でPHPでシンプルな受信スクリプトを実装しました。
<?php
// receive_temp.php
$json_data = file_get_contents('php://input');
$data = json_decode($json_data, true);
if ($data) {
// ログファイルに保存
$log = date("Y-m-d H:i:s") . " - Temp: " . $data['temperature'] . "C\n";
file_put_contents("temp_log.txt", $log, FILE_APPEND);
echo "Success";
} else {
http_response_code(400);
echo "Invalid Data";
}
?>
実装のポイント:
- JSON形式でデータを受信
- タイムスタンプ付きでログファイルに保存
- エラー時は適切なHTTPステータスコードを返す
注意: 本実験では通常のレンタルサーバーを使用しています。1NCEの専用サーバーやサービスは使用していません。
2025-12-22 16:42:04 - Temp: 17.429688C
2025-12-22 16:43:06 - Temp: 17.492188C
2025-12-22 16:44:09 - Temp: 17.492188C
2025-12-22 16:45:12 - Temp: 17.507812C
2025-12-22 16:46:15 - Temp: 17.53125C
2025-12-22 16:47:18 - Temp: 17.414062C
temp_log.txtに記録された温度のログ
7. 設定ファイルの管理
機密情報を含む設定はconfig.pyとして管理し、.gitignoreに追加してリポジトリにコミットしないようにしました。
# config.py
SERVER_URL = "http://your-server.com/path/to/receive_temp.php"
DEVICE_ID = "MicroCat_01"
8. 実験結果
- 温度測定: ADT7410から正確に温度データを取得できた
- ネットワーク接続: 1NCEネットワークへの接続に成功(IPアドレス取得確認)
- データ送信: HTTP POSTでサーバーへの送信に成功
9. まとめ
MicroCat.1とADT7410温度センサー、SIM7672モデムを使って、モバイルネットワーク経由で温度データをクラウドに送信するシステムを構築しました。I2C通信、モバイルネットワーク接続、HTTP通信など、IoTシステムに必要な要素を一通り実装できました。
10. サンプル
11. 参考資料
12. FAQ
- MicroCat.1は、通常のRaspberry Pi Picoと何が違うのですか?
- MicroCat.1はRaspberry Pi Pico 2(RP2040/RP2350)と互換性を持ちつつ、SIM7672モデムを標準搭載している点が最大の違いです。これにより、Wi-Fi環境がない場所でもLTE回線を通じたモバイルデータ通信が単体で可能になっています。
- なぜADT7410の初期化に250msもの待機時間を設けているのですか?
- ADT7410のデータシートによると、電源投入後や設定変更後に動作が安定し、正確な温度データを取得できるようになるまで最大240msの時間を要するためです。この待機を入れないと、初期化直後のデータ読み取りでエラーが発生したり、不正確な値が返ってくる可能性があります。
- 温度データの精度を上げるために設定している「16ビットモード」とは何ですか?
- ADT7410はデフォルトでは13ビット分解能(0.0625℃単位)ですが、レジスタ設定を変更することで16ビット分解能(0.0078125℃単位)で計測できるようになります。より微細な温度変化を捉えたい場合に有効な設定です。
- 1NCEのSIMカードを使用する際、ユーザー名やパスワードが空欄なのはなぜですか?
- 1NCEの仕様上、接続にはPAP認証を指定する必要がありますが、認証に使用する具体的なIDやパスワードは個別に設定されていないためです。APN(
iot.1nce.net)が正しく設定されていれば、空欄のままでもネットワーク側で認証が行われます。 - PDPタイプを「IP」に設定している理由を教えてください。
- 1NCEのネットワークがIPv4のみをサポートしているためです。
IPV4V6などを選択すると、モデムやネットワークの仕様によって接続に失敗したり、接続確立まで時間がかかったりすることがあるため、明示的にIP(IPv4)を指定しています。 - 1NCEのSIM以外(他社の格安SIMなど)でもこの構成は動作しますか?
- はい、基本的には動作します。ただし、そのSIMのキャリアが使用しているバンドをSIM7672モデムがサポートしていること、およびそのSIM専用のAPN設定、認証方式(PAP/CHAP)、ユーザー名/パスワードを適切に設定し直す必要があります。
