Arduino関連

PythonとArduinoをシリアル通信で連携させる方法【pyserial入門・サンプルコード付き】

「ArduinoとPythonって、なんとなく別々のものって感じがして、一緒に使うイメージが湧かない…」

そんな風に感じている方、実は多いんじゃないでしょうか。

でも安心してください。シリアル通信という仕組みを使えば、PythonとArduinoはびっくりするほど簡単につながります。今回はその基本をゼロから丁寧に解説していきますね 🎉

この記事の対象読者・難易度

Arduino microcontroller
Arduino microcontroller / Photo by Chengxin Zhao via Pexels
  • ✅ Pythonの基本的な書き方がわかる方
  • ✅ Arduinoでスケッチを書いてみたことがある方
  • ✅ PythonとArduinoを連携させてみたい初〜中級者の方

難易度:★★☆☆☆(初〜中級者向け)

シリアル通信ってそもそも何?






まず「シリアル通信」という言葉、なんか難しそうですよね。でもイメージとしてはこんな感じです。

👉 「パソコンとArduinoが、USBケーブルを通してリアルタイムにメッセージをやり取りする仕組み」

たとえば、Arduinoのシリアルモニターを使ったことがある方なら、あの画面に文字が流れてくるアレです。Pythonからあの通信路を使って、データを送ったり受け取ったりできるんですよね。

つまり——

  • Python → Arduino:「LEDを光らせて!」と命令を送る
  • Arduino → Python:「センサーの値は23.5だよ!」とデータを返す

この双方向のやり取りが、シリアル通信で実現できます。

事前準備を確認しておきましょう

Python programming electronics
Python programming electronics / Photo by Nemuel Sereti via Pexels

実際にコードを書く前に、必要なものをチェックしておきましょう 📋

  • ✅ Arduino本体(UnoやNanoなど何でもOK)
  • ✅ USBケーブル(Arduino接続用)
  • ✅ Python 3.x がインストール済み
  • pyserial ライブラリのインストール

pyserialsのインストールはターミナルで以下を実行するだけです。

pip install pyserial

インストールできたか確認したい場合は pip show pyserial で確認できますよ。

STEP 1:Arduinoのスケッチを書く

まずはArduino側の準備です。今回は「Arduinoが1秒ごとにカウントアップした数値をシリアル送信する」シンプルなスケッチを書きます。

// Arduino側スケッチ:1秒ごとに数値を送信する

int counter = 0;  // カウンター変数

void setup() {
  Serial.begin(9600);  // シリアル通信を9600bpsで開始
}

void loop() {
  Serial.println(counter);  // Pythonへ数値を送信
  counter++;                 // カウントアップ
  delay(1000);               // 1秒待機
}

ポイントをまとめるとこんな感じです 👇

  • Serial.begin(9600):通信速度(ボーレート)を指定します。Python側と必ず合わせること!
  • Serial.println():改行付きでデータを送信します。Pythonで受け取りやすくなります

このスケッチをArduinoに書き込んでおきましょう。

STEP 2:PythonでArduinoからデータを受信する

次はPython側です。pyserial を使って、Arduinoが送ってくるデータを受け取ってみましょう。

import serial  # pyserialsライブラリをインポート
import time

# シリアルポートに接続(ポート名はお使いの環境に合わせて変更してください)
# Windows例: 'COM3'、Mac/Linux例: '/dev/ttyUSB0' や '/dev/cu.usbmodem1401'
ser = serial.Serial('/dev/cu.usbmodem1401', 9600, timeout=1)

time.sleep(2)  # Arduinoの起動を待つ(重要!)

print("Arduinoからデータを受信中...")

try:
    while True:
        line = ser.readline()          # 1行分のデータを読み取る
        if line:                        # データが空でなければ処理
            decoded = line.decode('utf-8').strip()  # バイト列を文字列に変換
            print(f"受信: {decoded}")
except KeyboardInterrupt:
    print("受信を停止しました")
    ser.close()  # 終了時は必ずポートを閉じる

