Go Down

Topic: Entender este código control RPM motor (Read 4384 times) previous topic - next topic

noter

¿Tienes el pulsador con su resistencia pull down correspondiente?
El código no está probado, pero no es muy complicado y creo que debería funcionar.

Metaconta

#16
Oct 14, 2015, 05:15 am Last Edit: Oct 14, 2015, 05:38 am by Metaconta
Hola:

He usado el Pull-Up y Down, hasta con interruptor, luego ondas cuadradas de 1 Hz, 10 Hz, 100 Hz y 1 KHz generadas por un PIC12F508. Se coporta igual haga lo qu ehaga, está conectada al pin 2 de Arduino UNO rv3. También he cambiado de 9600 baudios a 115200 y sigue con lo mismo. He probado hasta el pin 3 por si acaso, el mismo comportamiento de siempre.


Ver imagen.

Espero que no esté roto el pobre Arduino. Quizás hay qu eprobar mejor código, a parte en vez de usar delay un mili que es más preciso y no deja en ningún momento el microcontrolador esclavo.

Saludos.

noter

#17
Oct 14, 2015, 04:48 pm Last Edit: Oct 14, 2015, 09:37 pm by noter
Simulado en proteus con un pulsador funciona bien. Me da 0 cuando no pulso y sube dependiendo de mi frecuencia de pulsación.
¿Tienen tierra masa común el arduino y el generador de pulsos?

Metaconta

#18
Oct 14, 2015, 04:51 pm Last Edit: Oct 14, 2015, 04:53 pm by Metaconta
Buenas:

Sigo investigando y he probado un ventilador de 12 V. / 0.10 A. con tacómetro y su salida del cable amarillo de es 5 V.



El comportamiento es el mismo, hasta con tacómetro, probando otro ventilador ocurre lo mismo.

Estoy buscando como loco un ejemplo sencillo sobre leer RPM de un ventilador de PC precisamente por aquí.

Si encuentran algunos interesantes antes que yo, los probaré todos, me quedo con el más efizaz. Sigo pensando mejor ponerlo a 115200 baudios com proyecto final, ya que trabaja más rápido en la lectura de datos y sin problemas. Por ahroa nos centramos en el famoso 9600 baudios.

El generador si tiene masa. también he hecho pruebas de lo que preguntas.

Lo queno entiendo que hace sin RPM conectado en el serial contando RPM como si lo tuviera así sin más. Debería poner 0 RPM. Conectando el ventilador lo he detenido quitándo la alimentación, debería poner 0 RPM y sigue con la misma.

Un cordial saludo.

noter

Haz la siguiente prueba:
Sin nada conectado al pin2, prueba el programa, pero iniciando el pin en el setup así:

Code: [Select]
pinMode(hallsensor, INPUT_PULLUP);

Debería darte cero. Si es así, pon un pulsador entre pin2 y GND y prueba pulsando a ver.

Metaconta

Buenas:

hice lo que dijiste y si funcinoa a 0 RPM, luego le puse el tacómetro del ventilador activado y funciona de maravilla, es lo que quiero. Y sin usar la resistencia como en el esquema que pusieron en un vídeo en el tacómetro.

Code: [Select]
static int NbTopsFan; // contador de impulsos.
const int fandiv = 2; // dos pulsos por vuelta
const int hallsensor = 2; // pin 2, que está unido a interrupción 0.

void rpm ()     // se llamará cada vez que se pruduce la interrupción
{
 NbTopsFan++;
}

 
void setup()
{
 //pinMode(hallsensor, INPUT);
 pinMode(hallsensor, INPUT_PULLUP);
 Serial.begin(115200); // 115200
 attachInterrupt(0, rpm, RISING);
}
void loop ()
{
   NbTopsFan = 0;
   sei();   
   delay (1000);
   cli();
   int Calc = ((NbTopsFan * 60)/fandiv);
   Serial.print (Calc, DEC);
   Serial.print (" rpm\r\n");
}


Donde pone delay(1000) quise poner    millis(1000);

Me parece que es mejor y más preciso, a parte de no dejar esclavo Arduino durante ese tiempo. Si no es importante como creo, pues lo dejamos en Delay y me dejo de tonterías.

Los RPM se muestra en cada segundo, no en menos tiempo para al menos que se parezca en tiempo real, ya que si reduzjo los RPM, tarda un segundo en ver los nuevos datos.

¿Hay alguna manera de hacerlo más rápido la lectura de los RPM?


Como los coches, que no tardan cada segundo en mostrar cada revolución.

Muchas gracias por la ayuda a todos.

noter

