TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Algec en 16 de Noviembre de 2007, 15:06:59
-
Voy a tratar de explicar mi problema, he comprado un potenciometro de los que usan los equipos de audio que en realidad son una especie de encoder que genera dos trenes de pulsos , a y b, tipicos de un encoder. Es un encoder en miniatura realmente y para usarlo con jogg en una fresadora es para lo que quiero usarlo.
El problema es que al parecer uno de los trenes de pulsos llega antes que el otro, a ver si me explico, si giramos a derechas el tren el tiempo de aparicion del flanco del tren A con respecto al tren B es menor que si giramos a izquierdas y el programa aunque me detecta el giro no discrimina bien el sentido.
No se donde esta el fallo porque por lo demas va bien.
Os pego el codigo y a ver si veis vosotros el porque.
Una sugerencia,¿ que tal serian estos potenciometros para usarlos como encoders para los ejes de una fresadora? baratos son y si se averian se pueden sustituir facilmente.
/code
#include <16F876.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
#use delay(clock=1000000)
int tiempox = 100; // variable de tiempo de salida de pulsos en botones
int tiempoy = 100; // variable de tiempo de salida de pulsos en botones
int tiempoz = 5; // variable de tiempo de salida de pulsos en botones
int lentoxy = 50;
int lentoz = 2;
int rapidoxy = 100;
int rapidoz = 4;
int pulsos_encoderxy;
int pulsos_encoderz;
int direccion = 0;
int flag =0; // deteccion de salto de la interrupcion
// rutina de interrupcion si se gira el encoder
#INT_EXT
void giro (void)
{
if(input(PIN_B1))
direccion =1;
flag=1;
}
// rutina principal
void main(){
int x=0;
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
ext_int_edge(L_TO_H);
// con divisor 8 1500 RPM OK con 20 Mhz
// a 4 Mhz 120 RPMs Ok
output_high(PIN_C6); // bloquea X
output_high(PIN_A3); // bloquea Y
output_high(PIN_A0); // bloquea Z
while(TRUE){
// Si se genero la interrupcion
/////// EJE X //////////////
If (flag==1)
{
disable_interrupts(GLOBAL);
If(input(PIN_C2)) // esta seleccionado X en el selector
{
// depende del sentido de giro del encoder fija el bit de direccion de X
if(direccion == 1)
output_high(PIN_C5); // direccion a un lado
else
output_low(PIN_C5); // direccion al otro lado
output_low(PIN_C6); // desbloquea X
// hace la salida del pulsos de X
for(x=0;x<pulsos_encoderxy;x++)
{
delay_ms(1);
output_high(PIN_C4);
delay_ms(1);
output_low(PIN_C4);
}
output_high(PIN_C6); // bloquea X
}
/////// EJE Y //////////////
If(input(PIN_C1)) // esta seleccionado Y en el selector
{
// depende del sentido de giro del encoder fija el bit de direccion de X
if(direccion =1)
output_high(PIN_A5); // direccion a un lado
else
output_low(PIN_A5); // direccion a un lado
output_low(PIN_A3); // desbloquea Y
for(x=0;x<pulsos_encoderxy;x++)
{
output_high(PIN_C7);
delay_ms(1);
output_low(PIN_C7);
delay_ms(1);
}
output_high(PIN_A3); // bloquea Y
}
/////// EJE Z //////////////
If(input(PIN_C3)) // esta seleccionado Z en el selector
{
// depende del sentido de giro del encoder fija el bit de direccion de Z
if(direccion = 1)
output_high(PIN_A1); // direccion a un lado
else
output_low(PIN_A1); // direccion a un lado
output_low(PIN_A0); // desbloquea Z
// hace la salida del pulsos de Z
for(x=0;x<pulsos_encoderz;x++)
{
output_high(PIN_A2);
delay_ms(6);
output_low(PIN_A2);
delay_ms(6);
}
output_high(PIN_A0); // bloquea Z
}
flag=0;
direccion = 0;
enable_interrupts(GLOBAL);
}
if(input(PIN_C0))
{
tiempox=2;
tiempoy=2;
tiempoz=10;
pulsos_encoderxy = lentoxy;
pulsos_encoderz = lentoz;
}
else
{
tiempox=0,1;
tiempoy=0,1;
tiempoz=2;
pulsos_encoderxy = rapidoxy;
pulsos_encoderz = rapidoz;
}
// Apaga los leds de direccion
output_low(PIN_A1);
output_low(PIN_A5);
output_low(PIN_C5);
// Pulsadores Eje X
// eje X hacia lado Izdo
If(input(PIN_B4))
{
output_low(PIN_C6); // desbloquea X
output_low(PIN_C5); // direccion a un lado
// hace la salida del pulsos de X
output_high(PIN_C4);
delay_ms(tiempox);
output_low(PIN_C4);
delay_ms(tiempox);
}
else
output_high(PIN_C6); // bloquea X
// eje X hacia lado Derecho
If(input(PIN_B2))
{
output_low(PIN_C6); // desbloquea X
output_high(PIN_C5); // direccion a un lado
// hace la salida del pulsos de X
output_high(PIN_C4);
delay_ms(tiempox);
output_low(PIN_C4);
delay_ms(tiempox);
}
else
output_high(PIN_C6); // bloquea X
// pulsadores Eje Y
// Eje Y hacia el fondo
if(input(PIN_B5))
{
output_low(PIN_A3); // desbloquea Y
output_low(PIN_A5); // direccion a un lado
// hace la salida del pulsos de Y
output_high(PIN_C7);
delay_ms(tiempoy);
output_low(PIN_C7);
delay_ms(tiempoy);
}
else
output_high(PIN_A3); // bloquea Y
// eje Y hacia adelante
if(input(PIN_B3))
{
output_low(PIN_A3); // desbloquea Y
output_high(PIN_A5); // direccion a un lado
// hace la salida del pulsos de Y
output_high(PIN_C7);
delay_ms(tiempoy);
output_low(PIN_C7);
delay_ms(tiempoy);
}
else
output_high(PIN_A3); // bloquea Y
// pulsadores Eje Z
// Eje Z hacia el abajo
if(input(PIN_B7))
{
output_low(PIN_A0); // desbloquea Z
output_low(PIN_A1); // direccion a un lado
// hace la salida del pulsos de Z
output_high(PIN_A2);
delay_ms(tiempoz);
output_low(PIN_A2);
delay_ms(tiempoz);
}
else
output_high(PIN_A0); // bloquea Z
// eje Z hacia arriba
if(input(PIN_B6))
{
output_low(PIN_A0); // desbloquea Z
output_high(PIN_A1); // direccion a un lado
// hace la salida del pulsos de Z
output_high(PIN_A2);
delay_ms(tiempoz);
output_low(PIN_A2);
delay_ms(tiempoz);
}
else
output_high(PIN_A0); // bloquea Z
}
}
encode/
-
Parece lógico que así sea, ya que los encoders uno de los trenes esta adelantado 90 grados respecto al otro para discriminar el sentido de giro.
Un saludo
-
Como bien dice jfh900, hasta donde yo sé los encoders llevan los dos canales desfasados para sensar el sentido de giro. Si los pulsos del canal A llegan antes que los del B el sentido de giro es uno, si por el contrario los primeros son los del canal B el sentido es el inverso.
-
PUes no va bien, quizas sea del hard? no lleva triggers de smich, es posible que sea eso?
-
¿Podrías poner el esquema del circuito de captura?
Un saludo
-
Tal vez este pdf pueda ayudarte en algo... solo espero que si y si no dimelo para quitar este mensaje :shock: :mrgreen: :mrgreen:
-
Ahi os subo todo, el encoder en proteus lo simulo girando un motor que lleva encoder a la salida.-
Asi funciona bien, en real falla la detecccion de sentido de giro