I have a problem while trying to send some values from Python 3.x
to Arduino
using Serial Communication.
It working fine when the value is smaller than 255, but when it's greater than 255, error will happen.
I'm using Struct.pack
in Python and Serial.read()
in Arduino
Python code:
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 code:
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();
}
}
Like I said at the beginning of this topic, when xcenter > 200 && xcenter <= 255
, the LED is turned ON (it's mean the code working fine).
But when xcenter > 255
, the LED is OFF (something wrong here).
I think I already read all 8 bytes in Arduino code and used unsigned int >II
in struct.pack
, so what and where is my false?
I'm appreciate for all help! Thank you!
EDIT and FIXED.
"It doesn't pack int into digits (0-9), it packs them into bytes (0-255)"_
So here is the false:
xcenter = (SerialData[0]*1000) + (SerialData[1]*100) + (SerialData[2]*10) + SerialData[3];
ycenter = (SerialData[4]*1000) + (SerialData[5]*100) + (SerialData[6]*10) + SerialData[7];
Changed to this (for the large values):
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]));
Or changed to this (for the small values):
xcenter = (SerialData[2]*256) + SerialData[3];
ycenter = (SerialData[6]*256) + SerialData[7];
Or this (for the small values too):
int result = int((unsigned int(unsigned char(SerialData[2])) << 8) | unsigned char(SerialData[3]));
And the code gonna work perfectly!