problem with receiving new data through serial port

Hello,
I'm using python program to do image processing and calculating the degrees that the motors should moves and send these data to the arduino and it works. However the data is not changing , the motors keep moving to the first location. I was using arduino uno and I tried to restart the arduino at the end of the loop by pushing the switch '' I know that I can use the REST pin to restart it but I was just checking'' and it works fine, I got the new data by restarting the arduino

Now I'm using arduino mega and If i push the switch to rest the arduino it stop moving '' it's not getting any data'' until I restart the python program then it received the new data and star working.

why I'm not getting the same results as arduino uno .. I can't restarting python program because it takes some time to run and it should not work like that

any idea to get the new data ?

here is my arduino and python code

import cv2
import numpy as np
from numpy import *
import serial
import struct
import time


ARM_Y_MAX = 350
ARM_X_MAX = 700
RESCALE_FACTOR = 0.5



cap = cv2.VideoCapture(1)
cap.set(3, int(1280*RESCALE_FACTOR))
cap.set(4, int(720*RESCALE_FACTOR))



for i in range(15):
    _, frame = cap.read()

#r = cv2.selectROI(frame)






arduino = serial.Serial('COM8', 9600)
time.sleep(2)

while 1:
    _, frame = cap.read()

    img_crop = frame[int(50):int(50+239), int(78):int(78+478)]

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

    lower_red = np.array([0, 80, 50])
    upper_red = np.array([30, 255, 255])

    mask = cv2.inRange(hsv, lower_red, upper_red)
    res = cv2.bitwise_and(img_crop, img_crop, mask = mask)
    blur = cv2.GaussianBlur(res, (15, 15), 0)
    cv2.imshow('Gaussian Blurring', blur)

    _, puck = cv2.threshold(blur, 70, 255, cv2.THRESH_BINARY)
    cv2.imshow('Puck', puck)
    cv2.imshow('frame', frame)


    xs = np.where(puck != 0)[1]
    ys = np.where(puck != 0)[0]

    xstd = np.std(xs)
    ystd = np.std(ys)

    x_init_avg = np.mean(xs)
    y_init_avg = np.mean(ys)

    # possibly if std is too high, we can consider that we have a problem?

    xs = [x for x in xs if x <= x_init_avg+xstd or x >= x_init_avg-xstd]
    ys = [y for y in ys if y <= y_init_avg+xstd or y >= y_init_avg-xstd]
    xavg = np.mean(xs)
    yavg = np.mean(ys)

    cropped_height, cropped_width, channels = img_crop.shape

    puck_x = xavg/cropped_width*100
    puck_y = yavg/cropped_height*100


    desired_arm_x = ((puck_x/100.0)*(ARM_X_MAX*2))-ARM_X_MAX
    desired_arm_y = ARM_Y_MAX*2 - ((puck_y/100.0)*(ARM_Y_MAX*2))



    px = desired_arm_x
    py = desired_arm_y



    z=180
    a1= 250-z
    a2 = 320
    a3 = 400



    theta1 = arctan(px/py) 
    theta1 = rad2deg(theta1)




    r1=sqrt(px**2 + py**2)
    r2=sqrt(r1**2 + a1**2)

    phi1=arctan(r1/a1)
    phi2=arccos((a2**2+r2**2-a3**2)/(2*r2*a2))
    theta2= pi - (phi1 - phi2)

    phi3=arccos((a2**2+a3**2-r2**2)/(2*a2*a3))
    theta3= (pi- phi3)

    theta2 = rad2deg(theta2)
    theta3 = rad2deg(theta3)


            
    if theta1 > 0 :
       theta1 = int(theta1)
       d=0



    if theta1 < 0 :
       theta1 = int(abs(theta1))
       d=1


    if 255 > theta2 > 0 :
            
       arduino.write(struct.pack('>BBBB',d,theta1,int(theta2),int(theta3)))
       
       print('theta_1: ', theta1)
       print('theta_2: ', theta2)
       print('theta_3: ', theta3)








    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

Thank you

test.ino (6.17 KB)

Thank you

