Hello, I am having a problem with my servo control. I am currently making a hand following servo using OpenCV and Pyfirmata. Right now it works but it's pretty unstable. The servo movement is working fine and it's following my hands but after while the servo just stop working when I'm testing it. I'm pretty new to arduino and electronics stuff so I would be very appreciated if someone have any solutions. Thanks in advance
import time
import cv2
import cvzone
import math
from pyfirmata import Arduino, SERVO
#Size 640 x 480
from cvzone.HandTrackingModule import HandDetector
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FPS, 20)
cap.set(3, 640)
cap.set(4, 480)
detector = HandDetector(staticMode=False, maxHands=1, modelComplexity=1, detectionCon=0.5, minTrackCon=0.5)
pTime = 0
lenght_r = 0
angle_pitch = 0
angle_yaw = 90
board = Arduino("COM4")
pin_9 = board.digital[9]
pin_9.mode = SERVO
def writeAngle(pin, angle):
pin.write(angle)
time.sleep(0.03)
while True:
success, img = cap.read()
height, width, _ = img.shape
img_center_x = width // 2
img_center_y = height // 2
img_center = [img_center_x, img_center_y]
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
hands, img = detector.findHands(img, draw=False, flipType=True)
if hands:
hand = hands[0]
lmList = hand["lmList"]
bbox = hand["bbox"]
center = hand['center']
handType = hand["type"]
length, info, img = detector.findDistance(lmList[4][0:2], lmList[8][0:2], img, color=(0, 255, 0),
scale=8)
hand_size = max(bbox[2], bbox[3])
lenght_r = round(length / hand_size, 1)
cv2.circle(img, center, 5, (255, 0, 0), cv2.FILLED)
cv2.line(img, center, (img_center_x, img_center_y), (255 ,0, 255), 2)
if lenght_r < 0.2:
lenght_r = 1
else:
lenght_r = 0
offset_x = center[0] - img_center_x
offset_y = img_center_y - center[1]
angle_yaw = int(((offset_x - (-320)) / (320 - (-320))) * (180- 0) + 0)
angle_pitch = int(((offset_y - (-240)) / (240 - (-240))) * (60 - 0) + 0)
print(angle_yaw)
#pin_9.write(angle_yaw)
writeAngle(pin_9, angle_yaw)
else:
writeAngle(pin_9, angle_yaw)
cv2.circle(img, (img_center_x, img_center_y), 5, (255, 0, 0), cv2.FILLED)
cv2.putText(img, f'FPS : {int(fps)}', (20, 40), cv2.FONT_HERSHEY_PLAIN, 1, (255, 0, 0), 2)
cv2.putText(img, "Fire: " + str(lenght_r), (20, 60), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0), 2)
cv2.putText(img, "Angle Yaw : " + str(angle_yaw), (20, 80), cv2.FONT_HERSHEY_PLAIN, 1, (255, 0, 255), 2)
cv2.putText(img, "Angle Pitch : " + str(angle_pitch), (20, 100), cv2.FONT_HERSHEY_PLAIN, 1, (255, 0, 255), 2)
cv2.line(img, (0, img_center_y), (width, img_center_y), (0, 255, 0), 1) # Horizontal line
cv2.line(img, (img_center_x, 0), (img_center_x, height), (0, 255, 0), 1) # Vertical line
resized_img = cv2.resize(img, (960, 720))
cv2.imshow("Tracked", resized_img)
#received_data = arduino.readline().decode('utf-8').strip()
#print("Received: " + received_data)
key = cv2.waitKey(1)
if key == ord('q'):
break
cap.release()
cv2.destroyAllWindows()