Help with cadence sensor

Hi All, I'm trying to build a cadence sensor using a photo resistor and an IR LED. So far I can tell they can see/not see each other when I obstruct the view.

The problem is that it seems like the counting might be too slow? I need it to be able to count in the low hundreds per second.

I'm not super seasoned with arduinos, but I hope you can help me. The code is rather simple. Also, I'm suing a particle photon if that makes any difference.

// This #include statement was automatically added by the Particle IDE.
#include <LiquidCrystal_I2C_Spark.h>


LiquidCrystal_I2C *lcd;

int cadenceSensor = D6;
int LED = D7;
unsigned long lastTime = millis();
unsigned long thisTime;
int inter = 1 * 1000;
int count = 0;
int rpm;

//4 to 1 ratio



void setup(void)
{
    pinMode(cadenceSensor,INPUT_PULLDOWN);
    pinMode(LED,OUTPUT);
    Serial.begin(9600);
    lcd = new LiquidCrystal_I2C(0x27, 16, 2);
    lcd->init();
    lcd->backlight();
    lcd->clear();
    lcd->print("Turning On");
    attachInterrupt(cadenceSensor,update,RISING,2);
}


void update(){
    count++;
}

void loop(void)
{
    thisTime = millis();
    if(thisTime - lastTime >= inter){
        lastTime = thisTime;
        rpm = 60000 * count  / thisTime;
        lcd->clear();
        lcd->print(rpm);
        count = 0;
        
    }
}

You don't say which photo resistor you're using, but checking the data sheets of a few common ones shows that they have fairly slow response times, of around 20-30ms. If yours is similar, it would probably have trouble responding faster than about 20 times a second. Perhaps you might like to consider using a faster sensor, such as a photodiode or phototransistor.

I don't see any timing related problems with your code, which, and although you don't say which model of Photon you are using, I would expect to be able to handle at least several thousand counts per second.

Thanks for your reply.

I'm using one like this:

It came with a kit, so I don't have the datasheet.

You have to make count volatile.

volatile unsigned int count = 0;

I also have the habit of making stuff that should never go negative (like counters) unsigned. Not strictly necessary.

Also as an int is a two-byte variable, you have to switch off interrupts while reading it to calculate the rpm.

So your loop (with a few other changes) becomes:

void loop(void)
{
  if (millis() - lastTime >= inter) {
    lastTime += inter;
    noInterrupts();
    unsigned int c = count; // copy the value of count.
    count = 0; // reset the counter.
    interrupts();    
    rpm = 60 * c; // You can be quite sure to be here at exactly 1000 ms since the last time.
    lcd->setCursor(0, 0);
    lcd->print(rpm);
    lcd->print("     ");
  }
}

The change to the LCD code will make the update much more smoothly. The five spaces printed are to clear any extra numbers, if the new number has less digits than the old one.