LoginSignup
1
2

More than 3 years have passed since last update.

ラズパイからArduinoに2byteシリアル通信する

Last updated at Posted at 2019-06-02

はじめに

前回の記事のデータを通信するために、USB-シリアル変換ボードを買ったので、ラズパイからArduinoに2byteシリアル通信する実験をしたメモ。

記述言語はpython。

ラズパイ側はUSBにUSB-シリアル変換ボードを差し、Arduino nanoのTX、RXに接続する。GNDをつながないと通信が安定しなかった

ラズパイ側からの値は16bit以下であることが、暗黙的な仕様になっている。

jsonファイル

辞書形式で読み込んだ時に、データの順番がファイル通りになるようにjsonファイルを読み込んで、valuesに格納されたxy座標をシリアル通信でArduinoに送信する。

{
    "0": [
        91,
        78
    ],
    "1": [
        119,
        169
    ],
    "2": [
        223,
        140
    ],
    "3": [
        174,
        115
    ],
    "4": [
        224,
        82
    ],
    "5": [
        283,
        160
    ],
    "6": [
        163,
        194
    ],
    "7": [
        53,
        168
    ]
}

pythonプラグラム

参考文献

以下の情報を参考にして、プログラムを作成した。

ライブラリ

pyserial、jsonを使用する。

プログラム

ラズパイ

数字を文字列ではなく実データとして送信する必要がある。従って2byteデータを上位8bit、下位8bitに分割してbig endianで送信し、Arduino側で合成する。

0 1 2 3 4 5 6 7 ...
x[0]_upp x[0]_low y[0]_upp y[0]_low x[1]_upp x[1]_low y[1]_upp y[1]_low ...
import json
import serial
import collections

#通信設定
sdev = '/dev/ttyUSB0'
baud = 115200

def send2Byte(pt):
    j = 0
    with serial.Serial(sdev, baud, timeout=1) as ser:
        for i in pt.values():
            #print(i[0]) # x
            #print(i[1]) # y
            ix_upp = (i[0] & 0xff00) >> 8
            ix_low = (i[0] & 0x00ff)
            iy_upp = (i[1] & 0xff00) >> 8
            iy_low = (i[1] & 0x00ff)
            #print("x : ", ix_upp * 256 + ix_low,"=",  i[0])
            #print("y : ", iy_upp * 256 + iy_low,"=",  i[1])
            print("x[", j, "] : ", ix_upp * 256 + ix_low)
            print("y[", j, "] : ", iy_upp * 256 + iy_low)
            ser.write(ix_upp.to_bytes(1, 'big'))
            ser.write(ix_low.to_bytes(1, 'big'))
            ser.write(iy_upp.to_bytes(1, 'big'))
            ser.write(iy_low.to_bytes(1, 'big'))
            j += 1
        ser.close()

if __name__ == "__main__":

    decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
    with open('test.json', 'r') as f:
        pt = decoder.decode(f.read())
    """
    for i in pt.values():
        print(i)
    """
    send2Byte(pt)

Arduino

通信データの上限は100として、1byteづつ送られてくるデータを4byte周期で合成し、x、y配列に格納していく。

#define DNUM 100
int n = 0;
int m = 0;
int x[DNUM], y[DNUM];
int nmod = 0;

void setup(){
  pinMode(13,OUTPUT); //13番ピンを出力に設定。特に使っていない。
  Serial.begin(115200);//シリアル通信のレート
  int i;
  for(i = 0; i < DNUM; i++){
    x[i] = 0;
    y[i] = 0;
  }
}

void loop(){

  int inchar;      //入力状態の読み取りに使う
  inchar = Serial.read();  //シリアル通信で送信された値を読み取る

  if(inchar!=-1){
    nmod = n % 4;

    if(nmod == 0){
      Serial.println("== received ==");
    }

    switch(nmod){
      case 0:
        x[m] += (inchar << 8);
        break;
      case 1:
        x[m] += inchar;
        Serial.print("x[");
        Serial.print(m);
        Serial.print("]:");
        Serial.println(x[m]);
        break;
      case 2:
        y[m] += (inchar << 8);
        break;
      case 3:
        y[m] += inchar;
        Serial.print("y[");
        Serial.print(m);
        Serial.print("]:");
        Serial.println(y[m]);
        m++;
        break;
    }
    //Serial.print("n:");
    //Serial.println(n);
    n++;
  }
  else{
    n = 0;
    m = 0;
    int i;
    for(i = 0; i < DNUM; i++){
      x[i] = 0;
      y[i] = 0;
    }
  }
}

実行結果

ラズパイ側

x[ 0 ] :  91
y[ 0 ] :  78
x[ 1 ] :  119
y[ 1 ] :  169
x[ 2 ] :  223
y[ 2 ] :  140
x[ 3 ] :  174
y[ 3 ] :  115
x[ 4 ] :  224
y[ 4 ] :  82
x[ 5 ] :  283
y[ 5 ] :  160
x[ 6 ] :  163
y[ 6 ] :  194
x[ 7 ] :  53
y[ 7 ] :  168

Arduino側

== received ==
x[0]:91
y[0]:78
== received ==
x[1]:119
y[1]:169
== received ==
x[2]:223
y[2]:140
== received ==
x[3]:174
y[3]:115
== received ==
x[4]:224
y[4]:82
== received ==
x[5]:283
y[5]:160
== received ==
x[6]:163
y[6]:194
== received ==
x[7]:53
y[7]:168

思ったようにできた。

1
2
0

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
1
2