pythonとarduinoとのserial通信まとめ
1byte, 2bytes, 複数データ *2
で6パターンあります.
過去の関連記事:
openFrameworks, serial通信, arduino, 1 byte, 2 bytes, multi-data
codes
1byte
python > arduino
write_1byte.py
import time
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=0.1)
while True:
val = 3
valByte = val.to_bytes(1, 'big')
# valByte = val.to_bytes(2, 'little')
ser.write(valByte)
print(val)
time.sleep(1)
serial_read_1byte.ino
int readByte = 0;
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
readByte = Serial.read();
Serial.println(readByte, DEC);
//Serial.println(readByte);
}
}
arduino > python
read_1byte.py
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=0.1)
while True:
c = ser.read() # 1文字読み込み
# val = int(c.hex(), 16)
val = int.from_bytes(c, 'big')
print(val)
serial_write_1byte.ino
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.write(234);
}
2bytes
python > arduino
write_2bytes.py
import time
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=0.1)
val = 500
while True:
head = 128
high = (val >> 7) & 127
low = val & 127
headByte = head.to_bytes(1, 'big')
highByte = high.to_bytes(1, 'big')
lowByte = low.to_bytes(1, 'big')
ser.write(headByte)
ser.write(highByte)
ser.write(lowByte)
#print(val)
time.sleep(1)
serial_read_2bytes.ino
int value = 0;
bool isValid = false;
void setup(){
Serial.begin(9600);
}
void loop(){
isValid = false;
if (Serial.available() >= 3) {
int head = Serial.read();
if (head == 128) {
int high = Serial.read();
int low = Serial.read();
value = (high<<7) + low;
Serial.println(value, DEC);
if (0 <= value <= 1023) {
isValid = true;
}
}
}
}
arduino > python
read_2bytes.py
import serial
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=0.1)
while True:
isValid = False;
headByte = ser.read() # 1文字読み込み
head = int.from_bytes(headByte, 'big')
if head == 128:
highByte = ser.read() # 1文字読み込み
lowByte = ser.read() # 1文字読み込み
high = int.from_bytes(highByte, 'big')
low = int.from_bytes(lowByte, 'big')
val = (high<<7) + low;
if 0 <= val and val <= 1023 :
#print("value is %d \n", val);
isValid = True;
if isValid:
print(val)
serial_write_2bytes.ino
int value = 963;
void setup(){
Serial.begin(9600);
}
void loop(){
int low = value & 127;
int high = (value >> 7) & 127;
int head = 128;
Serial.write(head);
Serial.write(high);
Serial.write(low);
}
複数データ 2bytes
python > arduino
write_multi-2bytes.py
import time
import serial
val_size = 3
values = [123, 456, 789]
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=0.1)
while True:
isValids = [False for x in range(val_size)]
for i in range(val_size):
head = 128+i
high = (values[i] >> 7) & 127
low = values[i] & 127
headByte = head.to_bytes(1, 'big')
highByte = high.to_bytes(1, 'big')
lowByte = low.to_bytes(1, 'big')
ser.write(headByte)
ser.write(highByte)
ser.write(lowByte)
print(values)
time.sleep(3)
:serial_read_multi-2bytes.ino
const int val_size = 3;
int values[val_size] = {0, 0, 0};
bool isValids[val_size] = {false, false, false};
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() >= 3*val_size+1) {
int head = Serial.read();
if (head == 128){
bool isValids[val_size] = {false, false, false};
}
for (int i=0; i<val_size; i++){
if (head == 128+i) {
int high = Serial.read();
int low = Serial.read();
values[i] = (high<<7) + low;
Serial.print("[");
Serial.print(i, DEC);
Serial.print("]");
if (0 <= values[i] <= 1023) {
Serial.print("[");
Serial.print(values[i], DEC);
if (head == 128+val_size-1) {
Serial.println("]");
}else{
Serial.print("] ");
}
isValids[i] = true;
}
}
}
}
}
arduino > python
read_multi-2bytes.py
import serial
val_size = 3;
values = [0 for x in range(val_size)]
isValids = [False for x in range(val_size)]
ser = serial.Serial('/dev/cu.usbmodem1421', 9600, timeout=0.1)
while True:
headByte = ser.read() # 1文字読み込み
head = int.from_bytes(headByte, 'big')
if head == 128:
isValids = [False for x in range(val_size)]
for i in range(val_size):
if head == 128+i:
highByte = ser.read() # 1文字読み込み
lowByte = ser.read() # 1文字読み込み
high = int.from_bytes(highByte, 'big')
low = int.from_bytes(lowByte, 'big')
values[i] = (high<<7) + low;
if 0 <= values[i] and values[i] <= 1023 :
isValids[i] = True;
#print(values[i])
if all(i == True for i in isValids):
print(values)
serial_write_multi-2bytes.ino
const int val_size = 3;
int values[val_size] = {123, 456, 789};
void setup(){
Serial.begin(9600);
}
void loop(){
for (int i=0; i<val_size; i++){
int high = (values[i] >> 7) & 127;
int low = values[i] & 127;
Serial.write(128+i);
Serial.write(high);
Serial.write(low);
}
}
ref
Pythonでシリアル通信
Python 3 で16進数とバイト列の相互変換
pySerial Short introduction
python3ならintとbytesの変換が楽勝になる
python 組み込み型 int.to_bytes
C言語の演算子について
python ビット演算子
How to check if all elements of a list matches a condition?
python Built-in Functions all