Найти - Пользователи
Полная версия: Python + Arduino (Управление Servo+Arduino из Python+OpenCV)
Начало » Python для экспертов » Python + Arduino (Управление Servo+Arduino из Python+OpenCV)
1 2 3
xam1816
gps38region
В том то и дело что мониторить нечем
скачай arduino ide,
здесь почитай если не понятно

в питоне просто принтами выводи что отправляшь.
Иначе просто будешь тыкать и не понимать что в какой момент передается
gps38region
xam1816
скачай arduino ide,
Arduino IDE я использую, все дело в том что когда в нем монитор порта включен то порт занят и питон уже не может открыть СОМ порт.
С питоном так и мониторю.
Я думаю для тестов что прилетело в Ардуинг , поставить экран и на него выводить. Есть еще осцилограф….
gps38region
Еще ложка дегтя в бочку с медом….
Проверил что камера как и СОМ порт работают в монопольном режиме…
Короче говоря на текущий момент если вы хотите крутить WEB камеру в Вацапе или Вайбере и пр. То нужно 2-две камеры. Одна для трансляции, вторая для трекера….
Нужно было сразу проверить….
Но опыт связки Питона и Ардуино ВСЕ РАВНО ПОЛОЖИТЕЛЬНЫЙ !!!
Буду копать дальше…
gps38region
Вернулся к рабочему варианту

Ардуино
 #include <Servo.h>
Servo servo[2];  
void setup() {
  Serial.begin(115200);  
  servo[0].attach(7, 400, 2400);
  servo[1].attach(8, 400, 2400);
 
  servo[0].write(90); 
  servo[1].write(90); 
}
void loop() {
  
  if (Serial.available() > 0) {
    int incomingByte = Serial.read();  
    servo[0].write(incomingByte);
    servo[1].write(incomingByte);
  }
}

Питон
 import serial
import time
port = "COM8"
baudrate = 115200
arduino = serial.Serial(port, baudrate=baudrate, timeout=1)
test_data = [0,0,0, 0,30,60,90,120,150,180,150,120,90,60,30,0]
def send_data(data):
    for value in data:
        arduino.write(bytes([value]))
        time.sleep(0.2)  
send_data(test_data)

Все по одному байту отрабатывает как положено !

Пытаюсь вставить в трекер на питоне
 import time
import numpy as np
import cv2
import serial
port = "COM8"  # Replace with the appropriate COM port name
baudrate = 115200
arduino = serial.Serial(port, baudrate=baudrate, timeout=1)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
	
capture = cv2.VideoCapture(0,cv2.CAP_DSHOW)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
xi = int(capture.get(3)) # Shirina camera
cxi = int(xi/2)          # Centr X
yi = int(capture.get(4)) # Visota camera
cyi = int(yi/2)          # Centr Y
while True:
    ret, frame = capture.read()
    
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    eyes = eye_cascade.detectMultiScale(gray, 1.3, 5)
    cv2.line(frame, (cxi,0),(cxi,yi),(120,120,120),1)
    cv2.line(frame, (0,cyi),(xi,cyi),(120,120,120),1)
    current_time0 = time.time()
    for (x, y, w, h) in faces:
        frame = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
        cx=int(x+w/2)
        cy=int(y+h/2)
        dx=int(cxi-cx)
        dy=int(cyi-cy)
        ct=int(90+(cxi-cx)/8) # Send to COM port
        cv2.putText(frame, str(cxi)+'x'+str(cyi)+' '+str(cx)+'x'+str(cy)+' '+str(ct), (0, 20), cv2.FONT_HERSHEY_DUPLEX, 0.9, (0, 0, 250), 1) 
        cv2.circle(frame, (cx,cy), 5, (0, 0, 255) , -1) #-1 
        cv2.line(frame, (cxi,cyi), (cx,cy),(0, 0, 255), 3)
        # Send commands to the Arduino
        arduino.write(ct) #*********************
        #arduino.write(f"{ct}n".encode())
        time.sleep(0.3)
    cv2.imshow('From Camera', frame)
    k = cv2.waitKey(30) & 0xFF
    if k == 27:
        if arduino.is_open:
          command = 0
          arduino.write(command)
          arduino.close()
          print("Serial connection closed.")
        break
capture.release()
cv2.destroyAllWindows()