ここが重要です ⚠️

  • ポート名は環境によって違います。Windowsなら「デバイスマネージャー」、Mac/Linuxなら ls /dev/tty* で確認できます
  • ボーレートはArduinoと必ず一致させること(今回は9600)
  • time.sleep(2) はArduinoのリセット後の起動待ちです。これを省略すると最初のデータが化けることがあります
  • readline() の戻り値はバイト列なので、decode('utf-8') で文字列に変換するのを忘れずに!

STEP 3:PythonからArduinoへデータを送信する

今度は逆方向です。PythonからArduinoへ命令を送って、LEDをON/OFF制御してみましょう 💡

まずArduinoのスケッチを更新します。

// Arduino側:Pythonから'1'を受信したらLED ON、'0'でOFF

const int LED_PIN = 13;  // 内蔵LEDのピン番号

void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);  // LEDピンを出力モードに設定
}

void loop() {
  if (Serial.available() > 0) {      // 受信データがあれば
    char received = Serial.read();   // 1文字読み取る
    if (received == '1') {
      digitalWrite(LED_PIN, HIGH);   // LED ON
      Serial.println("LED: ON");     // Pythonへ確認メッセージを返す
    } else if (received == '0') {
      digitalWrite(LED_PIN, LOW);    // LED OFF
      Serial.println("LED: OFF");
    }
  }
}

次にPython側のコードです。

import serial
import time

ser = serial.Serial('/dev/cu.usbmodem1401', 9600, timeout=1)
time.sleep(2)  # Arduino起動待ち

print("LED制御スタート! 'q' で終了")

try:
    while True:
        command = input("コマンドを入力(1: ON / 0: OFF): ")
        if command == 'q':
            break
        if command in ['0', '1']:
            ser.write(command.encode('utf-8'))  # 文字列をバイト列に変換して送信
            time.sleep(0.1)  # 返信を少し待つ
            response = ser.readline().decode('utf-8').strip()
            print(f"Arduino: {response}")
        else:
            print("0 か 1 を入力してください")
except KeyboardInterrupt:
    pass
finally:
    ser.close()  # 必ずポートを閉じる
    print("接続を終了しました")

これ、実際に動かしたとき「1」を打ち込んだ瞬間にArduinoのLEDが光ると、なんとも言えない達成感がありますよ 😄

ポイントはこちら 👇

  • ser.write() に渡すのはバイト列。encode('utf-8') を忘れずに
  • 送信後に少しだけ time.sleep() を入れると、Arduinoの返信を安定して受け取れます
  • finally ブロックで ser.close() することで、ポートを確実に解放できます

よくあるエラーと対処法






シリアル通信で詰まりやすいポイントをまとめておきますね 🔧

  • 「could not open port」エラー:ポート名が間違っている、またはArduino IDEのシリアルモニターが開いたままになっています。シリアルポートは同時に1つのプログラムしか使えません
  • 文字化けする:ボーレートがArduinoとPythonで一致していない可能性大
  • データが来ないtime.sleep(2) を入れ忘れていませんか?Arduinoはシリアル接続時にリセットがかかります
  • 「Permission denied」(Mac/Linux)sudo chmod 666 /dev/ttyUSB0 でポートの権限を変更してみてください

まとめ

今回学んだことをまとめます 📝

  • PythonとArduinoは pyserial を使ってシリアル通信で連携できる
  • Arduino側では Serial.begin()Serial.println() / Serial.read() を使う
  • Python側では serial.Serial() でポートに接続し、readline()write() でデータをやり取りする
  • ボーレートの一致・ポート名の確認・Arduino起動待ちの3点が特に重要!

シリアル通信をマスターすると、センサーデータをPythonで集計したり、Pythonで作ったGUIからArduinoを操作したり、できることが一気に広がりますよ 🚀

「むずかしそう」が「できそう」に変わった方は、ぜひ実際に手を動かして試してみてください!最初の一歩を踏み出すのが一番大事です。一緒に学んでいきましょう 💪

Pythonからデータ受信の実行結果
Pythonからデータ受信の実行結果
LED制御スクリプトの実行結果
LED制御スクリプトの実行結果

📡 Arduinoをもっと深く学ぼう!

Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。

Arduinoロボット入門のおすすめコース・部品を見る →

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

Arduinoをはじめよう 第4版 (Make: PROJECTS)

もしも

Arduinoをはじめよう 第4版 (Make: PROJECTS)

Arduino公式推薦の定番入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です