Hit a wall trying to make a Frame Per Second Counter

I wonder if someone can help? I'm new to this and have done the usual blinking LEDs, PWM tutorials and am now out of my depths trying to marry two sketches together.

I'm trying to build a frames per second monitor (as in video/film frames) to measure revolutions per second (it needs to run from 0 to around 60 fps). I've a Hall Effect sensor working as the trigger working from a magnet that revolves past the sensor.

I believe my wiring is correct, the LCD screen works with a "hello world" sketch and I can run a sketch which blinks the LED when a magnet is passed by the Hall Sensor.

The base sketch I have been adapting is from a rpm outputting to LCD, triggered from an optical sensor. The descriptions I've added, to try and explain to myself what I think is going on (so there is room for plenty of error there).

At the moment when I run the sketch the LED comes on, the LCD lights up with "FPS: " but thats it, when a magnet is wafted by the Hall Sensor LED doesn't blink and the LCD doesn't count any frames, the count remains at 0.

// Compute the Frames Per Second using a Hall Sensor

#include <LiquidCrystal.h>
#define HALL_PIN 8 // Pin for signal from Hall Sensor
#define LED_PIN 13 //Using Arduino's Internal LED; just as an indicator

boolean counted=false; //The results to count are false
int t1=0,t2=0; //Creates variables t1 and t2 and gives them a value of 0
int hits=0;
int rps=0;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Sets pins for LCD

void setup(){ //Sets variables
  pinMode(HALL_PIN, INPUT); //Sets Pin 9 as the Input from Hall Sensor
  pinMode(LED_PIN, OUTPUT); //Sets Pin 13 as output to LED
  lcd.begin(16, 2); //Sets the size of the LCD display
}

void loop(){ //The action of the sketch
  t2 = millis();
  if(t2 >= (t1 + 1000)){
    rps = hits;
    hits = 0;
    t1=t2;

    lcd.clear(); //Clears LCD
    lcd.print("FPS: "); //Prints text FPS to LCD
    lcd.print(rps*1000); //Prints revolutions per second to x 1sec to LCD
  }  
  
  if(digitalRead(HALL_PIN) == HIGH){ //Counts instances of True from Hall_Pin, pin 8
    if(!counted){
      counted = true;
      hits++;
    }
  } else {
    counted = false;
  }
   
  digitalWrite(LED_PIN, digitalRead(HALL_PIN));
  
  if (HALL_PIN == HIGH){ //If the Hall sensor is high turn the LED off
    digitalWrite(LED_PIN, LOW);
  }
  else{
    digitalWrite(LED_PIN, HIGH); //If the Hall sensor is low turn the LED on
  }

}

I wonder if anyone had any pointers where I'm going wrong (you can see where I'm struggling there are no descriptions).

Has anyone ever seen really good tutorials going though feeding data to LCDs? I've been trawling through tutorials but can't find anything specifically that shows me where I might be going wrong, I've found plenty of tachometer references but not written for an idiot.

If I can get this working I'd like to next bolt on a frame counter, counting the number of times the magnet passes the Hall Sensor… But one thing at a time!

Many thanks in advance.
Gus

I had no trouble with the LCD tutorial here: http://arduino.cc/en/Tutorial/LiquidCrystal
This is 100 times more useful that the barebones info in the general reference.

You haven't spelled out what problem you're having. Is this an issue with making anything appear on the LCD? If so, I suggest using a simple hello world type sketch to work through that, and come back to your tachometer when you can reliably make things appear on the LCD. The tutorial should take care of that part.

For my money, think I would use an interrupt powered approach to the tachometer part. Have each rising edge from the sensor fire a pin-2 interrupt. Have the interrupt handler increment a count and save a timestamp indicating the time of the most recent two interrupts.

Then, in your main loop, you can take several different approaches to determining the actual RPM:
if the time since the last interrupt is a long time, then there are no pulses and RPM is 0.

if the time between interrupts is medium, (maybe 25 to 500 ms) then you can work out the rotational speed from that

if the time between interrupts is short, then use the count of interrupts to see how many have occurred in the last X seconds, and work out the rotational speed from that.

Thanks for taking the time to reply!

The LCD is working as in its prints "FPS:" on the screen but then nothing would appear to be counted, as in the the number of times per sec the hall sensor is triggered, not the LED flash (which I thought I added as a confidence measure to show if the trigger was working).

Thanks for your suggestion on how you would write the sketch, that makes sense to me other than what the actual code looks like, so I'm scouring everything I can find on interrupts and "if"s. I'm beginning to think I've bitten off more than I can chew.

I wonder if you had any more words of wisdom, pointers or references? It would be nice to see some sample code so I know what I'm aiming at.

Many thanks!

The LCD is working as in its prints "FPS:"

If it prints "FPS: ", then there should be something printed after that string, even if it is 0.

Try adding another lcd.print() after the lcd.print(rps*1000); statement, to print " rps".

  if (HALL_PIN == HIGH){ //If the Hall sensor is high turn the LED off
    digitalWrite(LED_PIN, LOW);
  }
  else{
    digitalWrite(LED_PIN, HIGH); //If the Hall sensor is low turn the LED on
  }

HALL_PIN was assigned the value 8. That is not equal to HIGH, now, is it?

HALL_PIN was assigned the value 8. That is not equal to HIGH, now, is it?

Sorry you've lost me... That part of the script worked when I used it "stand alone" as I borrowed it from here Hall effect sensor – Starter Kit.

Thanks for the tip with adding another lcd.print, I'll give that a bash when I get home.

awallace42:
Sorry you've lost me... That part of the script worked when I used it "stand alone" as I borrowed it from here Hall effect sensor – Starter Kit.

No, it really didn't:

void loop(){
hallState = digitalRead(hallPin);

if (hallState == HIGH){
digitalWrite(ledPin, LOW);
}
else{
digitalWrite(ledPin, HIGH);
}
}

That code's fine, it's reading the state of the hallpin into hallstate and testing it. You've adapted it so that it is checking the pin number against HIGH, not the reading from the digitalread

Here's an interrupt-driven sketch for measuring RPM using a Hall sensor, which you could adapt to display FPS instead. It prints to serial but you can change it to print to lcd instead.

const int sensorPin = 2;
const int sensorInterrupt = 0;
const int timeoutValue = 5;

unsigned long lastPulseTime;
volatile unsigned long interval = 0;
volatile uint8_t timeoutCounter;

bool blink = false;

void setup()
{
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);    // enable internal pullup (if Hall sensor needs it)
  attachInterrupt(sensorInterrupt, sensorIsr, RISING);
  Serial.begin(9600);
  lastPulseTime = micros();
  timeoutCounter = 0;
}

void sensorIsr()
{
  unsigned long now = micros();
  interval = now - lastPulseTime;
  lastPulseTime = now;
  timeoutCounter = timeoutValue;
}

void loop()
{
  Serial.print(" RPM ");
  unsigned int rpm;
  if (timeoutCounter != 0)
  {
    noInterrupts();
    --timeoutCounter;
    unsigned long copyInterval = interval;
    interrupts();
    rpm = (unsigned int)(60000000UL/copyInterval);
  }
  else
  {
    rpm = 0;
  }
  Serial.println(rpm);
  delay(500);
}