И опять траблы….
Молчит серво , Ёхарный Бабай…..
И как int , и через bytes(), и .encode()
ГЛУХО.

Притомило.
Нужен анализ что в порт летит и что прилетает….
Попробую осцилограф и экран присобачить….
xam1816
gps38region
Нужен анализ что в порт летит и что прилетает….

Убери пока все лишнее
выполни что покажет
  
import serial
import time
port = "COM8"
baudrate = 115200
try:
    arduino = serial.Serial(port, baudrate=baudrate, timeout=1)
    time.sleep(2) # подождем для верности
except serial.SerialException:
    print('ошибка подключения ардуино')
    raise
data = bytes([45, 125])
arduino.write(data)
arduino.flush()  # Очищаем буфер после отправки
# проверяем что байты ушли
if arduino.out_waiting == 0:
    print(f'отправлены данные {data}')
resp = arduino.readline().decode().strip()
if resp:
    print(f'получен ответ от ардуино: {resp}')

ардуино
  
void setup() {
    Serial.begin(115200);
}
void loop() {
    if (Serial.available() >= 2) {  // Ждем 2 байта
        int x = Serial.read();
        int y = Serial.read();
        Serial.print("Принято: ");
        Serial.print(x);
        Serial.print(", ");
        Serial.println(y);
    }
}
gps38region
xam1816
выполни что покажет
E:\pythonProject\test1>test1.py
отправлены данные b'-}'
получен ответ от ардуино: Принято: 45, 125
gps38region
На Ардуино добавил серво

 #include <Servo.h>
Servo servo[2];  
void setup() {
    Serial.begin(115200);
    servo[0].attach(7, 400, 2400);
    servo[1].attach(8, 400, 2400);
}
void loop() {
    if (Serial.available() >= 2) {  // Ждем 2 байта
        int x = Serial.read();
        int y = Serial.read();
        Serial.print("Принято: ");
        Serial.print(x);
        Serial.print(", ");
        Serial.println(y);
        servo[0].write(x);
        servo[1].write(y);
    }
}

При time.sleep(2) Углы отрабатывает, но перед поворотом новых исправленных углов перемещает в старые а потом поворачивает на те которые отправил.
При time.sleep(1.7) возврата на старые углы нет. Доворачивает как нужно.
При time.sleep(1.64) и ниже ничего не крутит…

Где-то несинхрон какой-то…..
Или инициализация СОМ порта нужна или что в этой связи пока загадка.
Все тесты живут по разному и задержки разные (с камерой задержка в 1,7 сек это не камера)
gps38region
Пока сделал управление от мышки по экрану…

 #include <Servo.h>
Servo servo[2];  
void setup() {
    Serial.begin(115200);
    servo[0].attach(7, 400, 2400);
    servo[1].attach(8, 400, 2400);
 
    //servo[0].write(0); 
    //servo[1].write(0); 
}
void loop() {
    if (Serial.available() >= 2) {  // Ждем 2 байта
        int x = Serial.read();
        int y = Serial.read();
        Serial.print("Принято: ");
        Serial.print(x);
        Serial.print(", ");
        Serial.println(y);
        servo[0].write(x);
        servo[1].write(y);
    }
}

 import numpy as np
import cv2 as cv
import serial
import time
port = "COM8"
baudrate = 115200
arduino = serial.Serial(port, baudrate=baudrate, timeout=2)
ix,iy = 0,0
# mouse callback function ######################################################################
def draw_servo(event,x,y,flags,param):
    global ix,iy
    if event == cv.EVENT_MOUSEMOVE:
        ix,iy = int(x/2),int(y/2)
        cv.rectangle(img,(0,0),(180,21),(0,0,0),-1)
        cv.putText(img, str(ix)+' '+str(iy), (0, 20), cv.FONT_HERSHEY_DUPLEX, 0.9, (0, 0, 250), 1) 
        data = bytes([ix,iy])
        arduino.write(data)
        arduino.flush()  # Очищаем буфер после отправки
img = np.zeros((360,360,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_servo)
while(1):
    cv.imshow('image',img)
    k = cv.waitKey(1) & 0xFF
    if k == 27:
        break
cv.destroyAllWindows()

Все работает без time.sleep !!!!!!!!!!!!!!!!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB