Encoder + PIC

Hola amigos, recurro a ustedes para que me ayuden, tengo el enconder AS5304 con su respectiva cinta magnética modelo AS5000-MS-20-150
Encontré un código en Internet para trabajar con el PIC16F628A, yo estoy usando el 16F628.
El tema es que este código es capaz de reconocer en que dirección se está moviendo el encoder y prender unos led de acuerdo a eso.
Ahora mi problema, me gustaría que me ayudaran a modificarlo para poder asignarle una posición 0 y que sepa en que posición se encuentra, o sea, por ejemplo se desplazó 30° hacia la derecha y que prenda un Led, si se me movió 50° prenda dos Led y lo mismo hacia la izquierda, obviamente prendiendo otros led.
Ojala me pueda ayudar, abajo pego el código.

Saludos.

Código:
#include <16f628.h>

#FUSES NOWDT, XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD

#use delay(clock=4000000)

#byte porta = 0x05        // Asignamos PortA.
#byte portb = 0x06        // Asignamos PortB.

// ---------- Programa Principial ----------

void main()
{
   port_b_pullups(FALSE);                   // Sin resistencias pullups a las salidas del puerto B.
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Al no usar el TIMER configuramos lo más básico. 
   setup_comparator(NC_NC_NC_NC);           // Sin comparadores.
   setup_vref(FALSE);                       // Al no usar comparadores no necesitamos Vref.  
   
   //---- Fin de la configuración del 16F628A ----

   int8   x;    // Declaramos el valor de X como byte, se corresponderá con los 8 LEDs de salida.
   int8   enc;  // Se almacenará el valor actual de RA0 y RA1, hasta la siguiente comparación.
   int8   aux;  // Se almacenará el valor anterior de RA0 y RA1, hasta la siguiente comparación.

   set_tris_a(0b11111);     // Puerto A como entradas. Sólo usamos RA0 y RA1.
   set_tris_b(0b00000000);  // Puerto B como salidas, para los 8 LEDs.
   
   portb=0;   // Inicialmente ponemos a cero el puerto B.
   x=0;       // Inicialmente ponemos a cero la variable que se usa para contar.
   enc=0;     // Inicialmente ponemos a cero la variable que tomará los valores de RA0 y RA1.
   
   While (true)
   {
          aux=enc;               // Igualamos 'AUX' y 'ENC' para luego comparar cuando cambie 'ENC'.
          enc=porta & 3;         // Aislamos RA0 y RA1 como un número de 2 bits y se carga en la variable 'ENC'.
          
          If ((aux==2)&&(enc==3))// Si en la comparación hay flanco de subida,
          {  
              x++;               // entonces incrementar una unidad el valor de X.
          }
          
          If ((aux==3)&&(enc==2))// Si en la comparación hay flanco de bajada,
          {  
              x--;               // entonces decrementar una unidad el valor de X.
          }
          
          portb = x;             // El valor de X sale por el puerto B, los 8 LED de salida.
   }
              
}
 
Última edición por un moderador:
No conosco el encoder, pero cada paso a cuanto equivale????

usando un auxiliar para el conteo podras saber cuanto avanzo, igual como lo haces para ver si avanza o retrocede.

atte
jvk85321
 
cada paso equivale a 0.03°, la idea es hacer que prendan ciertos led si se mueve hacia la derecha y otros si se mueve hacia la izquierda y a las vez que por ejemplo llegado a las 15° prenda otro led.
 
Hola Amigo bueno parece que trabajas con un encoder relativo. Si deseas conocer una posición absoluta dicho encoder debe ofrecer una señal adicional designada como Z. Esta señal es un índice que indica el comienzo de grado 0. Ahora si sólo deseas conocer cuanto es su avance angular, debe añadirse unas líneas al codigo para que cuando cambie el sentido de giro el valor sea x=0.
Hay que prestar atención cuando x=0 ya que si se produce un decremento x--, el valor de la misma será 255 y no -1 cómo puede pensarse.
 
Última edición:
efectivamente necesito darle una posición 0 y así conocer su posición angular independiente del sentido de giro, es decir, que si gira hacia la derecha 90° o bien izquierda -90°, el encoder trae una señal index, que es el pulso que se produce cuando las dos señales (A y B) están en alto, a mi me cuesta llevar eso a código porque estoy empezando en esto de la programación, aun asi agradezco mucho sus consejos
 
Lo que necesitas es darle un HOME (referencia de inicio o cero) tu determinas esa posición cuando este ahí le pones a tu variable de posición=0 y cuando te empieces a mover el encoder trabaja de la siguiente manera: tiene dos canales A y B desfasados 90° con lo cual tienes 4 combinaciones cuando A y B están en CERO, cuando A esta en UNO y B en CERO, cuando A y B están en UNO, y cuando A esta en CERO y B en UNO
1 2 3 4
A 0 1 1 0
B 0 0 1 1

Si el paso que mencionas de 0.03° (es como te entendí) es cuando un canal pasa de CERO a UNO, con estas 4 combinaciones ahora tienes mas resolución, 0.03°/4=0.0075°.
Ahora debes de capturar cada uno de esos estados en la variable de posición y para saber si vas a incrementar o decrementar el valor haces lo siguiente si A=1 como es el cambio en B? si el flanco es ascendente incrementas y si el flanco es descendente decrementas ( o viceversa, como quieras)
espero que te sirva.....
 
En cuanto a los PIC, el 628 y el 628A son casi lo mismo, con alguna diferencia muy especifica, pero la mayoria de los proyectos que encuentras en la Internet corren bien con cualquera de ellos dos.
 
Buenas amigos, estoy trabajando en un codificador virtual absoluto, un encoder, lo estoy haciendo desde cero para un proyecto de iniciacion a la mecatronica. Ya tengo todo el diseño en autocad del dispositivo, estoy tratando de hacer el codigo para el pic pero no tengo muy clara la idea. Les agradeceria toda la ayuda posible, trabajo con codigo Gray de 4 bits, disco absoluto de 16 posiciones y disco incremental de 8 pasos
 
Si tenes la información del encoder sabes los pulsos que da por giro según lo que quieras hacer, posicionar o controlar velocidad es como haras la función del encoder, para uno sera candidad de pulsos en funcion de la cantidad de giros y la parte mecánca que no sabeos, y en otro cantidad de pulsos por unidad de tiempo
 
buenas compañeros

aquí os dejo un programa o dos para encoder. yo lo uso con un encoder del tipo potencio metro
pero lo probé con un encoder que saque de una impresora con el disco y funciona genial
por lo que tengo entendido este no usa flag, así que cuidado con la velocidad a la que lo trabajen
el encoder 1 . es para encoder sin auto posición
el encoder 2 . es para encoder con auto posicion ( se entiende que auto posiciona es aquel que lo giras y queda en una posición concreta )
y la prueba 12 es el encoder con auto posición que cuenta ascendente y descendente con cuatro
display 7 seg. multiplicado con el 74ls47n. en este ultimo si aumentan el tiempo de retado de
los display podrán ver a que me refiero con tener cuidado con la velocidad del encoder
(en el enlace esta encoder 1 y 2 https://www.forosdeelectronica.com/f24/maneja-encoder-pic-19542/ )
 

Adjuntos

  • RETARDOS INC.txt
    10 KB · Visitas: 22
  • encoder mas contador.txt
    3 KB · Visitas: 36
Atrás
Arriba