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.