通过 USB 从 Python 到 Arduino 的通信
Posted
技术标签:
【中文标题】通过 USB 从 Python 到 Arduino 的通信【英文标题】:Communication from Python to Arduino over USB 【发布时间】:2016-08-03 19:26:26 【问题描述】:我正在尝试与 Arduino 进行交流。我使用 python 和 pyserial 通过 USB 进行通信。正如您在下面的源代码中看到的那样,我正在尝试向 Arduino 发送一个字节数组,其中包含两个 LED 条的一些信息。但是 Arduino 没有收到正确的信息。看起来字节数组已转换或信息丢失。
我整天都在寻找解决方案,但没有任何效果。希望你们能帮我解决这个问题。
提前致谢。
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'
【问题讨论】:
【参考方案1】:将波特率更改为 9600 已修复通信
【讨论】:
以上是关于通过 USB 从 Python 到 Arduino 的通信的主要内容,如果未能解决你的问题,请参考以下文章
从 Arduino Yun 上的 USB 接口获取 MIDI 音符
无法通过 USB 向 Arduino 发送/接收数字来控制电机
将串行从 Raspberry 传递到 Arduino USB HID