スタートアップエンジニアの作ってみた日記

ものづくりが下手な横好きなエンジニアによる作ってみた的なブログです。

Python を使ってArduino 2台を通信してみた

Arduino2台の通信を調べてみたら、Arduino2台を直接接続してI2C通信する記事はたくさんあるのですが、Arduino2台をそれぞれをPCにUSBで接続して通信する記事はあまり見つからなかったので、書きます。

簡単ですが、以下のような構成です。

f:id:goengine:20190826002459p:plain

今回は1台のarduinoジョイスティックを接続して、もう1台にサーボモータを接続します。

ジョイスティックの値をserial.writeで一度、PCに送り、pythonでそちらの値を受け取ります。

その受け取った値を、python上で別のarduinoにserial.writeすることで別のarduinoに値を送信します。

その値に応じてサーボモータを動かします。

 

pythonの準備

以下のコードのser.port = "COM9"の箇所を自分の環境にあった値にしてください。デバイスマネージャーやArduino IDEなどで確認できると思います。

値;

と連続的に送られてきたものを;区切りで受け取り値を取り出すようになっています。

今回は受け取った値をそのままもう一台のArduinoに送ってますが、何かしらの処理をPython上でやって送ることももちろん可能です。

import serial
import binascii

#シリアル通信(PC⇔Arduino)
ser = serial.Serial()
ser.port = "COM9"     #デバイスマネージャでArduinoのポート確認
ser.baudrate = 115200 #Arduinoと合わせる
ser.setDTR(False)     #DTRを常にLOWにしReset阻止
ser.open()            #COMポートを開
ser1 = serial.Serial()
ser1.port = "COM3"     #デバイスマネージャでArduinoのポート確認
ser1.baudrate = 115200 #Arduinoと合わせる
ser1.setDTR(False)     #DTRを常にLOWにしReset阻止
ser1.open()            #COMポートを開く
while True:
    try:
        character_array = []
        read_line = ''
        while True:
            abc = ser.read()
            ch = abc.decode("UTF-8")
            if ch == ';' :
                break
            else:
                character_array.append(ch)
        map_c = map(str, character_array)
        read_line = ''.join(map_c)
        split_fields = read_line.split(',')
        value = split_fields[0] 
        #以下で他のarduinoに値を送信
        ser1.write(value.encode("UTF-8"))
        ser1.write(b";")
    except Exception as e:
        msg = 'false'
        print(msg)
ser.close()

 

■値を送る側Arduinoの準備

今回はジョイスティックのx成分の値だけをPCに送信します。

値;

という形式で連続的に送信しています。

int x_pin = 0; 
//両端の端子は,GNDと+5Vに接続
int x_val = 0;           //読み取った値を格納する変数

void setup()
{
  Serial.begin(115200);              //シリアルの設定
}

void loop()
{
  x_val = analogRead(x_pin);     //入力ピンの読み取り
  Serial.print(x_val);             //値の表示
  Serial.print(";");  
}

 

■値を受け取る側のArduinoの準備

値;

と連続的に送られてきたものを;区切りで受け取り値を取り出すようになっています。

#include <Servo.h>
Servo myServo;

String str;
String value;
int value1 = 525;
int angle;

void setup() {
  Serial.begin(115200);
  myServo.attach(11);
}

void loop() {
  if (Serial.available() > 0)
  {
    str = Serial.readStringUntil(';');

    value = str.substring(0, sizeof(str) - 1);
    value1 = value.toInt();

    angle = value1 / 1024.0 * 180;
  }

  myServo.write(angle);
}

 以上で(今回はかなり説明が雑ですが、、)、動くようになったかと思います。

動いた様子はこんな感じです。

 以上で、pythonを使った2台のArduinoの通信でした。