Leer encoder incremental de motor DC

¿Has creado algún proyecto genial con una Raspberry Pi? Este es tu lugar.
Responder
Erko200c
Pi Newbie
Pi Newbie
Mensajes: 4
Registrado: 20 Ene 2018, 04:37
Agradecido: 0
Agradecimiento recibido: 0

Hola a todos, soy nuevo manejando los pines GPIO.
Agradecería cualquier ayuda que me puedan dar, para poder leer un encoder incremental de 1150 pulsos por vuelta que esta montado a un motor dc que gira a 1300 rpm.

En arduino, pude leer hasta los 800 rpm aproximadamente, por eso es que ahora estoy intentando con el raspberry pi 3 en phyton.
Pero no me ha ido muy bien.
Gracias de ante mano por cualquier ayuda.
Atte. Erick
Alkimi
Pi Beta
Pi Beta
Mensajes: 108
Registrado: 21 Oct 2017, 19:14
Agradecido: 0
Agradecimiento recibido: 0

pon codigo de aurdiono y de rb a ver como haces la lectura. seguramente sea problema de programacion.

con los datos que estas manejando son unos 25000 pulsos por sengundos maximo eso es 25khz de muestreo, el adruino deberia llegar sin problema (1300*1150)/60 = 25khz y tu te has quedado en un muestreo de (900*1150)/60 = 17.5 khz

creo que es mas el como has realizado la programacion y por falta de potencia del arduino,
Erko200c
Pi Newbie
Pi Newbie
Mensajes: 4
Registrado: 20 Ene 2018, 04:37
Agradecido: 0
Agradecimiento recibido: 0

Gracias por la respuesta, en arduino he usado el siguiente codigo, que me permite capturar tanto subidas como bajadas de los dos pines del encoder incremental dandome 1150*4 pulsos por vuelta, al manejar dos interrupciones y la posibilidad de saber a que lado gira el motor y contar con un codigo extra que me permite controlarlo, dejo de leer tan rapido como deberia. Es por ello que recurro al raspberry pi, ya que quiero controlar no solo un motor si no varios y ademas necesito alta velocidad de lectura del encoder (mas que la del arduino), mi duda es como lograr utilizar toda la velocidad de lectura de los pines GPIO del Raspberry.
Agradesco cualquier ayuda en ello.
Saludos.
Atte. Erick


////////////////////codigo arduino, lectura de encoder incremental ///////////////////////////////////////////////////////

attachInterrupt(digitalPinToInterrupt(pin),encoder,CHANGE); // interrupcion para el encoder
attachInterrupt(digitalPinToInterrupt(pin_2), encoder, CHANGE); // en los pines 2 y 3, actúa la interrupción.

TCCR0B = TCCR0B & B11111000 | B00000001; // establece el temporizador 62500.00 Hz https://arduino-info.wikispaces.com/Ard ... -Frequency


void encoder(void)
{


ant=act; // Guardamos el valor 'act' en 'ant' para convertirlo en pasado.
act=PIND & 12; // Guardamos en 'act' el valor que hay en ese instante en el encoder y hacemos un, solo se considera el pin 2 y 3 , por eso se realiza la operacion logica & 12.
// enmascaramiento para aislar los dos únicos bits que utilizamos para esta finalidad.

if(ant==12 && act==4) { // Incrementa el contador si el encoder se mueve hacia delante.
contador++;
}
if(ant==4 && act==0) {

contador++;
}
if(ant==0 && act==8) {

contador++;
}
if(ant==8 && act==12) {

contador++;
}

if(ant==4 && act==12) { // Decrementa el contador si el encoder se mueve hacia atrás.
contador--;
}
if(ant==12 && act==8) {

contador--;
}
if(ant==8 && act==0) {

contador--;
}
if(ant==0 && act==4) {;

contador--;
}

}
Alkimi
Pi Beta
Pi Beta
Mensajes: 108
Registrado: 21 Oct 2017, 19:14
Agradecido: 0
Agradecimiento recibido: 0

varias cosas que no me cuadran de ese codigo

para que quieres leer si estas avanzando o retrocediendo? si solo necesitas sabe las RPM te da igual el sentido. con lo que te ahorras todo el codigo del encoder.

la variable CONTADOR la debes definir como volatile para que se guarde en el procesador y sea mas rapido.

la interrupcion deberias definirla solo como RISING (de bajo a alto) o FALLING (de alto a bajo) con CHANGE te cuenta dos interrupciones por pulso y como tienes dos interrupciones te da los 1150*4 por revolucion. como yo te digo ya solo te da los 1150

otra cosa que no entiendo es proque hay dos interrupciones. el enconcer ya produce un pulso solo necesitas un pulso.

yo el codigo lo haria asi:

Volatile unsigned int numeroPulsos=0;
unsigned long tiempo=0;
unsigned int rpm;

void aumentaPulso(void){
numeroPulsos++;
}

void pins_init()
{
//resto declaracion de pines
//interrupciones
attachInterrupt(0, aumentaPulso, FALLING); // interrupcion 0 habilitada en el pin 2 sobre el metodo aumentaPulso en el flanco de bajada
}

void setup() {
pins_init();
//resto de configuracion....
}