That's premature. First, we are going to blast you for failing to read the stickies at the top of the forum, and then posting your code correctly.

When you fix that blunder, I'll consider reading your code.

sorry for that
I'll post a new one

Please also post your Arduino code in your next Reply so we don't have to download the file.

This simple Python - Arduino demo may give you some ideas.

Personally I prefer to send data as text unless the higher performance by sending binary data is essential. Sending data s text makes debugging much easier.

I also like to have code in my Python programs so they can display any debug messages sent from the Arduino.

...R

Robin2:
Please also post your Arduino code in your next Reply so we don't have to download the file.

This simple Python - Arduino demo may give you some ideas.

Personally I prefer to send data as text unless the higher performance by sending binary data is essential. Sending data s text makes debugging much easier.

I also like to have code in my Python programs so they can display any debug messages sent from the Arduino.

...R

Thank you ,, I will look at your code

This is the arduino code

// Include the Servo library 
#include <Servo.h> 
#include <EEPROM.h>

// defines pins numbers
const int step1 = 21; 
const int dir1 = 20; 
const int en1 = 19;

const int step2 = 17; 
const int dir2 = 16; 
const int en2 = 15;

const int step3 = 2; 
const int dir3 = 3; 
const int en3 = 4;

const int step4 = 8; 
const int dir4 = 9; 
const int en4 = 10;

// Declare the Servo pin 
int servo1 = 22; 
int servo2 = 24; 
int servo3 = 26; 
int servo4 = 28; 
int servo5 = 30;

 
// Create a servo object 
Servo Servo1; 
Servo Servo2;
Servo Servo3;
Servo Servo4;
Servo Servo5;


int incoming[3];
int direct1;
int theta1;
int theta2;
int theta3;
int mov1;

int theta1box=40;
int theta2box=105;
int theta3box=30;
int H2;



void setup() {

  Serial.begin(9600);
  
  // Sets the two pins as Outputs
  pinMode(step1,OUTPUT); 
  pinMode(dir1,OUTPUT);
  pinMode(en1,OUTPUT);

  pinMode(step2,OUTPUT); 
  pinMode(dir2,OUTPUT);
  pinMode(en2,OUTPUT);

  pinMode(step3,OUTPUT); 
  pinMode(dir3,OUTPUT);
  pinMode(en3,OUTPUT);

  pinMode(step4,OUTPUT); 
  pinMode(dir4,OUTPUT);
  pinMode(en4,OUTPUT);

  digitalWrite(en1,LOW);
  digitalWrite(en2,LOW);
  digitalWrite(en3,LOW);
  digitalWrite(en4,LOW);




   // We need to attach the servo to the used pin number 
   Servo1.attach(servo1); 
   Servo2.attach(servo2); 
   Servo3.attach(servo3); 
   Servo4.attach(servo4); 
   Servo5.attach(servo5);



}
void loop() {

   Servo1.write(60); 
   Servo2.write(180); 
   Servo3.write(180); 
   Servo4.write(180); 
   Servo5.write(0); 

    if (Serial.available() >= 4){
    // fill array
    for (int i = 0; i < 4; i++){             // 2= number of values receved at the end it should be 6
      incoming[i] = Serial.read();
    }
    
    // use the values
   
    direct1= incoming[0];
    theta1= incoming[1];
    theta2= incoming[2];
    theta3= incoming[3];

    


    

    MoveToObject();
    delay(500);
    GrapObject();
    delay(200);
    PutObject();
    delay(500);
    reference();



    theta1=0;
    theta2=0;
    theta3=0;
    incoming[0] = 0 ;
    incoming[1] = 0 ;
    incoming[2] = 0 ;
    incoming[3] = 0 ;

delay(1000);



      

}


}



