Video
Schematic
The Fan
Code
Download RPM.ino
// read RPM volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile int rpm = 0; unsigned long lastmillis = 0; void setup(){ Serial.begin(9600); attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2). } void loop(){ if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/ detachInterrupt(0); //Disable interrupt when calculating rpm = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/ Serial.print("RPM =\t"); //print the word "RPM" and tab. Serial.print(rpm); // print the rpm value. Serial.print("\t Hz=\t"); //print the word "Hz". Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or enter.*/ rpmcount = 0; // Restart the RPM counter lastmillis = millis(); // Uptade lasmillis attachInterrupt(0, rpm_fan, FALLING); //enable interrupt } } void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/ rpmcount++; } // Elimelec Lopez - April 25th 2013Code v2 (Calculate Average)
Download RPM_V2.ino
// read RPM and calculate average every then readings. const int numreadings = 10; int readings[numreadings]; unsigned long average = 0; int index = 0; unsigned long total; volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile unsigned long rpm = 0; unsigned long lastmillis = 0; void setup(){ Serial.begin(9600); attachInterrupt(0, rpm_fan, FALLING); } void loop(){ if (millis() - lastmillis >= 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/ detachInterrupt(0); //Disable interrupt when calculating total = 0; readings[index] = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/ for (int x=0; x<=9; x++){ total = total + readings[x]; } average = total / numreadings; rpm = average; rpmcount = 0; // Restart the RPM counter index++; if(index >= numreadings){ index=0; } if (millis() > 11000){ // wait for RPMs average to get stable Serial.print(" RPM = "); Serial.println(rpm); } lastmillis = millis(); // Uptade lasmillis attachInterrupt(0, rpm_fan, FALLING); //enable interrupt } } void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/ rpmcount++; }
rpmcount should be volatile see: http://arduino.cc/en/Reference/Volatile.
ReplyDeleteO.K
ReplyDeleteThank you very much, I changed the code.
What is the pair of IR led and diode you are using, can you provide a datasheet or link from where to buy them?
ReplyDeleteAre they suitable for a distance of about 5 inch?
Does this work of low rpm (approx 100rpm) ?
Thanks :)
Hello,
ReplyDeleteI'm using an IR photodiode and an standard IR transmiter. You can use any IR receiver and transmiter.
Of course, it will work with low RPM. I'm not sure about the distance, but you can try or use an IR laser instead.
Elimeléc
Here is the datasheet of the Photodiode:
ReplyDeletehttps://www.dropbox.com/s/kw0pl4yfdj2eb99/Photo_diode_S186p.pdf
This comment has been removed by the author.
ReplyDeletesketch_jan14a.ino: In function 'void setup()':
ReplyDeletesketch_jan14a:12: error: 'rpm_fan' was not declared in this scope
sketch_jan14a.ino: In function 'void loop()':
sketch_jan14a:26: error: 'rpm_fan' was not declared in this scope
getting these errors
Hello, Nitin
ReplyDeleteThe problem was in the comments, now you should be able to copy and paste. I also added the link to download the .INO file directly.
Elimelec
amigo felicitaciones ahora mi pregunta es si con esto puedo hacer que mida las revoluciones de la velocodad de mi carro y con esto ver si en un segundo han cambiado osea han aumentado y activar o desactivar algo , saludos y graci spor su ayuda
ReplyDeleteamigo no se que paso se cambio lo que escribi , quiero implementar este codigo para que en sobrepase un determinado numero de revoluciones me active o desactive alguna cosa se podra hacer me podria ayudar gracias
ReplyDeleteThanks for the response Elimelec. I am having issues with my project. Your code is not reading any input from the sensor. I dont see any analogread() for it to read the sensor. Where is it printing the results???? I think this is not the full code. Is there any way i can get the full code??? That will be really helpful
ReplyDeleteHola, Nicola
ReplyDeletePor supuesto que puedes hacer lo que deseas.
Elimelec
Hello, Nitin
ReplyDeleteThe code does not read any analog input, just a digital one and the result is printed over the serial port.
Elimelec
i am new in programming so i have alot of questions and i tried alot of sources before asking questions in this thread. How are you reading/ which digital pin are you using. According to my knowledge, i dont see any digitalread()/write in the code. Moreover, where can see this printed serial port data.
ReplyDeletethanks and regards
Hello, Nitin
ReplyDeleteThe reason you don't see the digitalRead function it's because we are using interrupts, the digital pin two (2) it's used as shown in the schematic. Please visit the following links to help you out:
http://arduino.cc/en/Reference/attachInterrupt
http://playground.arduino.cc/Code/Interrupts
http://www.jeremyblum.com/2011/03/07/arduino-tutorial-10-interrupts-and-hardware-debouncing/
http://www.ladyada.net/learn/arduino/lesson4.html
http://www.gammon.com.au/forum/?id=11473
Elimeléc
I am using this code for an RPM-display on an outboard-motor that contains a much larger setup-function, plus a Power On Self test.
ReplyDeleteThis results in the fact that millis is way over 10000 when the loop starts. As the loop is only called when millis - lastmillis equals a value, the arduino does nothing.
I suggest to use a ">= value" expression, to avoid this problem.
can i apply this code for motor dc?? so i can get the rpm of motor dc??
ReplyDeleteplease reply, i really need help, thank you
Yes, the motor in the video it's DC.
ReplyDeletese podría usar un sensor de inducción en lugar del sensor hall que habría que cambiar
ReplyDeletePuedes utilizar cualquier tipo de sensor, sólo tienes que hacer que se active ó desactive la entrada digital del arduino que se está utilizando para medir RPM, es probable que tengas que colocar algunos componentes para enlazar el arduino con el sensor, ejemplo: transistores.
ReplyDeleteRecuerda que necesitas un mecanismo que active y desactive rápidamente si vas a medir RPM muy altos.
Hello,
ReplyDeleteI tested the software with a square wave signal of 5 V, but it shown a frequency that was twice of the input source (PWM) frequency from a signal generator. COuld I read tension from arduino interrupt? What is the maximum tension it could read ? 3.3V? I have to read an hall sensor powered by a tension between 5V and 18 V.
Regards
Andrea