Just wanted to convey the outcome of a 2 week long battle to find a bug in my project.
Cliff Notes: Don't underestimate the CPU cost of doing even simple floating point operations.
I'm building a POV clock, spinning at about 1000rpm, with 32 LEDs and 360 rotation segments. Needless to say, my timings need to be pretty accurate. I was using a "float" for the decimal precision when dividing the total time per rev in microseconds by 360. I needed that decimal accuracy since as the arm swung around closer to the end of it's rotation, the precision would drift without the decimal accuracy. A simple single float operation doing just 1 divide. Well... I'd been struggling to find a strange "judder" issue. It was especially strange because it seemed to start out perfectly smooth, then slowly get worse and worse. It's worth noting , I'm using TeensyThreads to offload the much much slower image generation for some of the animations. So, I spent a good deal of time tweaking those thread timing thinking that was where the problem was.
Finally.. after stripping down the clock to it's bare functionality of just lighting up the LEDs (360x/rev), the judder was still there. This is when I finally just dropped the "float" in favor of multiplying the int values by 100 since I only really needed 1-2 decimals of precision. Voila!! judder gone.
My conclusion has to be that the float was expensive enough to slow down each of the 360 output steps (aprox 160us @ 1000rpm) by just enough, that the arm had moved too far along between grabbing the "micros()" value, and doing the math on it. I knew the Teensy3.2 didn't have a FPU on board, but I guess I just figured one float should not have cost that much CPU. Alas, it did.
So.. avoid floats.. if you can. I know I will in the future.
Cliff Notes: Don't underestimate the CPU cost of doing even simple floating point operations.
I'm building a POV clock, spinning at about 1000rpm, with 32 LEDs and 360 rotation segments. Needless to say, my timings need to be pretty accurate. I was using a "float" for the decimal precision when dividing the total time per rev in microseconds by 360. I needed that decimal accuracy since as the arm swung around closer to the end of it's rotation, the precision would drift without the decimal accuracy. A simple single float operation doing just 1 divide. Well... I'd been struggling to find a strange "judder" issue. It was especially strange because it seemed to start out perfectly smooth, then slowly get worse and worse. It's worth noting , I'm using TeensyThreads to offload the much much slower image generation for some of the animations. So, I spent a good deal of time tweaking those thread timing thinking that was where the problem was.
Finally.. after stripping down the clock to it's bare functionality of just lighting up the LEDs (360x/rev), the judder was still there. This is when I finally just dropped the "float" in favor of multiplying the int values by 100 since I only really needed 1-2 decimals of precision. Voila!! judder gone.
My conclusion has to be that the float was expensive enough to slow down each of the 360 output steps (aprox 160us @ 1000rpm) by just enough, that the arm had moved too far along between grabbing the "micros()" value, and doing the math on it. I knew the Teensy3.2 didn't have a FPU on board, but I guess I just figured one float should not have cost that much CPU. Alas, it did.
So.. avoid floats.. if you can. I know I will in the future.