Max rpm is 10500, and I want a signal that is precise within max 0.5 degree. Is that possible with the arduino? I have no intention in learning assembler for this project.
The math for this(?):
10500 rpm/60 secs = 175 rev/sec
1 sec / 175 rev / 360 degrees / 2 (to have a ½ degree) = 0.0000079 sec. to calculate, count time and set the output pin on the arduino.
That's 8us approx, which should be achievable. Using interrupts would give you pretty good resolution (1us or so?), but just polling an input ought to be good enough (there will be some jitter from the timer0 interrupts, could be an issue).
You need to keep recalculating the delay as it is a function of the current RPM - there should be enough time between pulses as you have over 5ms.
Next when the micros resets, I can't have it to fire at the wrong time, is it possible to make it skip the one output when that happens?
So long as you use the correct test roll-over is invisible - you do something like:
volatile long trigger_timepoint ;
volatile long last_timepoint ;
volatile long current_period ;
void loop ()
{
while (micros() - trigger_timepoint < 0)
{} // wait till trigger time
output_pulse () ;
while (micros () - trigger_timepoint >= 0)
{} // wait till trigger changes
}
void int_handler ()
{
this_timepoint = micros () ;
current_period = this_timepoint - last_timepoint ;
// current_angle is fixed-point 16.16 representation of the fraction of whole-revolution.
trigger_timepoint = this_timepoint + (current_angle * current_period) >> 16 ;
last_timepoint = this_timepoint ;
}
The important point is to subtract one time from another and then look at the sign, don't directly compare them.
I've given a suggestion as to how an interrupt driven variable delay could work - attach the int_handler to the relevant pin, and the main loop polls for changes in the trigger time, waits for that time and sends a pulse.