void loop(){
if (( millis() - tiempo ) >= 1000){
tiempo=millis();
noInterrupts(); // desactivamos interrupciones para mostrar dato salida
rpm = ( numeroPulsos / 1150)*60; // calculamos cuantas revoluciones ha dado en un segundo y multiplicamos por 60
// para ahorrar operaciones matematicas hacemos (1/1150)*60 = 0.0522 y multiplicamos por los pulsos
// rpm = numeroPulsos * 0,0522;

numeroPulsos=0;
Interrupts(); // reactivamos interrupciones para que vuelva a contar.
//mostramos el valor de rpm
}
}

creo que este codigo es mucho mejor, lo he hecho de cabeza puede que haya algun error.

pero en teoria si solo quieres contar las rpm con esto te basta, si quieres detectar el sentido y cuantas vueltas ha dado en cada sentido el codigo si se pareceria algo mas al orginal.
Erko200c
Pi Newbie
Pi Newbie
Mensajes: 4
Registrado: 20 Ene 2018, 04:37
Agradecido: 0
Agradecimiento recibido: 0

Gracias por la respuesta, creo que no me explique bien en lo que realmente busco, mil disculpas. No solo quiero contar los rpm, tambien quiero la posicion, estoy controlando la posicion de un motor DC, mediante la posicion y la velocidad.
Bueno ya lo he logrado pero con velocidades maximas de 900RPM.
La posicion y la velocidad por que se trata de un sistema de control multi entrada y multi salida. ( Llega a la posicion acelerando en un principio llegando a un maximo de velocidad y luego va desacelerando hasta llegar a la posicion que le indico).
Es por ello que uso CHANGE y no puse todos los pormenores de mi programa en arduino, como la declaracion de variables por que funciona bien. El problema es que no puede leer mas rapido y necesito el Raspberry Pi, para lograr lo que busco, quisiera saber como hacer para leer el encoder a 1150*4 pulsos por vuelta con presicion en Raspberry.
Gracias de antemano y saludos
Atte. Erick
Alkimi
Pi Beta
Pi Beta
Mensajes: 108
Registrado: 21 Oct 2017, 19:14
Agradecido: 0
Agradecimiento recibido: 0

vale ahora tiene algo mas de sentido tu codigo, pero de todas forma hay demasiado codigo en las interrupciones. Las interrupciones por definicion han de tener el minimo codigo posible y realizar fuera con un bloque noInterrupts() Interrupts() las opreciones y reinicios de variables.

Quizas deberias crear dos interrupciones distintas una para conteo de pulsos y otra para obtener la direcion y fuera calcular la posicion.

sigo pensado que el arduino deberia poder llegar he visto en algun sitio de internet que captura hasta 80khz osea 80000 pulsos por segundos

respecto a la rb deberia ser sencillo traducir tu codigo tal cual a C y compliarlo en RB ya que lo tienes en C en el arduino.

No tiene mucho sentido meter un lenguaje interpretado ya que pierdes rendimiento. si quieres la maxima velocidad es C y ya tienes el codigo en C del arduino.

he mirado un poco, buscando "interrupciones gpio raspberry" en google salen unos cuantos ejemplos en phyton incluso varios contadores del pulsos.

y si buscas informacion de WiringPi que es una libreria para C tiene soporte para interrupciones

con lo que la migracion del codigo no deberia ser muy compleja.
Erko200c
Pi Newbie
Pi Newbie
Mensajes: 4
Registrado: 20 Ene 2018, 04:37
Agradecido: 0
Agradecimiento recibido: 0

Muchas gracias por la respuesta, he probado con phyton, con WiringPi, pero mejores resultados hasta ahora he conseguido con pigpio, una libreria muy completa y con muchos ejemplos.
Haber si logro perfeccionar el codigo con esa libreria.
Muchas gracias Alkimi, creo que el camino es el lenguaje C (mediante pigpio), ya que phyton tiene limitaciones en velocidad.
Saludos
Atte. Erick
Alkimi
Pi Beta
Pi Beta
Mensajes: 108
Registrado: 21 Oct 2017, 19:14
Agradecido: 0
Agradecimiento recibido: 0

Esta claro si quieres potencia y velocidad hay que bajar a C. si es algo mas normal phyton.
Alkimi
Pi Beta
Pi Beta
Mensajes: 108
Registrado: 21 Oct 2017, 19:14
Agradecido: 0
Agradecimiento recibido: 0

el problema es que esos motores que lleva el coche que has puesto de muestra son motores DC normales donde no tienes ningun control.

No se si tu llevas esos motores, para eso que dices has de usar motores paso a paso con un driver, normalmente los pasos son de 1.8º y configurando el driver del motor se puede obtener micropasos de hasta 1/16 o 1/32.

esa configuracion se usa mucho en impresoras 3D la de los motores paso a paso y sincronizados, con eso ya prodrias investigar algo de codigo.

si no necesitas tanta precision te puedes crear tu mismo el encoder con una rueda con ranuras como las de los ratones y colocarla al motor DC la idea es simular el funcionamiento de un raton http://www.embedded.arch.ethz.ch/Exampl ... Background

acabo de encontrar motores DC con un lector de efecto hall incorporado que funciona de encoder. http://androminarobot.blogspot.com.es/2 ... duino.html

espero haberte ayudado un poco.
Responder