Arduino
python3
シリアル通信

PC-Arduino間 Python経由 シリアル通信備忘録

More than 1 year has passed since last update.

目的

本稿の目的は, Python を用いて, 'Arduino' のシリアル通信で得た値を数値として処理できるようにすることである.

目標

  • PC側から 'Arduino' にデータを送信, その内容に応じて 'Arduino' の動作を変化させる
  • PCが, 'Arduino' から受信したデータを数値的に処理できるようにする

具体的目標

  • PCから文字データを送信し, ArduinoのLEDの明滅を操作するプログラムを組む
  • 超音波距離センサ 'HC-SR04' から得たデータから数値を取り出すプログラムを組む
  • 上記プログラム言語には Python 3.x を利用する

準備

  • Arduino Uno Rev.3
  • USBケーブル
  • LED
  • ジャンパワイヤ 4本
  • HC-SR04
  • Python 3.x , Arduino IDE
  • Python モジュール : PySerial

環境

  • 汎用的なので省略

PC → Arduino シリアル通信

  1. Arduino の13番ピンとGNDにLEDをつなげる
    • LEDの足が長いほうが13番, 短い方はGND
  2. 以下のプログラム Serial_Com_LED.ino をArdino IDEで書いて, Arduino に書き込む
    一旦このプログラムをArduino IDE上で実行し, シリアルモニタを用いてLEDの明滅を制御できるか確認する
  3. 以下のプログラムSerial_Com_LED.pyを作成する
  4. Serial_Com_LED.pyを実行すると, Arduino IDEで実行した際と同様の動作が得られる
Serial_Com_LED.ino
void setup(){
  pinMode(13,OUTPUT); //13番ピンを出力に設定

  Serial.begin(9600);//シリアル通信のレートを9600に設定
}

void loop(){

  int inputchar;      //入力状態の読み取りに使う

  inputchar = Serial.read();  //シリアル通信で送信された値を読み取る

  if(inputchar!=-1){
    switch(inputchar){
      case 's':
        digitalWrite(13,HIGH);
        break;

      case 'q':
        digitalWrite(13,LOW);
        break;
    }
  }
  else{
  }
}
Serial_Com_LED.py
#coding:utf-8

#シリアル通信で文字をArduino側に送信
#aが押されたら通信を中止するプログラム

import serial   #モジュール名はpyserialだが, importする際はserialである

def main():
    with serial.Serial('COM3',9600,timeout=1) as ser:
        while True:
            flag=bytes(input(),'utf-8')

            #シリアル通信で文字を送信する際は, byte文字列に変換する
            #input()する際の文字列はutf-8

            ser.write(flag)

            #シリアル通信:送信

            if(flag==bytes('a','utf-8')):
                break;
        ser.close()

if __name__ == "__main__":
    main()

Arduino → PC シリアル通信

  1. ピン接続
    ジャンパワイヤとブレッドボードを用いてそれぞれ以下のように接続する
Arduino HC-SR04
5V Vcc
GND GND
Pin-9 Trig
Pin-10 Echo
  1. 以下の.ino, .py プログラムを書き込む
Serial_Com_Sonic.ino
#define echoPin 10 // Echo Pin
#define trigPin 9 // Trigger Pin

double Duration = 0; //受信した間隔
double Distance = 0; //距離
void setup() {
Serial.begin( 9600 );
pinMode( echoPin, INPUT );
pinMode( trigPin, OUTPUT );
}
void loop() {
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  digitalWrite( trigPin, HIGH ); //超音波を出力
  delayMicroseconds( 10 ); //
  digitalWrite( trigPin, LOW );
  Duration = pulseIn( echoPin, HIGH ); //センサからの入力
  if (Duration > 0) {
    Duration = Duration/2; //往復距離を半分にする
    Distance = Duration*340*100/1000000; // 音速を340m/sに設定
    Serial.println(Distance);
  }
  delay(500);
}
Serial_Com_Sonic.py
#coding utf-8
import serial
import re
def main():
    with serial.Serial('COM3',9600,timeout=1) as ser:

        while True:
            c = ser.readline()
            d = re.findall('[0-9]+\.+[0-9]',str(c),flags=0)
            d = [float(i) for i in d]
            for i in range(0, len(d)):  #要素を1つずつ順番に出力します
                print(d[i])
            print
        ser.close()

if __name__=="__main__":
    main()

実行

HC-SR04 についてのプログラムで, list型ではなく, float型を返させるのに苦労しました
原理はわかりませんがとりあえず動いたので良しとします

引用, 参考