Python - Problema de comunicación Python-Arduino

 
Vista:
sin imagen de perfil
Val: 1
Ha disminuido su posición en 16 puestos en Python (en relación al último mes)
Gráfica de Python

Problema de comunicación Python-Arduino

Publicado por Leonardo (1 intervención) el 17/07/2019 06:01:55
Hola!
Les cuento, estoy haciendo un programa que tiene como fin que un servomotor se mueva a el mismo angulo que un objeto detectado por una webcam utilizando la libreria openCv
La cosa es que haciendo pruebas con un programa simple para ingresar el angulo manualmente si funciona, pero al utilizar mi programa con detección de movimiento no.
¿Que podría estar pasando?

Anexo los códigos

Programa en Arduino:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <Servo.h>
String pos;
int e = 0;
Servo servo1;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  servo1.attach(9);
}
 
void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()>=1){
    pos=Serial.readString();
    e = pos.toInt();
    servo1.write(e);
    //delay(1);
 
  }
}

Programa para colocar el angulo manualmente

1
2
3
4
5
6
7
8
9
10
import serial
ser=serial.Serial('COM4',9600)
print ('Bienvenido!')
while True:
    entrada= input("Introduce el angulo: ")
    print ('///------------------------------------------------------///')
 
    if entrada == 'salir':
        break
    ser.write(str(entrada).encode())

Programa con detección de movimiento

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# De# Detecta objetos verdes, elimina el ruido y busca su centro
 
import cv2
import numpy as np
import math
import serial
import time
 
# Iniciamos la camara --------------------------------------------------------------
# DIMENCIONES DE LA CAMRA SON APROXIMADAMENTE 640 en x por 480 en y
captura = cv2.VideoCapture(0)
 
# Definimos varaible para iniciar la comunuicacion serial (dieferente en linux) -----
ser = serial.Serial('COM4', 9600)
 
# Variable para salir del ciclo -----------------------------------------------------
salir = True
 
# Definimios funciones para obtener las coordenadas ---------------------------------
def coord (cam_val, valor):
    plano = cam_val / 2
    coord = plano - valor
    return coord
# !!!!! ESTA FUNCION PRESENTA UN ERROR - NO MIDE DEBAJO DE 60 GRADOS
def angulo (vect_x, vect_y):
    if vect_x and vect_y != 0:
 
        if vect_x < 0:
            ang_rad = math.atan (vect_y / abs(vect_x))
            ang_grad = abs (round (math.degrees(ang_rad)))
            return abs (ang_grad - 90) + 90
            #return ang_grad + 90 
        else:
            ang_rad = math.atan (vect_y / vect_x)
            ang_grad = abs (round (math.degrees(ang_rad)))
            return ang_grad
    else:
        ang_grad = 90
        return ang_grad
 
# iniciamos el ciclo ----------------------------------------------------------------
while salir:
 
# Capturamos una imagen y la convertimos de RGB -> HSV ------------------------------
    _, imagen = captura.read()
    hsv = cv2.cvtColor(imagen, cv2.COLOR_BGR2HSV)
 
# Establecemos el rango de colores que vamos a detectar en RGB -----------------------
    verde_bajos = np.array([49,50,50], dtype=np.uint8)
    verde_altos = np.array([80, 255, 255], dtype=np.uint8)
 
# Creamos una mascara con solo los pixeles dentro del rango de verdes -----------------
    mask = cv2.inRange(hsv, verde_bajos, verde_altos)
 
# Encontrar el area de los objetos que detecta la camara -----------------------------
    moments = cv2.moments(mask)
    area = moments['m00']
 
# Creamos un condicional con respecto del area del objeto --------------------------
    if(area > 50000):
 
# Buscamos el centro x, y del objeto -------------------------------------------------
        x = int(moments['m10']/moments['m00'])
        y = int(moments['m01']/moments['m00'])
# Creamos las coordenadas en froma de plano cartesiano -------------------------------
        coord_x = coord (640, x)
        coord_y =  abs(y - 480)
# Obtenemos el angulo de inclinacion (usamos y o coord_y) -----------------------------
        ang_beta = angulo (coord_x, coord_y)
 
# Imprimimos la informacion en pantalla ----------------------------------------------
        #print ('Punto x =', coord (640, x))
        #print ('Punto y =', y)
        #print ('Angulo =', ang_beta)
        ser.write (str(ang_beta).encode())
 
        info = ' Objeto, x: {}, y: {}, angulo: {}°'.format ( coord_x, y, ang_beta)
        print (info)
 
# ELEMENTOS DE INTERFAZ ----------------------------------------------------------------------
 
# Dibujamos una marca en el centro del objeto --------------------------------------------
        cv2.rectangle(imagen, (x, y), (x+2, y+2),(0,0,255), 2)
