I am working on a 4-digit, 7-segment display that will show a number between 0 and 200, which reflects an efficiency percentage between a planned count and an actual count. The planned and actual counts max out at 99999999 and the percent rounds up or down to the nearest whole percent. I have the following code, using floats for the numbers, but the math is so intensive that the display flickers each time the count changes. How can I improve it to reduce the time?
void calculateEfficiency() {
if (plannedTotal > 0 && actualTotal > 0) {
float percent = (actualTotal / plannedTotal) * 1000.0;
effTenths = 0;
effOnes = 0;
effTens = 0;
effHundreds = 0;
if (percent >= 2000.0) {// Efficiency can't be greater than 200%
effOnes = 0;
effTens = 0;
effHundreds = 2;
}
else {
for (unsigned int i = 0; i < percent; i++) {
if (effTenths >= 9) {
effTenths = 0;
if (effOnes >= 9) {
effOnes = 0;
if (effTens >= 9) {
effTens = 0;
if (effHundreds >= 9) effHundreds = 0;
else effHundreds++;
}
else effTens++;
}
else effOnes++;
}
else effTenths++;
}
}
if (effTenths >= 5) {// round up or down...
if (effOnes >= 9) {
effOnes = 0;
if (effTens >= 9) {
effTens = 0;
if (effHundreds >= 9) effHundreds = 0;
else effHundreds++;
}
else effTens++;
}
else effOnes++;
}
}
}
I think the flcker does not come from the maths in this function but on the way you refresh the display. This is not present in the snippet of code you provided, so it's not easy to help. But, I believe that your loop runs very fast and updates the display each time, hence the flicker.
In order to reduce this, you have 2 possible solutions (among others...):
delay() the execution of the loop (the lazy way)
update the display only if it changes: store the previous value, compare it to the current one and update if different
lesept:
I think the flcker does not come from the maths in this function but on the way you refresh the display. This is not present in the snippet of code you provided, so it's not easy to help. But, I believe that your loop runs very fast and updates the display each time, hence the flicker.
In order to reduce this, you have 2 possible solutions (among others...):
delay() the execution of the loop (the lazy way)
update the display only if it changes: store the previous value, compare it to the current one and update if different
The way I refresh the display... is not based on the execution of this code, but based on a timed multiplexing of each digit, common cathode, at a nominal refresh rate of 120Hz. Although it is a 4-digit display, it draws 6 digits to match the intensity of 6-digit displays in close proximity, although there is nothing connected to those cathodes. 1 digit is lit for 1388 microseconds before moving to the next. It only flickers at the time this code executes and I am guessing that it takes longer than 1.388 milliseconds to divide 2 floats and break the result into 4 bytes, then execute a rounding, at least the way that I'm doing it, which is why I need some help.
Perehama:
The way I refresh the display... is not based on the execution of this code, but based on a timed multiplexing of each digit, common cathode, at a nominal refresh rate of 120Hz. Although it is a 4-digit display, it draws 6 digits to match the intensity of 6-digit displays in close proximity, although there is nothing connected to those cathodes. 1 digit is lit for 1388 microseconds before moving to the next. It only flickers at the time this code executes and I am guessing that it takes longer than 1.388 milliseconds to divide 2 floats and break the result into 4 bytes, then execute a rounding, at least the way that I'm doing it, which is why I need some help.
Use a timer interrupt to clock the multiplexer. That way there's no flicker no matter how long any one function blocks, since it will be done in the background.
The other option, if you still need to reduce computation time, is to use integers for fixed point math. Since you're dealing with a very small range of magnitudes in this computation the full functionality of floating point arithmetic is just wasteful.