90
85

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-08-18

#目的
本稿の目的は, 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

環境

  • Windowsだがおそらく汎用的なので省略

PC → Arduino シリアル通信

  1. Arduino の13番ピンとGNDにLEDをつなげる
  • LEDの足が長いほうが13番, 短い方はGND
  1. 以下のプログラム Serial_Com_LED.ino をArdino IDEで書いて, Arduino に書き込む
    一旦このプログラムをArduino IDE上で実行し, シリアルモニタを用いてLEDの明滅を制御できるか確認する
  2. 以下のプログラムSerial_Com_LED.pyを作成する
  3. 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型を返させるのに苦労しました
原理はわかりませんがとりあえず動いたので良しとします

  • 以下の手続きを踏んでいる
    • ser.readline()で, serial.Serial...の出力を一行分読み込む
    • d = re.findall... で正規表現によって所望の出力を得る
    • re.findallが返す値の型はlist(str)であるため
      • リストから文字列を得る
      • floatに変換

引用, 参考

90
85
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
90
85

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?