The Arduino digitalRead function appears to be non-blocking. It reads either a LOW or a HIGH. If the pin you’re reading from is not connected to anything, it will read a random value. Here is a simple pulse counter that also measure the duration of the HIGH or LOW part of the pulse.
int pulsePin = 3;
int ledPin = 13;
unsigned long highCounter = 0;
unsigned long duration = 0;
int pulse = 0;
int lastPulse = LOW;
unsigned long timeNow = 0;
unsigned long lastTime = 0;
void setup() {
pinMode(pulsePin, INPUT);
// enable the 20K pull-up resistor to
// steer the input pin to a HIGH reading.
digitalWrite(pulsePin, HIGH);
Serial.begin(9600);
Serial.println("Pulse Reader - Version 2");
}
void loop() {
pulse = digitalRead(pulsePin);
if (pulse != lastPulse) { // pulse has changed
timeNow = millis();
duration = timeNow - lastTime;
// blink the LED
digitalWrite(ledPin, pulse);
Serial.print(pulse);
Serial.print(" ,");
Serial.println(duration);
lastPulse = pulse;
lastTime = timeNow;
if (pulse == HIGH) highCounter++;
}
}
January 30, 2009 at 10:07 pm |
Since I posted this note, I’ve learned that there is better way to do this using interrupts. Arduino/Atmel offer two interrupts (pin 2, and pin 3) that could be used for this purposes. The advantage of the interrupts is that you wont miss a pulse. I’ll add a note on this later.
April 20, 2011 at 8:25 am |
can u tell me how i can use the arduino to count pulses.
i am doing a project for my electronics alevel,, i am building a Wind speed detector..the pulses are coming from a reflective opto switch, this is the rpm count and i have to divide this by the number of wind blades…..this is my sketch so far.. but it keeps reading RPM as 250/245….so, the speed as 2.35mph…..even though i haven’t connected the output of the reflective opto switch to the digital pin 2.
#include
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
volatile byte rpmcount;
unsigned int rpm;
float speed;
unsigned long timeold;
void setup()
{
lcd.begin(16, 2); // Set up the LCD’s number of columns and rows:
lcd.setCursor(0, 0); // Sets the posiion of the cursor
lcd.print(“Hello World”); // Print a message to the LCD.
lcd.setCursor(0, 1); // Sets the posiion of the cursor
lcd.print(“WSD2011″); // Print a message to the LCD.
delay(4000); // Delay for opening message
lcd.begin(16, 2); // Clear Screen
attachInterrupt(0, rpm_fun, RISING); // input signal, pin 2
rpmcount = 0;
rpm = 0;
timeold = 0;
}
void loop()
{
if (rpmcount >= 30) {
//Update RPM every 20 counts, increase this for better RPM resolution,
//decrease for faster update
// calculate the revolutions per milli(second)
rpm = ((30*1000/(millis() – timeold))*rpmcount)/6;
timeold = millis();
rpmcount = 0;
// WHEELCIRC = 2 * PI * radius (in meters)
// speed = (rpm * WHEELCIRC * “minutes per hour”) / “meters per miles”
// simplify the equation to reduce the number of floating point operations
// speed = 60* rpm* WHEELCIRC* 1/ 1609.344 —- In mph
speed = (60* rpm* 0.251)/1609.344;
lcd.setCursor(0, 0); // Sets the posiion of the cursor
lcd.print(“RPM:”); // Print a rpm lable to the LCD.
lcd.setCursor(6, 0); // Sets the posiion of the cursor
lcd.print(rpm,DEC); // Print rpm value
lcd.setCursor(0, 1); // Sets the posiion of the cursor
lcd.print(“Speed:”); // Print a speed lable to the LCD.
lcd.setCursor(7, 1); // Sets the posiion of the cursor
lcd.print(speed,2); // Print speed value
lcd.println(” mph”); // Speed unit
}
}
void rpm_fun()
{
rpmcount++;
//Each rotation, this interrupt function is run twice
}
April 20, 2011 at 8:30 am |
oh…. forgot to mention….even though the output is not connected a jumper wire has to be connected to show the readings…!!!!!!!!!