MENU

ArduinoとPython、センサーデータ連携の壁を越える

「まただ…また動かない…」

深夜2時。モニターに映し出されたエラーメッセージを前に、僕はPCのキーボードを打つ手を止めた。部屋の片隅に置かれたArduinoには、温度センサーが寂しそうにぶら下がっている。数時間前まで、「これでリビングの温度をリアルタイムでモニタリングできるぞ!」と意気揚々としていた熱意は、冷え切った部屋の空気のように、すっかり萎んでしまっていた。

あれは、僕がIoTの世界に足を踏み入れたばかりの頃の話だ。当時、僕はプログラミング経験はそこそこあったものの、ハードウェアとの連携はまるで素人だった。Arduinoでセンサーデータを読み取るのは簡単だった。でも、そのデータをPythonで受け取り、グラフ化したり、もっと複雑な処理をさせたいと思った瞬間、目の前に分厚い壁が立ちはだかったんだ。

ネット上には「ArduinoとPythonでシリアル通信!」といった記事がたくさんあった。僕はそれらを片っ端から読み漁り、コードをコピペしては実行した。しかし、結果はいつも同じ。Pythonスクリプトはエラーを吐き出し、Arduinoからのデータは一向に届かない。ポートが開けない、ボーレートが合わない、バイト列と文字列の変換で文字化け…。「なぜ、みんなはこんなに簡単にやっているように見えるのに、僕だけがこんなにもつまづくんだ?」

焦燥感が募る。時間だけが過ぎていく。家族が寝静まったリビングで、一人、モニターの光を浴びながら、僕は何度も心の中で叫んだ。「もうダメかもしれない…このままじゃ、僕のIoTの夢は、ただの夢で終わってしまうのか…?」

そんな絶望の淵にいた僕を救ってくれたのは、プログラミングスクールで講師をしている友人だった。彼に現状を話すと、彼は静かに言った。「お前は、ArduinoとPythonが『会話』するための準備をしていないだけだよ」。

「会話?」僕は聞き返した。

「そう。シリアル通信は、例えるなら海外旅行での言葉の壁だ。お互いが違う言語を話しているのに、いきなり複雑な話をしようとしても無理だろう?まずは、お互いが理解できる共通の言葉(データ形式)と、話す速度(ボーレート)を合わせることから始めるんだ。」

友人の言葉は、僕の頭の中でバラバラだった知識の断片を、一本の線で繋いでくれた。僕はハッとさせられた。そうだ、僕はただ闇雲にコードをコピペしていただけで、その裏にある「対話のルール」を全く理解していなかったのだ。

そこから僕は、シリアル通信の基礎を徹底的に学び直した。ArduinoのSerial.begin()で設定するボーレートの意味。Pythonのpyserialライブラリでポートを開く手順。そして最も重要だったのは、Arduinoから送られてくる「バイト列」のデータを、Pythonで「意味のある文字列」や「数値」に変換する方法だった。

1. Arduino側の準備:データの「話し方」を決める

まずはArduinoスケッチで、シンプルにセンサーデータをシリアルポートへ出力する。ポイントは、データを読みやすく、Python側でパースしやすい形式にすることだ。例えば、Serial.println("Temp:25.5");のように、識別子と値をセットで送る。そして、Serial.begin(9600);でボーレート(通信速度)を設定する。この「9600」が、Pythonとの共通言語の速度になる。

“`cpp

void setup() {

Serial.begin(9600); // Pythonとボーレートを合わせる

}

void loop() {

float temperature = 25.5; // 仮のセンサーデータ

Serial.print(“Temp:”);

Serial.println(temperature); // 「Temp:25.5」のように送信

delay(1000);

}

“`

2. Python側の準備:データの「聞き方」を学ぶ

次に、Pythonでpyserialライブラリをインストールする。これは、Arduinoが話す言葉を聞き取るための「翻訳機」のようなものだ。

“`bash

pip install pyserial

“`

そして、Pythonスクリプトでシリアルポートを開き、データを読み取る。最も重要なのは、Arduinoと同じボーレートを設定すること、そして、どのポートにArduinoが接続されているかを正確に指定することだ。WindowsならCOMx、macOSやLinuxなら/dev/tty.usbmodemXXXXのような形式になる。

“`python

import serial

import time

ser = serial.Serial(‘COM3’, 9600, timeout=1) # 環境に合わせてポート名とボーレートを設定

print(f”Connected to {ser.name}”)

try:

while True:

if ser.in_waiting > 0:

line = ser.readline().decode(‘utf-8’).strip() # バイト列を文字列に変換し、改行を除去

print(f”Received: {line}”)

ここでデータパースや処理を行う

if line.startswith(“Temp:”):

try:

temp_str = line.split(“:”)[1]

temperature = float(temp_str)

print(f”Temperature: {temperature}°C”)

except (ValueError, IndexError) as e:

print(f”Error parsing temperature: {e}”)

time.sleep(0.1)

except KeyboardInterrupt:

print(“Exiting…”)

finally:

ser.close() # 忘れずにポートを閉じる

print(“Serial port closed.”)

“`

このコードを実行した瞬間、モニターに次々と表示される「Received: Temp:25.5」。僕は思わず声を上げた。「動いた!本当に動いたんだ!」

あの時の感動は忘れられない。まるで、遠く離れた異国の友人と、初めて言葉が通じ合ったかのような感覚だった。センサーデータがただの数字の羅列ではなく、意味を持った「情報」として、僕のPythonスクリプトの中を駆け巡る。それは、僕のアイデアが形になる瞬間の、確かな手応えだった。

シリアル通信は、決して難しい技術じゃない。大切なのは、ArduinoとPythonがお互いに「何を、どう伝えたいか」を理解し、そのための「共通のルール」を設定することだ。一度この基礎を理解すれば、あなたのIoTプロジェクトは、まるで魔法にかかったかのように動き出すだろう。

もう、あの時の僕のように、エラーメッセージと孤独に戦う必要はない。センサーデータは、あなたの手の中で、無限の可能性を解き放つ準備ができている。さあ、あなたも「会話」の第一歩を踏み出してみないか?このシンプルな一歩が、あなたの未来を大きく変えるきっかけになるはずだ。