【发布时间】:2019-09-04 09:31:42
【问题描述】:
我在尝试使用 串行通信 将一些值从 Python 3.x 发送到 Arduino 时遇到问题。
小于 255 时正常,大于 255 时会报错。
我在 Python 中使用 Struct.pack,在 Arduino 中使用 Serial.read()
Python 代码:
import cv2
import numpy as np
from serial import Serial
import struct
arduinoData = Serial('com6', 9600)
cap = cv2.VideoCapture(0)
hand_cascade = cv2.CascadeClassifier('hand.xml')
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
handdetect = hand_cascade.detectMultiScale(gray, 1.6, 3)
for (x, y, w, h) in handdetect:
cv2.rectangle(frame, (x, y), (x + w, y + h), (127, 127, 0), 2)
xcenter = int(x + w/2)
ycenter = int(y + h/2)
#This is where i send values to serial port
arduinoData.write(struct.pack('>II',xcenter,ycenter))
cv2.imshow('Webcam', frame)
k = cv2.waitKey(25) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
Arduino 代码:
int SerialData[8];
const int led = 7;
int xcenter;
int ycenter;
void setup(){
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
if (Serial.available() >= 8){
for (int i = 0; i < 8; i++){
SerialData[i] = Serial.read();
}
xcenter = (SerialData[0]*1000) + (SerialData[1]*100) + (SerialData[2]*10) + SerialData[3];
ycenter = (SerialData[4]*1000) + (SerialData[5]*100) + (SerialData[6]*10) + SerialData[7];
if (xcenter <= 200){
digitalWrite(led, LOW);
}
else if(xcenter > 200){
digitalWrite(led, HIGH);
}
//Serial.flush();
}
}
就像我在本主题开头所说的那样,当xcenter > 200 && xcenter <= 255 时,LED 亮起(这意味着代码工作正常)。
但是当xcenter > 255 时,LED 熄灭(这里有问题)。
我想我已经读取了 Arduino 代码中的所有 8 个字节,并在 struct.pack 中使用了 unsigned int >II,那么我的错误是什么以及在哪里?
我很感激所有的帮助!谢谢!
编辑和修复。
“它不会将 int 打包成数字 (0-9),而是将它们打包成字节 (0-255)”_
所以这是错误的:
xcenter = (SerialData[0]*1000) + (SerialData[1]*100) + (SerialData[2]*10) + SerialData[3];
ycenter = (SerialData[4]*1000) + (SerialData[5]*100) + (SerialData[6]*10) + SerialData[7];
改成这个(对于大值):
long result = long((unsigned long(unsigned char(SerialData[0])) << 24) | (unsigned long(unsigned char(SerialData[1])) << 16)
| (unsigned long(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
或者改成这个(对于小值):
xcenter = (SerialData[2]*256) + SerialData[3];
ycenter = (SerialData[6]*256) + SerialData[7];
或者这个(也适用于小值):
int result = int((unsigned int(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
代码会完美运行!
【问题讨论】:
-
它不会将 int 打包成数字 (0-9),而是将它们打包成字节 (0-255)。 256 被打包到 00 00 01 00 中,您将其解压缩为 10x1,而 255 是 00 00 00 ff,在您的情况下为 1x255。将 10 的幂更改为 256 (2^8) 的幂。或者不要打包它们,只需将它们转换为字符串,例如 "{:04d}{:04d}".format(intA, intB)
-
感谢@IcedLance 向我展示了我的错误。我是代码新手,请问第一个字节代表什么?。
-
您可以查看 this link 以了解其工作原理,但简而言之:十进制(以 10 为底)从 0 变为 9,因此 356 = 3*10*10 + 5*10 + 6 而字节从 0 到 255,这意味着 03 05 06 = 3*256*256 + 5*256 + 6。我用 2 个字母写它们,因为通常用成对的十六进制数字表示字节值(基数 16 , 256=16*16)。在您的情况下,第一个字节基本上代表`xcenter /(256 * 256 * 256)。在 xcenter 大于 256^3 之前,它将为 0。
-
亲爱的@IcedLand,谢谢你的帮助,我已经解决了我所有的问题!你拯救了我的一天,再次感谢,祝你有美好的一天!最好的尊重。
-
@IcedLance 请将解决方案作为答案发布并接受!
标签: python-3.x arduino serial-port pyserial serial-communication