First timer need help! Python data to Arduino?

Hi everyone!
First off sorry if this kind of question comes out a lot, this is my first post on this forum and I'm new. Anyway, I'm combining Python OpenCV with an Arduino-controlled arm for an agriculture project. For context, the ESP32 Camera will be checking for seeds in a hole and transferring that data to the Arduino-controlled robot arm to move in XYZ coordinates.
I'm currently working on using the ESP32 Camera to detect the number of seeds in a hole using Python OpenCV.

These are my 2 problems :

  1. How do I transfer the output data "counting" from Python to Arduino? don't understand what function to use to transfer the "counting" data to Arduino.

These are the guides I was referring to, and they only transfer strings.

  1. Is it possible to run Python and Arduino at the same time? If not, how do I automate Python and Arduino to run and close automatically?

I'm fairly new to Python and not much of an expert in Arduino so I need help with this.:smiling_face_with_tear:
Any new guides, forums, explanations, and code would be greatly appreciated.

Thank you!

#Declaring libraries
import cv2 
import numpy as np 
import matplotlib.pyplot as plt
import serial


#Get the image
image = cv2.imread(r"C:\Users\edu\Desktop\Personal Project\Python Projects\OpenCV Datasets\Testing_10Light\6cm.jpg")


#Increase brightness and contrast of the image
brightness = 3
contrast = 2.4
image2 = cv2.addWeighted(image, contrast, np.zeros(image.shape, image.dtype), 0, brightness) 

#Sharpening image
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharpened_image = cv2.filter2D(image2, -1, kernel) 

#Make the image B&W
gray = cv2.cvtColor(sharpened_image, cv2.COLOR_BGR2GRAY) 

#Apply blur to get rid of noise
blur = cv2.GaussianBlur(gray, (11, 11), 0)

#Detect the edges of the object  
canny = cv2.Canny(blur, 30, 150, 3)

#Connect the edges and fill in the gaps of unfinished edges
dilated = cv2.dilate(canny, (1, 1), iterations=0) 


#Find the contours in the image 
(cnt, hierarchy) = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 


rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 
cv2.drawContours(rgb, cnt, -1, (0, 255, 0), 2) 

counting = len(cnt)

#Send the output to Arduino
ser = serial.Serial('COM6', 9600) #Arduino PORT at 9600 baud rate
ser.write(str(counting).encode())

print("number of seeds : ", counting)

#Display
plt.imshow(sharpened_image)
plt.show()
plt.imshow(rgb)
plt.show()

ser.close() # Close the serial port
     

This is the original code combining ESP32 Camera with Arduino which I haven't connected yet, but here is just a reference.

import cv2
import numpy as np
import urllib.request
import matplotlib.pyplot as plt
import serial

URL = 'http://194.18.15.175'
cap = cv2.VideoCapture(URL + ":81/stream")

while True:
    success, img = cap.read()

    #Sharpening image
    kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
    sharp_img = cv2.filter2D(img, -1, kernel) 

    # Convert to grayscale
    gray_img = cv2.cvtColor(sharp_img, cv2.COLOR_BGR2GRAY)

    #Apply blur to get rid of noise
    blur = cv2.GaussianBlur(gray_img, (11, 11), 0)

    #Detect the edges of the object  
    canny = cv2.Canny(blur, 30, 150, 3)

    #Connect the edges and fill in the gaps of unfinished edges
    dilated = cv2.dilate(canny, (1, 1), iterations=0) 

    #Find the contours in the image 
    (cnt, hierarchy) = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

    rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    cv2.drawContours(rgb, cnt, -1, (0, 255, 0), 2) 

    #len = return number of items
    #cnt = count number of items
    counting = len(cnt)
    print("number of seeds : ", counting)

    #Send the output to Arduino
    ser = serial.Serial('COM6', 9600) #Arduino PORT 
    ser.write(str(counting).encode())

    #Display live feed showing contours of seeds
    cv2.imshow("CAM", dilated)
    cv2.waitKey(1)

cap.release()
cv2.destroyAllWindows()

Simple Arduino(COM6) code to light up PIN13

const int ledPin13 = 10;

void setup() {
 pinMode(ledPin13, OUTPUT); // Set pin as output
 Serial.begin(9600); // Begin serial communication at 9600 bps
}

void loop() 
{
 if (Serial.available() > 0) { // If data is available to read
    int seedCount = Serial.parseInt(); // Read the incoming data as integer

    if (seedCount > 3) 
    { // If seed count is greater than 3
      Serial.print("TOO MUCH");
      digitalWrite(ledPin13, HIGH); // Turn the LED on
      delay(5000);
    } 
    else if (seedCount == 3)
    {
      digitalWrite(ledPin13, LOW); // Turn the LED off
      Serial.print("GOOD");
    }
    else
    {
      Serial.print("ERROR");
    }
 }
}

Hi @afiqsu

welcome to the Arduino-Forum.
Well done posting the code in code-sections in your very first post.

OpenCV requires a lot of computation power. What is the device that is running

?

Again: On what device are you running Python OpenCV?
and what do you mean by "run Arduino" ?

What do you mean with

???

closing the python-"window" on your computer?
and how would ever "closing" arduino look like???

Well even the strings can be converted to numbers beeing integer or float.

best regards Stefan

Transferring numbers as strings is less efficient than using binary, it's true. But is efficiency of high importance here, and if so, why?

Transferring numbers as strings has some advantages. If you want to look at the data that is being transferred, for debugging purposes for example, then the numbers will be readable to humans. They won't if they are in binary format. In binary format, you have the problem that the sender and receiver may not have the same endianness. One might be big-endian and the other little-endian.

I also do not understand what you are asking.

If you mean run Python and the Arduino IDE on a pc/laptop/RPi then yes no problem.

If you mean run python and C/C++ Arduino code on an Arduino, then no.

If you want to send numbers in binary format for speed reasons, why use such a very slow baud rate?

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