I am trying to send an integer value from Python to Arduino. The integer value is a position given by a webcam, which will determine how many turns a stepper motor moves.
Arduino:
#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER,8,9);
void setup() {
Serial.begin(9600);
stepper.setMaxSpeed(1000.0);
stepper.setAcceleration(700.0);
}
void loop() {
int val = 0;
if(Serial.available()){
val = map(Serial.parseInt(), 0, 1280, 0, 551);
Serial.println(val);
}
stepper.runToNewPosition(val);
}
Python:
# source: http://www.steinm.com/blog/motion-detection-webcam-python-opencv-differential-images/
import cv2
import numpy as np
import serial
import time
def diffImg(t0, t1, t2):
d1 = cv2.absdiff(t2, t1)
d2 = cv2.absdiff(t1, t0)
dif = cv2.bitwise_and(d1, d2)
return np.fliplr(dif)
cam = cv2.VideoCapture(0)
#winName = "Movement Indicator" #camera window
#cv2.namedWindow(winName, cv2.WINDOW_NORMAL)
# Read three images first:
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
h, w = t.shape
winTest = "Test Window" #test window
cv2.namedWindow(winTest, cv2.WINDOW_NORMAL)
thresh = 100
ser=serial.Serial('/dev/cu.usbmodem1411',9600,timeout=0)
time.sleep(2)
while True:
img = diffImg(t_minus, t, t_plus)
# cv2.imshow(winName, img )
nz = np.transpose(np.nonzero(img>thresh))
a = 0
b = 0
c = 0
d = 0
avg=0
if nz.size>0:
a,b = nz[0]
c,d = nz[-1]
avg = (b+d)/2
if 0<=avg and avg<=1280:
print avg
ser.write(str(int(avg))+" ")
test = np.zeros((h,w))
cv2.rectangle(test, ((avg-5),a), ((avg+5),c), (255), -1)
cv2.imshow(winTest, test )
# Read next image
t_minus = t
t = t_plus
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
print ser.readline();
key = cv2.waitKey(10)
if key == 27:
cv2.destroyWindow(winName)
ser.close()
break
print "Goodbye"
This works OK but occasionally 'val' will take some ridiculous value, say 7182, and the motor spins out of control. I realize I can check values with an if statement before I actually write to the stepper motor, but I think my problem is with reading and writing to the Arduino.
My other issue is I feel Arduino is not receiving some of the data sent to it via serial connection. This is hard to say, as Serial.print() is slow and mostly doesn't make it through to my terminal before it's already been rewritten.
Serial.print() is slow
- try a faster baud rate, like 115200?