Claro que se puede mostrar cada menos tiempo. En el código actual no hay diferencia entre delay y millis, porque no necesitas hacer nada durante el tiempo de medida. En cuanto a actualizar a más frecuencia, claro que es posible. Ahora lo que te limita es que hay que dejar suficiente delay como para que le de tiempo a serial print a completarse, pues en caso contrario llenas el buffer.
Supongo que a 115200bps así le daría tiempo a refrescar:

Code: [Select]
void loop ()
{
   NbTopsFan = 0;
   sei();   
   delay (100);
   cli();
   int Calc = ((NbTopsFan * 600)/fandiv);
   Serial.print (Calc, DEC);
   Serial.print (" rpm\r\n");
}

Metaconta

Buenas:

Que curioso, si lo pongo a 100 el delay con el 115200 los RPM como máximo son algo más de 400 RPM, si halo lo mismo pero con el delay a 1000 como estaba son unos 3600 RPM.

¿Esto es normal?

Saludos.

noter

Sospecho que igual nos estamos saliendo del rango de int en los cálculos.
Cambia las declaraciones de Calc, NbTopsFan y fandiv de int a long.

Metaconta

Los puse todo a long, se comporta como si tuviera 300 RPM.

Code: [Select]
static long NbTopsFan; // contador de impulsos.
const long fandiv = 2; // dos pulsos por vuelta
const int hallsensor = 2; // pin 2, que está unido a interrupción 0.

void rpm ()     // se llamará cada vez que se pruduce la interrupción
{
 NbTopsFan++;
}

 
void setup()
{
 //pinMode(hallsensor, INPUT);
 pinMode(hallsensor, INPUT_PULLUP);
 Serial.begin(115200); // 115200
 attachInterrupt(0, rpm, RISING);
}
void loop ()
{
   NbTopsFan = 0;
   sei();   
   delay (100);
   cli();
   long Calc = ((NbTopsFan * 60)/fandiv);
   Serial.print (Calc, DEC);
   Serial.print (" rpm\r\n");
}

noter

De momento cambia un error mío que aparentemente no tiene importancia, pero puede tenerla. En la primera línea, en lugar de static debería poner volatile (no sé en qué estaría pensando).
Sigo revisando a ver.

noter

#26
Oct 15, 2015, 09:45 pm Last Edit: Oct 15, 2015, 10:04 pm by noter
En segundo lugar, en la fórmula debes multiplicar el número de ticks por 600; no por 60, ya que estamos contando los ticks que se producen en una décima de segundo (delay 100 ms), no en un segundo.

... Lo que me lleva a pensar que con este sistema la variación va a ser sobre múltiplos de 600, con lo que la precisión no va a ser muy buena.

Por aquí se ha dicho varias veces, ahora que me acuerdo, que para bajas frecuencias es más efectivo calcular la frecuencia midiendo el tiempo entre ticks (periodo), y para altas contando ticks.

noter


Metaconta

Es deicr, si pongo el delay a 100, el de 60 tengo que ponerlo a 600. ¿Es lo que te refieres?

No se si le falta precisión, pero si funciona.

Por cierto, si el código anterior de arriba de delay a 1000 y el calc a 60 tiene más precisión, pues dejaré ese. ¿Cómo sabemos cuando tiene mñas precisión uno que el otro?

Code: [Select]
volatile long NbTopsFan; // contador de impulsos.
const long fandiv = 2; // dos pulsos por vuelta
const int hallsensor = 2; // pin 2, que está unido a interrupción 0.

void rpm ()     // se llamará cada vez que se pruduce la interrupción
{
 NbTopsFan++;
}

 
void setup()
{
 //pinMode(hallsensor, INPUT);
 pinMode(hallsensor, INPUT_PULLUP);
 Serial.begin(115200); // 115200
 attachInterrupt(0, rpm, RISING);
}
void loop ()
{
   NbTopsFan = 0;
   sei();   
   delay (100);
   cli();
   long Calc = ((NbTopsFan * 600)/fandiv);
   Serial.print (Calc, DEC);
   Serial.print (" rpm\r\n");
}


voy a husmear el código del enlace que me dejaste.

noter

Exactamente. Si en lugar de tomar muestra durante un segundo la tomas durante una décima, para calcular lo que corresponde a un minuto deberás multiplicar por 600 en lugar de 60.
Por lo tanto, un solo tick de más (o de menos) medido en esa décima de segundo, traspasado a minuto (rpm) se convierte en 600 pulsos, por lo que las rpm subirán en múltiplos de 300 (600/2 ticks por vuelta).
No he mirado el código de Nick, pero te garantizo que sacará partido al máximo de las capacidades del timer del arduino.

Go Up