counting fast light pulses with analog in

Hello,
I am trying to improve upon some code that I wrote to count light pulses. More specifically, I built a machine to count labels on a roll (opaque labels on a white paper backing). The machine has an LED and photoresistor, with the LED shining through the label backing into the photoresistor. When the gap between labels goes by, the light to the photo resistor increases and I count that as one label passing by. The signal is basically a messy square wave. The “high” pulses are short - 50 to 100 milliseconds ballpark- but that is a long time by computer standards

Hardware: Leonardo ATmega32u4 plus Adafruit motor and LCD shields

Currently I use an Analog-in pin to measure the light level. In my code I constantly use analogRead(lightsensor) to get the reading to decide if a label or a gap is passing by at the moment, all inside while loops. Basically: while low: read sensor. While high: count = count-1, read sensor. Then repeat. I’ll put actual code at the end.

The issue is that at high speed it misses the light pulses. I’ve tried to make the code as lean as possible so the loops can run as fast as possible. I am averaging the light value over 3 readings to be eliminate outliers than can and do occur. At low speed, perhaps 4 labels per second, it is fine, but at higher speeds it misses them. I would like to be able to do 20 to 30 per second.

Any ideas on a better way to code this? Is there a better way to read the sensor quickly or do I need to go to a different input type? One reason I use the analog input is so I can adjust the definition of high and low easily in the code.

Actual code (I’ve removed a lot of extraneous stuff. Also note I have to check buttons to see if machine has been paused and I also update an LCD screen). Any ideas are appreciated. I’m a total Arduino noob.

//********************start printing*************************
  while (reset == 0) {   //make sure reset isn't pushed... are reset and pause used interchangably
    if (resume == 0)  {
      count = qty;   //if printing is NOT resuming from pause, set the count to the initial desired qty.  else, keep the same count going. 
    }

      lightlevel = analogRead(lightsensor); //check light level
      lightlevelavg=lightlevel;   
            myMotor->setSpeed(motorspeed);  //adjust the motor speed
    
      while (lightlevelavg < lightupper){    //dark while - a label is passing 
             
        motorspeed = analogRead(motorpot)/4;  //read pot to get motor speed
        myMotor->setSpeed(motorspeed);  //adjust the motor speed
        lightlevel = analogRead(lightsensor);
        lightlevelavg=0.6666*lightlevelavg+0.3333*lightlevel;     //rolling average of 3 readings
              uint8_t buttons = lcd.readButtons();
       if (buttons & BUTTON_SELECT) {       
         pause = 1; 
     
      }  //end dark while

        
      count = count-1;    //the dark while loop has ended, so light must be present... count the label
             
         lightlevel = analogRead(lightsensor);
   
         lightlevelavg=lightlevel;

      while (lightlevelavg >= lightlower){   //wait while light gap goes by
         lightlevel = analogRead(lightsensor);
          lightlevelavg=0.6666*lightlevelavg+0.3333*lightlevel;
             uint8_t buttons = lcd.readButtons();
       
        if (buttons & BUTTON_SELECT) {
          pause = 1;
               }  //end pause
        //Serial.println(pause);
         }     //end of light while loop

      // 
      lcd.clear();
      lcd.setCursor(0,0); 
      //display qty remaining
      lcd.print(count);
      lcd.setCursor(8,1);
           
      
      //lcd.setCursor(1,0); 
      //lcd.print(lightlevel);

      //end if
      if  (count<1)  {   //done printing; pause it.

There are two major problems with your approach: photoresistors are very slow, and analogRead() is slow.

You can avoid both problems by using a phototransistor as the detector, and a digital input.