#はじめに
前回の記事のデータを通信するために、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
思ったようにできた。