ISR inside of a FOR Loop..

Hi,

I’m a hardware guy that’s playing in the dark side. I’m running a PWM For loop, but want to do a few things inside of it, like handle a couple of ISR’s that keep track of time… I can set PWM, manually and it works…

int PWM;
int X = 0;
unsigned long first_pulse = 0;  // variable to be updated by the interrupt
unsigned long second_pulse =0;
unsigned long RPM;
int ADVANCE;


void setup() {
  // put your setup code here, to run once:

  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(5, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(13, LOW);
  attachInterrupt(0, A_DETECT, RISING);
  attachInterrupt(1, B_DETECT, RISING);
  Serial.begin(115200);  //turn on serial communication
   
  }
  
  


void loop()
{

  analogWrite(6, 100);// put your main code here, to run repeatedly:
  

  
}
  
void A_DETECT(){

  RPM =(millis() - first_pulse)/1000;
  //RPM =((1/(millis() - first_pulse))/1000)*60;
  //digitalWrite(13, LOW);
  first_pulse = millis();
  //Serial.print("Raw_RPM = ");
  //Serial.println(Raw_RPM);
  Serial.print("RPM = ");
  Serial.println(RPM);

   
}

void B_DETECT(){
  second_pulse = millis();
  ADVANCE = second_pulse - first_pulse;
  Serial.println(ADVANCE);
}

But to run a PWM sweep, and handle the ISR’s inside of the FOR loop, has me stumped…

  int PWM;
  int X = 0;
  int ADVANCE;
  unsigned long first_pulse = 0;  // variable to be updated by the interrupt
  unsigned long second_pulse =0; 
  unsigned long RPM;
   

void setup() {
  
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(5, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(13, LOW);
  attachInterrupt( 0, A_DETECT, RISING );
  attachInterrupt( 1, B_DETECT, RISING );
  Serial.begin(115200);  //turn on serial communication

  for (int PWM=100; PWM <= 240; PWM++)  //Setup PWM counter
    {
      analogWrite(6, PWM);
      delay(100);
      Serial.println(PWM);

  void A_DETECT(){
  RPM =(millis() - first_pulse)/1000;
  //RPM =((1/(millis() - first_pulse))/1000)*60;
  //digitalWrite(13, LOW);
  first_pulse = millis();
  //Serial.print("Raw_RPM = ");
  //Serial.println(Raw_RPM);
  Serial.print("RPM = ");
  Serial.println(RPM);
  }

  void B_DETECT(){
  second_pulse = millis();
  ADVANCE = second_pulse - first_pulse;
  Serial.println(ADVANCE);

  }


 
       
   }
      
  PWM = 0;
  analogWrite(6, PWM);

  }
 
  
void loop()
{
   
}

Any thoughts? Should I stick with hardware??

thanks,

Cam

You cannot define a function or ISR within a loop, or another function. Why would you want to do so?

The Arduino already keeps track of time with millis() and micros().

You can't use Serial.print etc in an ISR, READ THE DOCUMENTATION.

You never call an ISR and you have no FOR loop in that code.

Mark

What they said - you can’t define ISR’s inside other function. Like any other function, they must not be defined inside another function. You shouldn’t (not can’t - you can in current Arduino version. If you don’t believe me, take a look at HardwareSerial.cpp - they catch that case and busywait instead of relying on the ISR to reload UDR. Probably should have left it as it was, breaking everything, because it’s just enabling terrible coding practice) use serial.print in an ISR. ISR’s should execute quickly.

ISRs should never be called directly.

holmes4:
you have no FOR loop in that code.

Yes he does?

So, the context of this experiment is a DC motor, spinning an automotive distributor. I have an index pulse on the motor, that I use to capture time (ISR0), until a seperate input comes along and qualifies the time (ISR1). It's a digital version of an old Sun Distributor Machine...

Thanks

Sun Distributor Machine

So, let me see if I have this right.. You can't service an interrupt request inside of a loop or another function? what good are they if you can only run through them once??

But to run a PWM sweep, and handle the ISR's inside of the FOR loop, has me stumped...

So, let me see if I have this right.. You can't service an interrupt request inside of a loop or another function? what good are they if you can only run through them once??

You misunderstand. The interrupts run over and over again independently.

The ISR's do not need to be inside the FOR loop. Just sweep the PWM duty cycles to speed up the motor, and let the interrupts collect the advance/delay data.

If you know that the firing pulse is always advanced or delayed to the reference pulse, you could use one interrupt.

Thanks CattleDog. I figured I was missing something...

So, can I update variables with millis(), micros() reliably inside an ISR?

first_pulse = micros();

So, can I update variables with millis(), micros() reliably inside an ISR?

Yes. The variables must be global and declared "volatile unsigned long".