通过USB从Python到Arduino的通信

2024-06-08 20:34:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我想和一个阿杜伊诺人交流。我使用python和pyserial通过USB进行通信。正如您在下面的源代码中看到的,我正在尝试向Arduino发送一个bytearray,其中包含两个LED条带的一些信息。但是Arduino没有收到正确的信息。看起来bytearray被转换了或者信息丢失了。你知道吗

我找了一整天的解决办法,但什么都没用。希望你们中有人能帮我解决这个问题。你知道吗

提前谢谢。你知道吗

Python代码

import sys
import serial
import time

HEADER_BYTE_1 = 0xBA
HEADER_BYTE_2 = 0xBE


def main():
    ser = serial.Serial('/dev/ttyUSB0', 57600)
    message = { 'header': [None]*2, 'colors': [None]*6, 'checksum': 0x00 }
    message['header'][0] = HEADER_BYTE_1
    message['header'][1] = HEADER_BYTE_2
    # first led
    message['colors'][0] = 0xFF
    message['colors'][1] = 0xFF
    message['colors'][2] = 0xFF

    # second led
    message['colors'][3] = 0x00
    message['colors'][4] = 0x00
    message['colors'][5] = 0x00

    # create checksum
    for color in message['colors']:
        for bit in bytes(color):
            message['checksum'] ^= bit

    # write message to arduino
    cmd = convert_message_to_protocol(message)
    ser.write(cmd)
    print(cmd)

    time.sleep(5)
    # read response from arduino
    while True:
        response = ser.readline()
        print(response)


def convert_message_to_protocol(message):
    cmd = bytearray()
    for header in message['header']:
        cmd.append(header)

    for color in message['colors']:
        cmd.append(color)

    cmd.append(message['checksum'])

    return cmd

if __name__ == '__main__':
    main()

Arduino代码

const int kChannel1FirstPin = 3;
const int kChannel1SecondPin = 5;
const int kChannel1ThirdPin = 6;

const int kChannel2FirstPin = 9;
const int kChannel2SecondPin = 10;
const int kChannel2ThirdPin = 11;

// Protocol details (two header bytes, 6 value bytes, checksum)

const int kProtocolHeaderFirstByte = 0xBA;
const int kProtocolHeaderSecondByte = 0xBE;

const int kProtocolHeaderLength = 2;
const int kProtocolBodyLength = 6;
const int kProtocolChecksumLength = 1;

// Buffers and state

bool appearToHaveValidMessage;
byte receivedMessage[6];

void setup() {
  // set pins 2 through 13 as outputs:
  pinMode(kChannel1FirstPin, OUTPUT);
  pinMode(kChannel1SecondPin, OUTPUT);
  pinMode(kChannel1ThirdPin, OUTPUT);

  pinMode(kChannel2FirstPin, OUTPUT);
  pinMode(kChannel2SecondPin, OUTPUT);
  pinMode(kChannel2ThirdPin, OUTPUT);

  analogWrite(kChannel1FirstPin, 255);
  analogWrite(kChannel1SecondPin, 255);
  analogWrite(kChannel1ThirdPin, 255);

  analogWrite(kChannel2FirstPin, 255);
  analogWrite(kChannel2SecondPin, 255);
  analogWrite(kChannel2ThirdPin, 255);

  appearToHaveValidMessage = false;

  // initialize the serial communication:
  Serial.begin(57600);
}


void loop () {

  int availableBytes = Serial.available();

  Serial.println(availableBytes);

  if (!appearToHaveValidMessage) {
    // If we haven't found a header yet, look for one.
    if (availableBytes >= kProtocolHeaderLength) {
      Serial.println("right size");
      // Read then peek in case we're only one byte away from the header.
      byte firstByte = Serial.read();
      byte secondByte = Serial.peek();

      if (firstByte == kProtocolHeaderFirstByte &&
          secondByte == kProtocolHeaderSecondByte) {

          Serial.println("Right Header");
          // We have a valid header. We might have a valid message!
          appearToHaveValidMessage = true;

          // Read the second header byte out of the buffer and refresh the buffer count.
          Serial.read();
          availableBytes = Serial.available();
      }
    }
  }

  if (availableBytes >= (kProtocolBodyLength + kProtocolChecksumLength) && appearToHaveValidMessage) {

    // Read in the body, calculating the checksum as we go.
    byte calculatedChecksum = 0;

    for (int i = 0; i < kProtocolBodyLength; i++) {
      receivedMessage[i] = Serial.read();
      calculatedChecksum ^= receivedMessage[i];
    }

    byte receivedChecksum = Serial.read();

    if (receivedChecksum == calculatedChecksum) {
      // Hooray! Push the values to the output pins.

      analogWrite(kChannel1FirstPin, receivedMessage[0]);
      analogWrite(kChannel1SecondPin, receivedMessage[1]);
      analogWrite(kChannel1ThirdPin, receivedMessage[2]);

      analogWrite(kChannel2FirstPin, receivedMessage[3]);
      analogWrite(kChannel2SecondPin, receivedMessage[4]);
      analogWrite(kChannel2ThirdPin, receivedMessage[5]);


      Serial.print("OK");
      Serial.write(byte(10));

    } else {

      Serial.print("FAIL");
      Serial.write(byte(10));
    }

    appearToHaveValidMessage = false;
  }
}

示例

在Python中生成的字节:b'\xba\xbe\xff\xff\xff\x00\x00\x00\x00'

在Arduino上接收的字节:b'L\xc30\r\n'


Tags: theincmdmessageforifserialbyte