Photogate Frequency

I was wondering if anyone here has any ideas for the project I am working on. Recently, I built a photogate to determine a frequency that is proportional to how fast a wheel is spinning. Right now the code I wrote can only determine the time difference between blocked and unblocked states with the millis() function and it is not very accurate. I was wondering if there was a better way to extract the frequency. The Arduino needs to execute a function at a speed proportional to the frequency of the photogate signal. The photogate is blocked at about 5.00 volts and unblocked at about 4.93 volts. Here is the code I have so far, It is not too good haha

code.ino (1.23 KB)

Please read and follow the instructions in the “How to use this forum” post.

Your code, posted properly for others to see:

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#define DISPLAYS_ACROSS 5
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);
int tmsb = 0;
int tmsu = 0;
int deltaTime = 0;
int i = 160;
int count = 0;
int ledPin = 5;
String gateStatus = "unblocked";

void scanDMD(){
  dmd.scanDisplayBySPI();
}

void setup(){
  Serial.begin(9600);
  Timer1.initialize(5000);
  Timer1.attachInterrupt(scanDMD);
  dmd.clearScreen(true);
  pinMode(ledPin, OUTPUT);
}

void drawBar(int i){
  dmd.drawLine(i,0,i,15,GRAPHICS_NORMAL);
 }

void loop(){
  int sens = analogRead(A0);
  float volt = sens * (5.0/1023.0);
  //Serial.println(volt);
  if(volt >= 4.99){
    gateStatus = "blocked";
    tmsb = millis();
    //digitalWrite(ledPin, HIGH);
    //delay(20);
    //digitalWrite(ledPin, LOW);
    }
  else{
    gateStatus = "unblocked";
    tmsu = millis();
    }
  //Serial.println(gateStatus);
  int deltaTime = tmsu-tmsb;
  if(deltaTime < 0){
    deltaTime = deltaTime*-1;
    }
  Serial.println(deltaTime);
      if(deltaTime <= 10){
        count = count + 1;
        if(count > 15){
          drawBar(i);
          if(i==0){
            dmd.clearScreen(true);
            i = i+160;
            }
          i=i-1;
        }
      }
  else{count = 0;}
}

Some comments:

  1. Don’t use analogRead(), it is too slow. Use a digital input instead.

  2. You should never attempt serial I/O within an interrupt. Usually it depends on interrupts, which are turned off within an interrupt routine.

  3. Always use unsigned long variables with millis() and micros(). You should carefully study the “Blink without Delay” example to learn how to time events.

  4. Beginners should avoid using interrupts, as they generally create more problems than they solve.

  5. Avoid using Strings. They cause unpredictable memory problems and program crashes.

  6. “the photogate is blocked at about 5.00 volts and unblocked at about 4.93 volts.” That means that the sensor is not working correctly. Fix that first.

Basically, you need to start over. There are plenty of tutorials on photogates for Arduino.