It seems your forgetting one thing - the amount of time the uC takes too calculate all the variables and lookup/s. This time will have to be measured and subtracted from the delay calculation for accurate ignition timing. I have done this using both counting clock tics (@16mhz) and just micro-seconds, this where a test bench comes in handy and a scope. For those that don't know the uC can only make delays to set the timing. So less delay - makes for advancing the timing and vice-a-versa more delay less timing, it can not predict the future. I try for setting the trigger pulse between 45 and 90 degrees BTDC to give the uC enough time depending on the application.@willray
The coil I am using likes to see as you say, about 4ms of dwell. This is the time to charge the coil and determines the energy of the spark. If my engine is running at 4000 RPM and I am using wasted spark where I fire both spark plugs every revolution of the crankshaft, I need to fire the spark plugs every 15 milliseconds. (4000 RPM is 66.7 Revolutions per second, or 1/66.7 = .015) Of this 15 milliseconds, 4ms is used to charge the coil. At 7500RPM, the crankshaft is turning 125 times a second, or once every 8 milliseconds. We still have half of this time to charge the coil.
When the engine is running, the crankshaft rotates and the magnetic sensor produces a reference pulse each revolution. These are fed to the microcontroller, which records the time of each reference to microsecond accuracy on an internal clock. From these times the RPM is calculated and the required timing advance angle is derived. The actual time of the next spark is calculated, and when the clock reaches this value, the pair of plugs fire. For starting, the priority is to prevent kickback and ensure a big spark. To achieve this the spark occurs at 3 degrees AFTER TDC. The active edge of the magnet is physically installed at this point and this generates the spark immediately. Both spark plugs are fired in my twin engine, thus one spark is “wasted” as it occurs at the end of the exhaust stroke, and so has no effect. The benefit of this is that no distributor is required and the accuracy of the spark timing is improved, as the timing is taken directly from the crank, not through the gear driven camshaft. The microcontroller does a number of other things as well as controlling the main timing process.
The spark timing is as follows: from 0 to 500 RPM the spark is fired 3 degrees after TDC. From 500 RPM to 1000 RPM the spark is advanced to 7 degrees before TDC. From 1000 RPM to 3000 RPM the timing is advanced linearly from 7 to 25 degrees before TDC. From 3000 RPM to 5000 RPM the timing is advanced to 25 degrees before TDC. Above 5000 RPM the spark is not advanced and set to TDC. This is an over rev limiter of sorts.
The microcontroller uses at minimum a 25 microsecond time base, which equates to one degree timing resolution up to 6667 RPM.
Does this answer your question?
I'm not sure what uC you are talking about but, a time base of 25 msec equates to a 40khz uC ?
With a UNO-R3 running at 16mhz the time base is 62.5 nsec between clocks (time base). Using an interrupt and as far as I know it takes 5 clock pulses just to activate the interrupt handling before any code execution. This is where you need to start a timer from when the trigger pulse is seen and stop it when the interrupt exits, take the number of counts and convert it to time, if you wish. You then subtract this from your ignition delay (actual ignition timing). I use clock counts to control my ignition time delay. All of this (trigger pulse width = RPM, calculation time, and timing lookup) must be measured as processing time. If you only have 1 coil firing per rev then add the coil charging time to your processing time to get your max RPM i.e. Calibration.
Calculating the RPM and firing delays is not that easy. Microchip has a micro-controller the PIC16LF1619 family that was designed to use angular velocity to do the RPM & processing but, it does not use pulse width, it instead uses the time between 2 trigger pulses. It was only designed for single cylinder engines or wasted spark for twins. They have demo software available but, their IDE software has a big learning curve compared to Arduino. In RCgroups we used the PIC12LF1840 (16Mhz) and got 11,000 rpm (single cylinder) out of it with 2 ignition curves stored on it. Programmable-Open-Source-CD-Ignition-PIC1840
Anyway that's my 2 cents worth for now and I hope it helps. Oh, the Excel spreadsheet I have included is for a V8 with triggers very 90 degree but, it still shows what is going on.
Cheers
Ray