Take the 2-minute tour ×
Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. It's 100% free, no registration required.

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.

share|improve this question
1  
Serial.print() is slow - try a faster baud rate, like 115200? –  Nick Gammon Jul 31 at 5:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.