Python to arduino serial communication to run stepper motor

Dear ALL,

I want to send "1" or "2" values from python to Arduino through SERIAL READ(). I have posted my Arduino code and Python code below . I could run the stepper motor by entering the values "1" or "2" on arduino serial monitor.
I have a python code that tracks the color and gives output values 1 or 2.
Please let me know how to supply those values correctly to arduino to run stepper motor clockwise and anticlockwise
Python code:

#Developed by Vikrant Fernandes

import numpy as np
import cv2
import serial
import time

#Serial object for communication with Arduino
ser = serial.Serial('/dev/ttyACM0')

#Capture from external USB webcam instead of the in-built webcam (shitty quality)
cap = cv2.VideoCapture(0)

#kernel window for morphological operations
kernel = np.ones((5,5),np.uint8)

#resize the capture window to 640 x 480
ret = cap.set(3,640)
ret = cap.set(4,480)

#upper and lower limits for the color yellow in HSV color space
lower_yellow = np.array([20,100,100])
upper_yellow = np.array([30,255,255])

#begin capture
while(True):
ret, frame = cap.read()

#Smooth the frame
frame = cv2.GaussianBlur(frame,(11,11),0)

#Convert to HSV color space
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

#Mask to extract just the yellow pixels
mask = cv2.inRange(hsv,lower_yellow,upper_yellow)

#morphological opening
mask = cv2.erode(mask,kernel,iterations=2)
mask = cv2.dilate(mask,kernel,iterations=2)

#morphological closing
mask = cv2.dilate(mask,kernel,iterations=2)
mask = cv2.erode(mask,kernel,iterations=2)

#Detect contours from the mask
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
	cv2.CHAIN_APPROX_SIMPLE)[-2]

if(len(cnts) > 0):
    #Contour with greatest area
    c = max(cnts,key=cv2.contourArea)
    #Radius and center pixel coordinate of the largest contour
    ((x,y),radius) = cv2.minEnclosingCircle(c)

    if radius > 5:
        #Draw an enclosing circle
        cv2.circle(frame,(int(x), int(y)), int(radius),(0, 255, 255), 2)

        #Draw a line from the center of the frame to the center of the contour
        cv2.line(frame,(320,240),(int(x), int(y)),(0, 0, 255), 1)
        #Reference line
        cv2.line(frame,(320,0),(320,480),(0,255,0),1)

        radius = int(radius)

        #distance of the 'x' coordinate from the center of the frame
        #wdith of frame is 640, hence 320
        length = 320-(int(x))

        #write distance and radius to Arduino through Serial Communication
        if int(y) < 210:
            ser.write(1)
            print (1)
            time.sleep(1)
        if int(y) > 210:
            ser.write(2)
            print (2)
            time.sleep(1)
        
        
        

#display the image
cv2.imshow('frame',frame)
#Mask image
cv2.imshow('mask',mask)
#Quit if user presses 'q'
if cv2.waitKey(30) & 0xFF == ord('q'):
    break

#Release the capture
cap.release()
cv2.destroyAllWindows()

Arduino code

/*
Stepper Motor Control - one revolution

This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.

The motor should revolve one revolution in one direction, then
one revolution in the other direction.

Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe

*/

#include <Stepper.h>
#define motorSteps 200
Stepper myStepper(motorSteps, 3, 4, 2, 5);

void setup() {
myStepper.setSpeed(60);
Serial.begin(9600);
}

void loop() {

char ch;
if (Serial.available() > 0)
{
ch = Serial.read();
if (ch == '1')
{
myStepper.step(200);
}
else if (ch == '2')
{
myStepper.step(-200);
}
Serial.read();
}
}

Hello,

and to the forum.

Do yourself a favour and please read How to get the best out of this forum and modify your post accordingly (including code tags and necessary documentation for your ask).

Start by getting a simple sketch working on the Arduino that does nothing but

receive and print characters

sent your Python program, or a simpler version indeed of that side of the communication.

Just the characters. When you have that reliably functioning it will be much easier to add the "real" stuff those chars are destined to control.

Divide and conquer.

a7

Yes, I could some how manage this:
Please find the final working code

Python:

#Developed by Vikrant Fernandes

import numpy as np

import cv2

import serial

import time

#Serial object for communication with Arduino

ser = serial.Serial('/dev/ttyACM0')

#Capture from external USB webcam instead of the in-built webcam (shitty quality)

cap = cv2.VideoCapture(0)

#kernel window for morphological operations

kernel = np.ones((5,5),np.uint8)

#resize the capture window to 640 x 480

ret = cap.set(3,640)

ret = cap.set(4,480)

#upper and lower limits for the color yellow in HSV color space

lower_yellow = np.array([20,100,100])

upper_yellow = np.array([30,255,255])

#begin capture

while(True):

ret, frame = cap.read()

#Smooth the frame

frame = cv2.GaussianBlur(frame,(11,11),0)

#Convert to HSV color space

hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

#Mask to extract just the yellow pixels

mask = cv2.inRange(hsv,lower_yellow,upper_yellow)

#morphological opening

mask = cv2.erode(mask,kernel,iterations=2)

mask = cv2.dilate(mask,kernel,iterations=2)

#morphological closing

mask = cv2.dilate(mask,kernel,iterations=2)

mask = cv2.erode(mask,kernel,iterations=2)

#Detect contours from the mask

cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,

cv2.CHAIN_APPROX_SIMPLE)[-2]

if(len(cnts) > 0):

#Contour with greatest area

c = max(cnts,key=cv2.contourArea)

#Radius and center pixel coordinate of the largest contour

((x,y),radius) = cv2.minEnclosingCircle(c)

if radius > 5:

#Draw an enclosing circle

cv2.circle(frame,(int(x), int(y)), int(radius),(0, 255, 255), 2)

#Draw a line from the center of the frame to the center of the contour

cv2.line(frame,(320,240),(int(x), int(y)),(0, 0, 255), 1)

#Reference line

cv2.line(frame,(320,0),(320,480),(0,255,0),1)

radius = int(radius)

#distance of the 'x' coordinate from the center of the frame

#wdith of frame is 640, hence 320

length = 320-(int(x))

#write distance and radius to Arduino through Serial Communication

if int(y) < 210:

ser.write(b'1')

print (1)

time.sleep(1)

if int(y) > 210:

ser.write(b'2')

print (2)

time.sleep(1)

#display the image

cv2.imshow('frame',frame)

#Mask image

cv2.imshow('mask',mask)

#Quit if user presses 'q'

if cv2.waitKey(30) & 0xFF == ord('q'):

break

#Release the capture

cap.release()

cv2.destroyAllWindows()

Arduino code
/*
Stepper Motor Control - one revolution

This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.

The motor should revolve one revolution in one direction, then
one revolution in the other direction.

Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe

*/

#include <Stepper.h>
#define motorSteps 2000
Stepper myStepper(motorSteps, 3, 4, 2, 5);
int incomingByte = 0; // for incoming serial data

void setup() {
myStepper.setSpeed(60);
Serial.begin(9600);
}

void loop() {

if (Serial.available() > 0)
{
// read the incoming byte:
incomingByte = Serial.read();

if (incomingByte == '1')
{
myStepper.step(2000);
}
else if (incomingByte == '2')
{
myStepper.step(-2000);
}
Serial.read();
}
}

The code tracks the color and moves the stepper motor clockwise and counter clockwise and can be used for actuators or camera sliders

please for the second time, edit all your posts, select the code part and press the </> icon in the tool bar to mark it as code. It’s barely readable as it stands. (also make sure you indented the code in the IDE before copying, that’s done by pressing ctrlT on a PC or cmdT on a Mac)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.