#目的
本稿の目的は, 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 シリアル通信
- Arduino の13番ピンとGNDにLEDをつなげる
- LEDの足が長いほうが13番, 短い方はGND
- 以下のプログラム
Serial_Com_LED.ino
をArdino IDEで書いて, Arduino に書き込む
一旦このプログラムをArduino IDE上で実行し, シリアルモニタを用いてLEDの明滅を制御できるか確認する - 以下のプログラム
Serial_Com_LED.py
を作成する -
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 シリアル通信
- ピン接続
ジャンパワイヤとブレッドボードを用いてそれぞれ以下のように接続する
Arduino | HC-SR04 |
---|---|
5V | Vcc |
GND | GND |
Pin-9 | Trig |
Pin-10 | Echo |
- 以下の
.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に変換
-