Genial ejemplo, gracias por compartirlo, para los que anden justos de tiempo os dejo el código en este comentario, esta sin probar y con mis aclaraciones en lenguaje poco formal, puede haber también erratas aunque lo he repasado ya varias veces. Un saludo //declaracion de variables unsigned int order_angle=0; char incomingByte; //Usado para la lectura serial long count=0; //Contador de pulsos de pwm, los cambios emitidos por el encoder int error; int actual_angle; int pwm; int flag=0; int x=4; //pines para el control del giro int y=5; //pines para el control del giro int salida; unsigned long timep, time, etime; //etime==evaluacionTiempo boolean A,B; byte state, statep; //statep==statePasado void setup() { Serial.begin(9600); //Inicializa la comunicacion serial pinMode(2,INPUT); //Canal A del encoder pinMode(3,INPUT); //Canal B del encoder pinMode(x,OUTPUT); // IN1 pinMode(y,OUTPUT); // IN2 pinMode(11,OUTPUT); // ENA ENABLE???Tiene pinta attachInterrupt(0,Achange,CHANGE); //Genera una interrupccion al detectar cambios en el canal A del encoder attachInterrupt(1,Bchange,CHANGE); //Genera una interrupccion al detectar cambios en el canal B del encoder timep=micros(); A = digitalRead(2); //Lectura del canal A B = digitalRead(3); //Lectura del canal B //Declaracion de los estados posibles entre la lectura de los canales A y B del Encoder if((A==HIGH)&&(B==HIGH)) statep=1; if((A==HIGH)&&(B==LOW)) statep=2; if((A==LOW)&&(B==LOW)) statep=3; if((A==LOW)&&(B==HIGH)) statep=4; } void loop() { time = micros(); etime = time - timep; /*********************************************************************** * TODO ESTO ES PARA COGER MAS DE UN CARACTER DEL PUERTO SERIAL!!! ***********************************************************************/ if (Serial.available() > 0) //Primero pregunta si hay algo en el serial { //Este bucle permite capturar mas de un numero en el serial!!!! Porque antes solo podian uno order_angle = 0; //Descarta el valor anterior de order_angle while(1) { // obliga a entrar a un ciclo hasta que se reciba una incomingByte = Serial.read(); if (incomingByte == '/n') break; //Salir del ciclo cuando haya un salto de linea if (incomingByte == -1) continue; //Si no hay caracter... order_angle *= 10; //Multiplica "order_angle" por 10, lo que lo desplaza hacia la izquierda en decimales // Convierte ASCII a valor entero order_angle = ((incomingByte - 48) + order_angle); } } actual_angle=map(count,0,5284,0,360); // Transformamos lo acumulado en grados /*****************************************************************************/ /*********************************************************************** * IMPLEMENTACION EN BUCLE CERRADO!!!! * Calculamos el error como el absoluto de la resta entre la posicion actual * la posicion buscada y tras esto mapeamos el error en una variable que la * introduciremos mas tarde para controlar el ciclo de trabajo, luego cuanto * mas cercano este menor sera el valor del mapeo y a su vez menor ciclo de trabajo * hasta llegar a 0. ***********************************************************************/ error= abs(order_angle-actual_angle); // Calculo del error (abs == absoluto (siempre en positivo)) pwm = map(error,0,360,0,255); // Tranformación del error a un valor de PWM analogWrite(11,pwm); // Se imprime el valor de salida del pwm if (order_angle>actual_angle) // Si el angulo ordenado es mayor que el angulo actual gira a la izquierda { turnRight(); // Motor girando a la derecha flag=1; } else { turnLeft(); // Motor girando a la izquierda } /*****************************************************************************/ if (etime > 1000000) //Si ha pasado 1 segundo (estampos en microsegundos) { //Imprime cada segundo los datos, solamente hace eso Serial.print("Angulo deseado: "); Serial.print(order_angle); Serial.print(", Angulo actual: "); Serial.print(actual_angle); Serial.print(", PWM: "); Serial.print(pwm); if(flag==1) { Serial.print("Girando CW"); //Siguiendo las manecillas de relog } else { Serial.print("Girando CCW"); //Contra las manecillas de relog } timep = time; } } /*********************************************************************** * FUNCION ACHANGE() DETECTA EL CAMBIO DE FLANCO DEL CANAL A DEL ENCODER ***********************************************************************/ void Achange() { A = digitalRead(2); //Lectura del canal A B = digitalRead(3); //Lectura del canal B //Declaracion de los estados posibles entre la lectura de los canales A y B del Encoder if((A==HIGH)&&(B==HIGH)) state =1; if((A==HIGH)&&(B==LOW)) state =2; if((A==LOW)&&(B==LOW)) state =3; if((A==LOW)&&(B==HIGH)) state =4; switch(state) { case 1: //Si el estado actual es 1 { //Comparacion con el estado pasado if(statep == 2) count--; // Si el estado pasado es 2 decrementamos el contador en 1 if(statep == 4) count++; // Si el estado pasado es 4 incrementamos el contador en 1 break; } case 2: //Si el estado actual es 2 { //Comparacion con el estado pasado if(statep == 1) count++; // Si el estado pasado es 1 incrementamos el contador en 1 if(statep == 3) count--; // Si el estado pasado es 3 decrementamos el contador en 1 break; } case 3: //Si el estado actual es 3 { //Comparacion con el estado pasado if(statep == 2) count++; // Si el estado pasado es 2 incrementamos el contador en 1 if(statep == 4) count--; // Si el estado pasado es 4 decrementamos el contador en 1 break; } default: //Utilizado el default como el estado 4 { //Comparacion con el estado pasado if(statep == 1) count--; // Si el estado pasado es 1 decrementamos el contador en 1 if(statep == 3) count++; // Si el estado pasado es 3 incrementamos el contador en 1 //break; } } statep = state; // actualizamos la variable statep con el valor del actual estado para cerrar el circulo } /*********************************************************************** * FUNCION BCHANGE() DETECTA EL CAMBIO DE FLANCO DEL CANAL B DEL ENCODER ***********************************************************************/ void Bchange() { A = digitalRead(2); //Lectura del canal A B = digitalRead(3); //Lectura del canal B //Declaracion de los estados posibles entre la lectura de los canales A y B del Encoder if((A==HIGH)&&(B==HIGH)) state=1; if((A==HIGH)&&(B==LOW)) state=2; if((A==LOW)&&(B==LOW)) state=3; if((A==LOW)&&(B==HIGH)) state=4; switch(state) { case 1: //Si el estado actual es 1 { //Comparacion con el estado pasado if(statep == 2) count--; // Si el estado pasado es 2 decrementamos el contador en 1 if(statep == 4) count++; // Si el estado pasado es 4 incrementamos el contador en 1 break; } case 2: //Si el estado actual es 2 { //Comparacion con el estado pasado if(statep == 1) count++; // Si el estado pasado es 1 incrementamos el contador en 1 if(statep == 3) count--; // Si el estado pasado es 3 decrementamos el contador en 1 break; } case 3: //Si el estado actual es 3 { //Comparacion con el estado pasado if(statep == 2) count++; // Si el estado pasado es 2 incrementamos el contador en 1 if(statep == 4) count--; // Si el estado pasado es 4 decrementamos el contador en 1 break; } default: //Utilizado el default como el estado 4 { //Comparacion con el estado pasado if(statep == 1) count--; // Si el estado pasado es 1 decrementamos el contador en 1 if(statep == 3) count++; // Si el estado pasado es 3 incrementamos el contador en 1 //break; } } statep = state; // actualizamos la variable statep con el valor del actual estado para cerrar el circulo } void turnRight() // Ordena el giro en CW (Clock Way) { digitalWrite(x,HIGH); digitalWrite(y,LOW); } void turnLeft() // Ordena el giro en CCW (Contra Clock Way) { digitalWrite(x,LOW); digitalWrite(y,HIGH); }
@carlosrojo73816 жыл бұрын
ya lo probaste ?
@haroldaguivillar4247 Жыл бұрын
@@carlosrojo7381 sin funciona necesitas el hardware adecuado nomas
@juancamiloserranocorrea62395 жыл бұрын
Genial, hicieron lo que hace un servomotor pero sin limitación de ángulo.
@c1a9h9r93 жыл бұрын
Excelente, para evitar la oscilacion debiste usar el PID
@3ST3BANJIMENEZ9 жыл бұрын
Una pregunta, Tlacalel, Si en lugar de encoder adaptamos un potenciometro al motor (de manera fisica) para que nos indique la posición actual del motor, cómo adaptamos ese cambio en programación??
@jacquelinnehernandezlorenz75057 жыл бұрын
oye amigo, podrias ayudarme, diciendo que tipo de motor usas?? porfavor.,, que relcion es y de que tipo es el encoders
@jomahero239 жыл бұрын
Buen trabajo, gracias por compartirlo ya que me ha sido de mucha utilidad
@erikpalacios72386 жыл бұрын
Muchas gracias!!! excelente video!
@3ST3BANJIMENEZ9 жыл бұрын
Hola me podrías compartir el codigo que utilizaron. Saludos
@gerardoramirez94504 жыл бұрын
Hola amigo, excelente video. Solo una duda: En el void loop () en la funcion map para el cálculo de actual_angle, ¿de dónde sale el número 5284? Muchísimas gracias y saludos.
@annie00763 жыл бұрын
Tengo la misma duda, ¿Si encontraste a que corresponde? Saludos
@davidromero63653 жыл бұрын
Es el número de pulsos emitidos por el encoder en una vuelta completa del eje del motor
@efrainramos68367 жыл бұрын
amigo muy bueno, ¿me podrias ayudar con el codigo?
@jhonyluiscarbajalquispe26977 жыл бұрын
HOLA PORFAVOR. UNA PREGUNTA. COMO INGRESAS ESE ANGULO EN ARDUINO PARA QUE GIRE EL MOTOR. NO ENCUENTRO LAS OPCIONES
@deaelectronic81756 жыл бұрын
A mi me pasa lo mismo no encuentro como ingresar el angulo, lo averiguaste tu. Gracias
@dantejimrandalgallotorres8856 жыл бұрын
mediante el puerto serial
@MegaJosepreciado6 жыл бұрын
Alguien que me pueda pasar el código y el driagrama de favor? se los agradecería, lo necesito para un proyecto de control clásico igual.
@piezaspararobotica7 жыл бұрын
Si estas en categoria educacion ..creo te falta poner los datos de codigo y diagrama utilizados en el proyecto sino para que sirve???? no podemos experimentar y llevar a la practica...Sdos..