void MoveToObject(){

     if ( direct1 == 0){
       digitalWrite(dir1,LOW);
  
  }
  
      if ( direct1 == 1){
       digitalWrite(dir1,HIGH);
       theta1=abs(theta1);
  }


        for(unsigned long x = 0; x < theta1*525L; x++) {
        digitalWrite(step1,HIGH); 
        delayMicroseconds(70); 
        digitalWrite(step1,LOW); 
        delayMicroseconds(70); 
  }
  
      digitalWrite(dir4,HIGH);
      for(unsigned long x = 0; x < theta3*2000L; x++) {
        digitalWrite(step4,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step4,LOW); 
        delayMicroseconds(20); 

        }
        



      digitalWrite(dir2,HIGH); 
      for(unsigned long x = 0; x < theta2*2350L; x++) {
        digitalWrite(step2,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step2,LOW); 
        delayMicroseconds(20); 
    }
}


void GrapObject(){

  // Close fingers, then.....

   Servo1.write(180); 
   Servo2.write(0); 
   Servo3.write(0); 
   Servo4.write(0); 
   Servo5.write(180); 



H2=40;

          digitalWrite(dir2,LOW); 
      for(unsigned long x = 0; x < H2*2450L; x++) {
        digitalWrite(step2,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step2,LOW); 
        delayMicroseconds(20); 

}


        digitalWrite(dir3,HIGH);
      for(unsigned long x = 0; x < 90*2000L; x++) {
        digitalWrite(step3,HIGH); 
        delayMicroseconds(18); 
        digitalWrite(step3,LOW); 
        delayMicroseconds(18); 

        }
  
  
}


void PutObject(){

if  (direct1 == 1){
  theta1= -theta1;
}

   theta1 = theta1box - theta1;
   theta2 = theta2box - (theta2 - H2);
   theta3 = theta3box - theta3;


        if ( theta1 > 0){
       digitalWrite(dir1,LOW); 
  }
      if ( theta1 < 0){
       digitalWrite(dir1,HIGH);
       theta1=abs(theta1);
  }




        if ( theta2 > 0){
       digitalWrite(dir2,HIGH); 
  }
      if ( theta2 < 0){
       digitalWrite(dir2,LOW);
       theta2=abs(theta2);
  }




          if ( theta3 > 0){
       digitalWrite(dir4,HIGH);  
  }
      if ( theta3 < 0){
       digitalWrite(dir4,LOW);
       theta3=abs(theta3);
  }


        for(unsigned long x = 0; x < theta1*525L; x++) {
        digitalWrite(step1,HIGH); 
        delayMicroseconds(70); 
        digitalWrite(step1,LOW); 
        delayMicroseconds(70); 
  }


          digitalWrite(dir3,LOW);
      for(unsigned long x = 0; x < 90*2000L; x++) {
        digitalWrite(step3,HIGH); 
        delayMicroseconds(18); 
        digitalWrite(step3,LOW); 
        delayMicroseconds(18); 

        }
  

      for(unsigned long x = 0; x < theta3*2000L; x++) {
        digitalWrite(step4,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step4,LOW); 
        delayMicroseconds(20); 

        }
        
      for(unsigned long x = 0; x < theta2*2350L; x++) {
        digitalWrite(step2,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step2,LOW); 
        delayMicroseconds(20); 
    }    




    // open fingers

   Servo1.write(60); 
   Servo2.write(180); 
   Servo3.write(180); 
   Servo4.write(180); 
   Servo5.write(0); 
}


void reference(){

       digitalWrite(dir1,HIGH);
       digitalWrite(dir2,LOW);
       digitalWrite(dir4,LOW);

        for(unsigned long x = 0; x < theta2box*2750L; x++) {
        digitalWrite(step2,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step2,LOW); 
        delayMicroseconds(20); 
    }

          for(unsigned long x = 0; x < theta3box*2000L; x++) {
        digitalWrite(step4,HIGH); 
        delayMicroseconds(20); 
        digitalWrite(step4,LOW); 
        delayMicroseconds(20); 
        }

          for(unsigned long x = 0; x < theta1box*525L; x++) {
        digitalWrite(step1,HIGH); 
        delayMicroseconds(70); 
        digitalWrite(step1,LOW); 
        delayMicroseconds(70); 
  }


  
}

Don't do this...

    if (Serial.available() >= 4){

If one character is missed then this never gets back in sync with the first character in a block of data.

Look up Serial Input Basics to see a better method.