Edit: Here are some extra comments about your question and your sketch, not necessarily related to the problem you are seeing.
You wrote:
measuring [loop()] with micros() proved it never took longer than 0.26ms.
It seems you measured incorrectly. Maybe you measured a version of the
program that was not printing so much to the serial port. Or maybe you
looked only at the first iterations of the loop, where
Serial.println()
is fast because the output buffer hasn't filled yet.
The following code is fragile:
bool accel(double increment, double newSpeed) { if (abs(Speed - newSpeed) < 0.1) { return true; } // ... }
The value 0.1 is arbitrary, and the “right choice” is dependent on the program timing. I suggest something more robust, like:
bool accel(double increment, double newSpeed) {
if (increment > 0) {
Speed = min(Speed + increment, newSpeed);
} else {
Speed = max(Speed + increment, newSpeed);
}
return Speed == newSpeed;
}
Note that, although it is generally recommended to not test floating
point numbers for exact equality, in this case it is safe, because
min()
and max()
return exactly one of their arguments.
The optimization consisting of calling motor::accel()
only during the
acceleration phase is futile: this methods takes an very tiny fraction
of the loop()
time. In the same vein, there would be no harm in
calling Servo::writeMicroseconds()
on every loop iteration, even if
some of the calls turn out to be useless.
The code would be more readable if instructions
was an array of
struct
rather than an array of arrays: this way the fields of each
instruction could have evocative names rather than numeric indices.
You are using too much floating point here. Most of the data fields,
including all the contents of instructions
, could be integers of
suitable length.