I am trying to make a simple orbital shaker which uses an A4988 driver and a stepper motor to give a precisely-controlled speed. (I know things like this already exist, but I wanted the learning experience and for the motor to start and stop very gently).
Originally I tried a few non-blocking stepper motor libraries but the motor would still do a little "pause" whenever the Arduino calculated the current speed. It really seemed like the non-blocking driver libraries aren't non-blocking at all!
Some users on here helped me out by suggesting I ditch the libraries and use timer interrupts to set the speed instead, so I followed a few tutorials on how to do that and wrote some code which averaged out the last 10 inputs for target RPM, calculated the CMR (compare match register) required for that speed, and set the CMR to achieve that speed. I am very new to this so I'm not sure if this is the "correct" way of doing things.
The problem is the equation that calculates the CMR. The code includes some serial output for diagnostics, in which you can see the desired RPM, the frequency (in Hz) of the output signal, and the CMR required to achieve that frequency. The frequency and RPM come out correct, but the CMR arbitrarily goes into negative numbers and back to positive, like this:
rpm: 3 freq: 20 cmr: 780 rpm: 4 freq: 26 cmr: 599 rpm: 5 freq: 32 cmr: -489 rpm: 6 freq: 40 cmr: -652 rpm: 7 freq: 46 cmr: -869 rpm: 8 freq: 52 cmr: -1303 rpm: 9 freq: 60 cmr: -3907 rpm: 10 freq: 66 cmr: 7811
I'm pretty sure I've made some simple math error somewhere, but I can't find it for the life of me and neither could my lab's resident engineer. Here is a link to my code – I would really appreciate if someone could point me in the right direction.