Thanks you for your answers, I really appricate your support. Here what I'm trying to achieve:
The application is a system to control the ignition timing of an engine. In chronoloical order here what I would like to do for each engine cycle:
1-I receive on D2 a trigger IN coming form a hall sensor, and starting and hardware interrupt
2-The hardware interrupt set a timer interrupt that will be the time to wait before the trigger OUT (spark), this time to wait will change at each cycle.
3- waiting for the time interrupt, I can compute next cycle timing
4- I can do a lower priority task like sending data out thru the serial interface
Constraints:
I need a 1 degree accuracy at 15000rpm it means that 1 and 2 must be done at max of 11µs
In my previous attempts I gave up using interrupts as it was too long but my code ended up being too complex to maintain (I plan to put it ompen source) and at that time I did not have to do task 4 (send serial data out).
you were right I messed up my measurement, I took back my notes here what I posted long ago: Quickest way to detect pin change - #8 by roscodemars - Programming Questions - Arduino Forum
With the hardware interrupt , takes 3.47µs (time between the LOW state on pin 2 and the ouput going to HIGH on pin 5
void setup() {
pinMode(2, INPUT);
pinMode(5, OUTPUT);
attachInterrupt(0, inter, FALLING);
}
void inter (void)
{
PORTD |= 1 << 5; //fast digitalwrite HIGH on output 5
PORTD &= ~(1 << 5); //fast digitalwrite LOW on output 5
}
void loop() {
// do nothing else than waiting for interrupts
Question:
Now I want to try to simulate 1 & 2 to measure the timining needed to process, with a sheduled interrupt timer of 1µs, I'm going to do it tonite, this is the code I have not tested yet, let me know if you find someting wrong, I'm not fmiliar with the prescaler, I'll give it a try.
I want the cleanest code as possible, I anticipating to be too slow on a nano to be usable, then I will try and compare it with a teensy 3.1 at 96Mhz
void setup() {
pinMode(2, INPUT);
pinMode(5, OUTPUT);
attachInterrupt(0, inter, FALLING);
Serial.begin(115200);
}
void inter (void)
{
//set a timer that will trigger only once and change of frequecy at each cycle
cli();//stop interrupts
//set timer1 interrupt at 1Mhz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1Mhz increments
//This will change at each cycle
OCR1A = 15; // = (16*10^6) / (1*10^6) - 1
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS10 presaceler 1
TCCR1B |= (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();//allow interrupts
}
//this enables the trigger OUT
ISR(TIMER1_COMPA_vect){
PORTD |= 1 << 5; //fast digitalwrite HIGH on output 5
delayMicroseconds(1);
PORTD &= ~(1 << 5); //fast digitalwrite LOW on output 5
TIMSK1 |= (1 << OCIE1A); //disable timer as it needs to be triggered only once
}
void loop()
{
Serial.print("Background low priority task");
delay(500);
}