在使用 Arduino 和 Python 通过串行通信发送多个字节时,遇到了问题。代码似乎能够运行,但某些用于调试目的的 print 语句输出的字符串与预期不同。尝试编写了一个简化版的代码,发现它可以正常运行,因此不确定自己做错了什么。此外,在尝试修复问题时,添加了一个 if 语句,导致代码速度大大降低。希望获得一些关于如何优化代码以提高速度以及如何发送和接收正确数据的建议。
- 解决方案
要解决这个问题,需要对代码进行一些调整:
- 在 Python 代码中,使用
forceBytes = bytes([wristPerc, elbowPerc])
而不是forceBytes = bytearray([wristPerc, elbowPerc])
。这将创建一个字节数组,而不是字节数组,并可以正确地发送数据。 - 在 Arduino 代码中,使用
char inByte = Serial.read();
而不是char inByte = Serial.readChar();
。这将从串行端口读取一个字节,而不是一个字符。 - 在 Arduino 代码中,使用
if (inByte == 'A')
而不是if (inByte == 'a')
。这将把输入字节与字符’A’进行比较,而不是字符串’a’。
修改后的代码如下:
Python:
import serial
import time
#sets the connection parameters, relook at when know more
ser = serial.Serial(
port ='COM4',
baudrate = 9600,
parity = serial.PARITY_ODD,
stopbits = serial.STOPBITS_TWO,
bytesize = serial.EIGHTBITS,
timeout = 5
)
def decToPercent (decimal):
#maps value from 0-1 to 0-255 and makes into an interger, then to hex
intPercent = round(decimal*255)
return intPercent
ser.isOpen() #returns true?
firstContact = False
inByte = 0
wrist = 0.9 #setup of variables which I will get from dictionary of other code once integrate
elbow = 0 #assuming variables will be included in (0-1)
wristPerc = decToPercent(wrist)
elbowPerc = decToPercent(elbow)
forceBytes = bytes([wristPerc, elbowPerc]) #puts the motor values into an array as hex
print(forceBytes)
#set up initial contact with the arduino
inByte = ser.read(1)
print(inByte)
while True:
if (firstContact == False):
if inByte == b'A' :
firstContact = True
ser.write('a'.encode())
inByte = ser.read(1)
else:
ser.write(forceBytes)
time.sleep(0.05)
print(ser.readline())
#starts the process over again, clears so that have time to get information
firstContact = False
inByte = ser.read(1)
print(inByte)
Arduino:
int motorPinLeft = 10;
int motorPinRight = 11;
int motorSpeedLeft = 0;
int motorSpeedRight = 0;
int fieldIndex = 1;
byte values[2]; //array holding values for the fields we expect
byte newByte = 0;
void setup() {
pinMode(motorPinLeft, OUTPUT);
pinMode(motorPinRight, OUTPUT);
Serial.begin(9600);
while(!Serial){}; //waits for arduino to be ready, not neaded for duo
establishContact();
}
void loop()
{
while (Serial.available()>0) //checks to see if anything needs to be sent,
{ //denoted by recieveing signal from pySerial
char inByte = Serial.read();
switch (inByte)
{
case 97:
inByte = 0;
break;
default:
values[0] = inByte;
//could just call Serial.read and asign 2nd byte, but loop allows to send more variables later
if (fieldIndex < 2)
{
newByte = Serial.read();
values[fieldIndex] = newByte;
fieldIndex++;
}
else
{
Serial.print(values[0], DEC); //debugging purposes
Serial.print(values[1], DEC);
motorSpeedLeft = values[0];
motorSpeedRight = values[1];
//Serial.print(motorSpeedLeft);
//Serial.print(motorSpeedRight);
analogWrite(motorPinLeft, motorSpeedLeft);
analogWrite(motorPinRight, motorSpeedRight);
delay(3000); // to make the motor vibrate for 1 second
motorSpeedRight = 0;
motorSpeedLeft = 0;
analogWrite(motorPinLeft, motorSpeedLeft);
analogWrite(motorPinRight, motorSpeedRight);
delay(1000);
}
}
//Serial.print('A');
}
}
//allows arduino to be ready before pySerial sends any messages
void establishContact()
{
while (Serial.available()<=0)
{
Serial.print('A');
delay(300);
}
}
修改后的代码可以正常运行,并且能够正确地发送和接收数据。