TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: enero0022 en 16 de Enero de 2008, 22:39:38
-
hola a todos tengo la inquietud de conectar un encoder a un pic para poder controlar el avance de un motor a determinada
distancia y quiero saber si ya alguien lo realizo y si me pueden enviar algun ejemplo o alguna sugerencia a la vez quiero saber si se puede controlar el motor con el pwm han de saber que el motor es de tipo industrial 1 hp aproximadamente.
gracias
-
mi estimado enero0022, le recomiendo usar al señor BUSCADOR del foro, si lo usa le facilitara la busqueda de informacion, acabo de consultarle con la palabra "encoder" y me arrojo 9 paginas de 30 enlaces(aprox) cada una, animese a preguntarle, el no muerde :mrgreen: :mrgreen:
-
Sí se puede. Yo hice un ejemplo que podrías mirar, aunque sólo sirve si utilizas un dsPIC con módulo QEI.
dsPIC33F - Capítulo 3: Quadrature Encoder Interface (QEIM) (http://www.micropic.es/index.php?option=com_content&task=view&id=18&Itemid=44)
Hay muchos tipos de motores; unos se pueden regular con PWM y otros no. Habría que saber más sobre el que indicas.
-
Puedo agregar que también se puede con un 18F y con un 16F utilizando el módulo de comparación y captura, por ejemplo.
Todo depende de la precisión que necesites y si necesitas sensar sentido de giro o si tu lo etarás comandando y a cuantas RPM estarás girando el eje y de cuantos pulsos por vuelta arroje el mismo.
Cuantos mas pulsos por vuelta arroje y mayor velocidad gire el eje más velocidad necesitaras en tu microcontrolador para leer el pulso.
-
Hay algunos modelos de pic18f que llevan incorporado QEI (Quadrature Encoder Interface) por ejemplo el 18F4431, 2431, 2331 etc... verás toda la información en el capitulo 16.2 del Datasheet.
-
Estoy trabajando en el tema, lei el ejemplo de nocturno, pero yo estoy trabajando con 18f4331 que tiene el modulo.
La pregunta es yo me tendria que armar un disco con esa forma pero la duda es cuantas ventanas tiene que tener?
cuantas mas ventanas, mas presicion?
-
No hace falta ningun modulo ni nada, con dos entradas y el soft adecuado se leen, yo tengo tres encoders caseros en mi fresadora y leen posicion perfectamente, con un 16F877 a 20 Mhz leen hasta 2500 rpms.
Si necesitas el ejemplo lo subo.
-
gracias el tema es como los instalo en el motor?
Uso sensor optico , o hall?
una vez hecho eso es analizar una senial cuadrada, periodo y duty cicle.
Si tenes un ejemplo subilo.
-
en el eje dos sensores desfasados es suficiente, que den señal de 0 a 5 v, para eso se suele usar un 40106 o similar.
Dos entradas del pic leen los pulsos desfasados, Hay que convertir de codigo Gray a codigo binario y comparar etc....y de ahoi sale el sentido de giro la velocidad y contador si quieres para posicion.
-
Pero vi que al eje le colocan unos discos con ventanas blanco/negro y estoy viendo como hacer eso porque es un motor bastante importante
-
Si quieres seguridad compra un encoder hecho y usa el pic para controlarlo
-
No hace falta ningun modulo ni nada, con dos entradas y el soft adecuado se leen, yo tengo tres encoders caseros en mi fresadora y leen posicion perfectamente, con un 16F877 a 20 Mhz leen hasta 2500 rpms.
Si necesitas el ejemplo lo subo.
Hola Algec , puedes publicar tu ejemplo??
-
Vale lo publicare pero tengo un pequeño problema, no recuerdo como pegar el codigo y que quede como codigo, me lo recordais?
-
Cuando ingresas para responder en la parte de arriba hay varios iconos, elige el que tiene el simbolo # luego has un copy/past de tu codigo y leugo vuelve a precionar para cerar la opcion y ya esta...
-
Aver si os vale esto, si quereis mas decidmelo
Trato de subir el proteus completo caratulas etc pero de momento no me deja
#include <16F877.h>
#use delay(clock=4000000)
// mas precision y velocidad de conteo si se usa a 20 Mhz
// tambien trabaja a 4 Mhz pero pierde velocidad
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT // 0x3F71
// Uso mi propia libreria de LCD por usar un lcd de 4x20 y no estar este
// configurado en la rutina propia de CCS
// se puede usar la libreria lcd.h de CCS con un display conectado tal y como indica
// la libreria de CCS
#include <lcd1.c> //"lcd.h"
// inicializa valores de contadores
// si se utiliza int16 pierde valor maximo de conteo, pero gana en velocidad de calculo por
// lo que permite mas velocidad de giro o mas impulsos por vuelta sin dar error
// int32 da mas pulsos contados a costa de perder velocidad en el contador y generar mas errores
signed int16 contador_X = 0;
signed int16 contador_Y = 0;
signed int16 contador_Z = 0;
// Rutina de cambio de codigo
// pasa de codigo gray (que es el que genera a dos bits el encoder) a binario
// gray binario
// 00 00
// 01 01
// 11 10
// 10 11
/**************************************************************************************/
byte pasa_a_binario(byte valor)
{
if(bit_test(valor,1)==1) // si el bit 1 de valor es 1
{
if(bit_test(valor,0)==0) // invierte el bit 0 de valor
bit_set(valor,0); // hace 1 el bit 0 de valor
else
bit_clear(valor,0); // hace cero el bit 0 de valor
}
return valor;
}
void main(void)
{
unsigned byte actual_X ;
unsigned byte anterior_X ;
unsigned byte diferencia_X ;
unsigned byte actual_Y;
unsigned byte anterior_Y;
unsigned byte diferencia_Y;
unsigned byte actual_Z;
unsigned byte anterior_Z;
unsigned byte diferencia_Z;
disable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
// inicializa el lcd
lcd_init();
// visualiza los Textos
lcd_gotoxy(1,1);
lcd_putc("X:");
lcd_gotoxy(1,2);
lcd_putc("Y:");
lcd_gotoxy(1,3);
lcd_putc("Z:");
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X);
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y);
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z);
// borra las salidas de los leds de error
output_c(0x00);
// Lectura inicial
// lee los dos bits de menos peso del puerto A y los pone en la variable estado_X
// estos corresponden a las entradas del pic asignadas al encoder del eje X
anterior_X=input_a() & 0x03; // lee solo los bits 0 y 1
// hace la lectura del encoder Y
// para solo considerar los dos bits que interesan
anterior_Y=(input_a() & 0x0c)/4; // lee los bits 2 y 3 y desplaza a la izda 2 bits
// hace la lectura del encoder Z
// para solo considerar los dos bits que interesan
anterior_Z=(input_a()& 0x30) / 16; // lee los bits 4 y 5 y desplaza a la izda 4 bits
// pasa de codigo gray (que es el que genera a dos bits el encoder) a binario
anterior_X = pasa_a_binario(anterior_X);
anterior_Y = pasa_a_binario(anterior_Y);
anterior_Z = pasa_a_binario(anterior_Z);
while(TRUE)
{
// hace la lectura del encoder X
actual_X=input_a() & 3; // lee solo los bits 0 y 1
// hace la lectura del encoder Y
actual_Y=(input_a()& 0x0c)/4;
// hace la lectura del encoder Z
actual_Z=(input_a()& 0x30)/16;
// hace la lectura del encoder Z
actual_X = pasa_a_binario(actual_X); // cambia de codigo gray a binario
actual_Y = pasa_a_binario(actual_Y); // cambia de codigo gray a binario
actual_Z = pasa_a_binario(actual_Z); // cambia de codigo gray a binario
// rutina del eje X
if(actual_X != anterior_X) // si ha cambiado el estado es que ha habido un pulso
{
// calcula la diferencia para ver los bits de signo y de error
diferencia_X = actual_X - anterior_X;
//lineas de testeo
// lcd_gotoxy(10,1);
// printf(lcd_putc,"%d %d %x", anterior_X,actual_X,diferencia_X&3);
// chequeo los bits de error y signo
if(bit_test(diferencia_X,0) == 0) // si se ha producido un error se habra puesto a cero el bit 0
{
output_high(PIN_C0); // enciende el led de error
lcd_gotoxy(12,1);
lcd_putc("ERROR");
}
else
{ // chequea el bit de sentido de giro
// si es hacia un lado incrementa el contador lo que
// sea necesario segun el numero de pulsos/vuelta
// y la precision requerida
if(bit_test(diferencia_X,1) == 1)
contador_X = contador_X + 5;
else
contador_X = contador_X - 5;
// visualizacion eje X
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X/4);
}
// memoriza en anterior_X el estado actual
anterior_X = actual_X;
}
// rutina del eje Y
if(actual_Y != anterior_Y) // si ha cambiado el estado es que ha habido un pulso
{
// calcula la diferencia para ver los bits de signo y de error
diferencia_Y = (actual_Y- anterior_Y);
// chequeo los bits de error y signo
if(bit_test(diferencia_Y,0) == 0) // si se ha producido un error se habra puesto a cero el bit 0
{
output_high(PIN_C1); // enciende el led de error
lcd_gotoxy(12,2);
lcd_putc("ERROR");
}
else
{
if(bit_test(diferencia_Y,1) == 1) // chequea el bit de sentido de giro
contador_Y=contador_Y+5; // si es hacia un lado incrementa el contador
else
contador_Y=contador_Y-5; // hacia el otro lo decrementa igualmente
// visualizacion eje Y
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y/4);
}
// memoriza en anterior_Y el estado actual
anterior_Y = actual_Y;
}
// Rutina del eje Z
if(actual_Z != anterior_Z) // si ha cambiado el estado es que ha habido un pulso
{
// calcula la diferencia para ver los bits de signo y de error
diferencia_Z = actual_Z - anterior_Z;
// chequeo los bits de error y signo
if(bit_test(diferencia_Z,0) == 0) // si se ha producido un error se habra puesto a cero el bit 0
{
output_high(PIN_C2); // enciende el led de error
lcd_gotoxy(12,3);
lcd_putc("ERROR");
}
else
{
if(bit_test(diferencia_Z,1) == 1) // chequea el bit de sentido de giro que sera 1 girando a derecha
contador_Z=contador_Z+5; // si es hacia un lado incrementa el contador
else
contador_Z= contador_Z-5 ; // hacia el otro lo decrementa
// visualizacion eje Z
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z/4);
}
// memoriza en anterior_Z el estado actual
anterior_Z = actual_Z;
}
// Pulsadores de puesta a cero
/*
If(input(PIN_B0)) // puesta a cero de posicion Inicial tres ejes
{
output_low(PIN_C0); // pone a cero los leds de error
output_low(PIN_C1);
output_low(PIN_C2);
contador_X = 0;
contador_Y = 0;
contador_Z = 0;
lcd_gotoxy(12,1);
lcd_putc(" ");
lcd_gotoxy(12,2);
lcd_putc(" ");
lcd_gotoxy(12,3);
lcd_putc(" ");
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X);
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y);
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z);
}
If(input(PIN_B1)) // puesta a cero de posicion Inicial Eje X
{
output_low(PIN_C0);
contador_X = 0;
lcd_gotoxy(12,1);
lcd_putc(" ");
lcd_gotoxy(3,1);
printf(lcd_putc,"%4.2w ",contador_X);
}
If(input(PIN_B2)) // puesta a cero de posicion Inicial Eje Y
{
output_low(PIN_C1);
contador_Y = 0;
lcd_gotoxy(12,2);
lcd_putc(" ");
lcd_gotoxy(3,2);
printf(lcd_putc,"%4.2w ",contador_Y);
}
If(input(PIN_B3)) // puesta a cero de posicion Inicial eje Z
{
output_low(PIN_C2);
contador_Z = 0;
lcd_gotoxy(12,3);
lcd_putc(" ");
lcd_gotoxy(3,3);
printf(lcd_putc,"%4.2w ",contador_Z);
}
*/
}
}
-
VAmos a ver, este es un ejemplo, yo hice un sistema completo con tres encoders para los tres ejes de mi fresadora CNC, al ser tres encoders no pude usar la interrupcion por cambio de estado, que habria funcionado mejor, por eso la hice testeando las entradas al cabo de cierto tiempo de forma ciclica, que tambien funciona.
Tengo todo el proyecto y creo que en su dia lo subi, mirar por el foro en CNC.
LLeva los encoders que son de mi propio diseño y contruccion, fotos proteus completo isis y ares, de las placas, creo que un video, las caratulas que use en resumen un poco de todo.
TAmbien tengo un ejemplo con interrupcion por cambio de estado. si lo necsitais.....
El equipo esta funcionando en mi fresadora perfectamente y hasta 3000 rpm va bien al menos como yo lo tengo.
Al final encontre el post en el foro, es este
http://www.todopic.com.ar/foros/index.php?topic=23074.0
-
Hola, yo estoy usando un PIC18F4431 para hacer funcionar un motor trifásico de compactera y de disco rígido, ya he logrado hacerlos funcionar, con los 6 pwm y el inversor trifásico. Ahora quiero utilizar los 3 sensores hall que trae el motor de compactera, con el módulo QEI que trae el PIC18F4431. El tema es que no sé cómo trabajan los sensores hall. Una posibilidad que tengo, es llevarlo a la facu, y conectarle el osciloscopio, pero es mucho trastorno para mí. Estos sensores hall emiten un ancho de pulso proporcional a algo, o un pulso cuadrado proporcional a la velocidad?????. El motor trae 3 sensores hall, debajo de las bobinas, pero aún no me doy maña de cómo usarlo, tal vez conectar uno al QEA, otro al QEB, y otro al index????? para determinar el sentido de giro y las revoluciones.
El sentido de giro no es problema, porque lo manejo yo invirtiendo 2 fases del motor, lo que más me interesa es tener un control de la velocidad, ya que aunque la misma la varíe con la frecuencia, quiero que el sensor me la envía para mostrarla en un display.
-
Yo me enfrenté a lo mismo con un motor parecido, aquí dejé lo que hice, puede que te sirva: http://www.micropic.es/index.php?option=com_content&task=view&id=81&Itemid=39
-
Yo me enfrenté a lo mismo con un motor parecido, aquí dejé lo que hice, puede que te sirva: http://www.micropic.es/index.php?option=com_content&task=view&id=81&Itemid=39
Yo me enfrenté a lo mismo con un motor parecido, aquí dejé lo que hice, puede que te sirva: http://www.micropic.es/index.php?option=com_content&task=view&id=81&Itemid=39
Muchas gracias, estoy visitando el MicroPIC más seguido. El enlace al control del motor brushless que me pasaste está muy bueno, de hecho, estoy tratando de implementarlo, pero no entiendo bien el motor que tengo. tiene 3 sensores hall, smd de 4 conectores, y hay 8 cables a los sensores hall, y no puedo ver el conexionado, ya que son miniatura y los tapan las bobinas. Voy a ver si en las vacaciones, puedo ir al lab de la facu y usar los osciloscopios para descubrir como trabajan.
Yo lo he hecho funcionar con el control senoidal, pero no logro que levanten muchas revoluciones.
Los 3 sensores que traen son parecidos a estos: http://www.hallsensors.de/CYSH12AF.pdf
Agradezco mucho tu ayuda.