# Creamos marcas de referencia en la pantalla de la camara -----------------------------------
        cv2.line(imagen, (0, 240), (680, 240), (0, 200, 0), 1)  #Linea horizonatal media
        cv2.line(imagen, (320, 0), (320, 480), (0, 200, 0), 1)  #Linea vertical media
        cv2.line(imagen, (0, 0), (320, 480), (0, 200, 0), 1)    #Linea vert_sup_izq - med_abajo
        cv2.line(imagen, (320, 480), (640, 0), (0, 200, 0), 1)  #Linea med_abajo - vert_sup_der
        cv2.line(imagen, (160, 220), (160, 260), (0, 200, 0), 1)#Linea_med -x
        cv2.line(imagen, (240, 230), (240, 250), (0, 200, 0), 1)
        cv2.line(imagen, (480, 220), (480, 260), (0, 200, 0), 1)#Linea_med +x
        cv2.line(imagen, (400, 230), (400, 250), (0, 200, 0), 1)
        cv2.line(imagen, (300, 120), (340, 120), (0, 200, 0), 1)#Linea_med +y
        cv2.line(imagen, (310, 180), (330, 180), (0, 200, 0), 1)
        cv2.line(imagen, (300, 380), (340, 380), (0, 200, 0), 1)#Linea_med -y
        cv2.line(imagen, (310, 320), (330, 320), (0, 200, 0), 1)
 
# Creamos marcas de referencia en la pantalla de la mascara -----------------------------------
        cv2.line(mask, (0, 240), (680, 240), (255,255,255), 1)  #Linea horizonatal media
        cv2.line(mask, (320, 0), (320, 480), (255, 255, 255), 1)#Linea vertical media
        cv2.line(mask, (0, 480), (640, 480), (255,255,255), 1)  #Linea inferior
        cv2.line(mask, (0, 0), (320, 480), (255,255,255), 1)    #Linea vert_sup_izq - med_abajo
        cv2.line(mask, (320, 480), (640, 0), (255,255,255), 1)  #Linea med_abajo - vert_sup_der
        cv2.line(mask, (160, 220), (160, 260), (255,255,255), 1)#Linea_med -x
        cv2.line(mask, (240, 230), (240, 250), (255,255,255), 1)
        cv2.line(mask, (480, 220), (480, 260), (255,255,255), 1)#Linea_med +x
        cv2.line(mask, (400, 230), (400, 250), (255,255,255), 1)
        cv2.line(mask, (300, 120), (340, 120), (255,255,255), 1)#Linea_med +y
        cv2.line(mask, (310, 180), (330, 180), (255,255,255), 1)
        cv2.line(mask, (300, 380), (340, 380), (255,255,255), 1)#Linea_med -y
        cv2.line(mask, (310, 320), (330, 320), (255,255,255), 1)
# Creamos un texto que siga al objeto en pantalla
        img_info = 'Objeto  ( %s, %s)'%(coord_x, coord_y)
 
        cv2.putText(imagen, img_info, (x - 100 , y + 30), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (255,255,0), lineType=cv2.LINE_AA)
# ---------------------------------------------------------------------------------------
 
# Mostramos la imagen original con la marca del centro y la mascara --------------------------
    cv2.imshow('mask', mask)
    cv2.imshow('Camara', imagen)
 
    if cv2.waitKey(1) & 0xFF == ord('e'):
         salir = False
 
cv2.destroyAllWindows()
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 24
Ha disminuido su posición en 3 puestos en Python (en relación al último mes)
Gráfica de Python

Problema de comunicación Python-Arduino

Publicado por Johannes (9 intervenciones) el 14/08/2019 23:13:19
Hola Leonardo. Yo he tenido el mismo problema de comunicación entre Python y Arduino utilizando la librería serial de Python, te recomiendo que nstales la librería de pyfirmata y cartes en tu Arduino el módulo de firmara Standard Qué viene como parte de la librería estándar de Arduino y no deberías tener problemas. Te iba a adjuntar un manual pero no pude desde mi celular pero en Google encuentras muchos sobre pyfirmata.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Problema de comunicación Python-Arduino

Publicado por Gustavo Camilo Carcamo Pedrozo (1 intervención) el 15/12/2021 22:04:17
Hola, yo tenía el mismo problema también, y busqué por todas partes a ver en donde podría estar el error, al final me di cuenta que era porque hay que dejarle un tiempo de más o menos un segundo entre envío de un dato y el siguiente, esto más que todo pasa cuando el envío del dato se realiza dentro de un loop y envia los datos de manera demasiado rápida, sin embargo en sí el por qué pasa esto si no estoy seguro, pero de arduino a python no pone problema, el problema es de python a arduino. Si alguien sabe por qué ocurre eso que también me diga por favor.
En conclusión usa un pequeño tiempo de espera con la librería time, un time.sleep(1) especificamente. Espero haber ayudado.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar