I'm new here. I'm not a native speaker, so pardon my English.
I just received my Arduino Leonardo today. I tried some basic calculations and stuff like blinking and LCD interfacing. Its interesting.
I am now trying to make a tachometer with the Leonardo. I'm following this tutorial.
I guess the board they've used differs from the Arduino Leonardo (ie pin 3 is interrupt0
in the Leonardo but it is pin 2 in the Arduino Uno board used in the tutorial). I tried changing the pins on the program and reconnecting the circuit but it doesn't work.
Circuit
This is the code from the tutorial:
/* Optical Tachometer
*
* Uses an IR LED and IR phototransistor to implement an optical tachometer.
* The IR LED is connected to pin 13 and ran continually.
* Pin 3 (interrupt 0) is connected across the IR detector.
*
* Code based on: www.instructables.com/id/Arduino-Based-Optical-Tachometer/
* Coded by: arduinoprojects101.com
*/
int ledPin = 13; // IR LED connected to digital pin 13
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void rpm_fun() {
//Each rotation, this interrupt function is run twice,
//so take that into consideration for calculating RPM
//Update count
rpmcount++;
}
void setup() {
lcd.begin(16, 2); // intialise the LCD
//Interrupt 0 is digital pin 2, so that is where the IR detector is connected
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(0, rpm_fun, FALLING);
//Turn on IR LED
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
rpmcount = 0;
rpm = 0;
timeold = 0;
}
void loop() {
//Update RPM every second
delay(1000);
//Don't process interrupts during calculations
detachInterrupt(0);
//Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
//happened once per revolution instead of twice. Other multiples could be used
//for multi-bladed propellers or fans
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
//Print out result to LCD
lcd.clear();
lcd.print("RPM=");
lcd.print(rpm);
//Restart the interrupt processing
attachInterrupt(0, rpm_fun, FALLING);
}
Can anyone help me to fix the project? Has anyone here tried this project before?
Thank you!
-
Try removing the phototransistor, get a jumbercable from ground and insert and remove it a few time at the point where the resistor and the photodiode were connected. If any rpm shows up on the lcd, you'd know it's that photodiode that is faulty, or just not near enough to the ir-diode. The code looks fine, and INT0 is indeed on pin D3 instead of D2.Gerben– Gerben2014年07月10日 15:59:57 +00:00Commented Jul 10, 2014 at 15:59
-
Your circuit looks wrong to me (although I haven't worked much with phototransistors). Why do you not have a resistor for the LED? Is it one built for 5V? Also, as far as I know, phototransistors only conduct when there's light. It seems odd to add a pull up resistor so it always reads high...Anonymous Penguin– Anonymous Penguin2014年07月10日 20:36:33 +00:00Commented Jul 10, 2014 at 20:36
-
What specifically did you do when you said you tried changing the pins in the program? have you tried running the program stock and changing the wiring to use pin 3? Also, can you be more specific how it is not working? is it always printing 0 RPM?BrettFolkins– BrettFolkins2014年07月11日 17:08:02 +00:00Commented Jul 11, 2014 at 17:08
-
yeah it is always writing rpm = 0. I've changed the interrupt0 to pin 3 on leonardo. would you guys suggest some simple way to test attachInterrupt() with ir transistor, i have both 2 pinned ( ?, ? )and 3 pinned (+, out , -) ir transistors/sensors. thank you!x0x– x0x2014年07月12日 19:26:08 +00:00Commented Jul 12, 2014 at 19:26
1 Answer 1
First, make sure that your LCD routines and wiring are working, by trying to display something on it.
Second, the code isn't correct - it will have some fluctuations from one measurement to another.
One way to do it is to start timing only after the first pulse has arrived, and stop timing only after the last pulse has passed.
Something like this:
- Wait until a falling edge.
- Time0 is millis().
- Wait for N pulses to pass.
- Time0 is millis() minus time0.
Now with time0 and N you can calculate your rpm.
Edit:
Here is the above code at work, running Arduino on a PIC24.
The input signal is 10Hz, 1 pulse per revolution, aka 600 rpm.
As you can see the rpm read-out is precisely 600rpm. I'm running the code at 8x oversampling.
As I indicated earlier, your code will introduce uncertainty, as much as one period for the pulses. So in a single pulse measurement, the rpm can be anywhere from 0.5x of the true value to 1.0x of the true value.
Explore related questions
See similar questions with these tags.