python–serial通信–arduino, 1byte, 2bytes, 複数データ

pythonとarduinoとのserial通信まとめ
1byte, 2bytes, 複数データ *2
で6パターンあります.

過去の関連記事:
openFrameworks, serial通信, arduino, 1 byte, 2 bytes, multi-data

codes

1byte

python > arduino

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)
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

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)
void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.write(234);
}

2bytes

python > arduino

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)
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

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)
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

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

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)
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

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です