Strange observation in code working, help needed

I am a hobbyist. I coded some IGBT firing program as enclosed. A very basic one.
General working is explained in it.

I have a strange observation.

The code gets stuck after Round 19.
However if you swap the next two statements in code (ref ISR routine), it work.

Round = Round + 1;
IGBTdelay = (500*Round);

I just would like to know what exactly causes the program to get stuck.
and also by swapping why it runs.

I have recently started working on Arduino and my knowledge of C++ is limited.
Seniors should be able to get me some clarification.
Regards
Milan

DemagProgram1.ino (6.78 KB)

First of all, which Arduino? I suppose some with ATmega MCU. Right? Your ISR looks pretty long, and even there is a delay. It is not recommended approach. Just set flag and do the stuff in main loop. Function SelectDivFactor looks horrible to me, why do not use an array? BTW: I'm suspecting you are not hobbyist nor your program is for hobby.

Hi, Welcome to the forum.

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html . Then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :)

Wouldn’t it make more sense to constrain FSelect BEFORE you use it rather than AFTER?

  if (FSelect < 1)  //limiting FSelect value
  {
    FSelect  = 1;
  }
  if (FSelect > 25) //limiting FSelect value
  {
    FSelect  = 25;
  }

The Arduino way to do that:

FSelect = constrain(FSelect, 1, 25);

If you are interrupting ever 10 milliseconds and your ISR has a delay of 20 half-milliseconds (Round*500) then your next interrupt will occur during your ISR and as soon as the ISR exits it will be called again. That is probably why your sketch hangs after Round 19.

YOUR ISR SHOULD TAKE LESS THAN ONE MILLISECOND! If you think you need an ISR that takes more than a millisecond, you are doing things wrong. :frowning:

Budvar10: First of all, which Arduino? I suppose some with ATmega MCU. Right? Your ISR looks pretty long, and even there is a delay. It is not recommended approach. Just set flag and do the stuff in main loop. Function SelectDivFactor looks horrible to me, why do not use an array? BTW: I'm suspecting you are not hobbyist nor your program is for hobby.

It is Arduino Uno R3. As long as ISR is finished within say 8mS I think it should not pose problem. (ISR occurance every 10mS). I am not conversant with raising a flag and using Array yet. Off late I took fancy on power electronics and this is my attempt to build cycloconverter. I am retired mechanical engineer. This tiny coding work took my 10days and couple of sleepless nights to think rethink and code. But I am enjoying it.

johnwasser:
Wouldn’t it make more sense to constrain FSelect BEFORE you use it rather than AFTER?

  if (FSelect < 1)  //limiting FSelect value

{
    FSelect  = 1;
  }
  if (FSelect > 25) //limiting FSelect value
  {
    FSelect  = 25;
  }





The Arduino way to do that:


FSelect = constrain(FSelect, 1, 25);





If you are interrupting ever 10 milliseconds and your ISR has a delay of 20 half-milliseconds (Round*500) then your next interrupt will occur during your ISR and as soon as the ISR exits it will be called again. That is probably why your sketch hangs after Round 19.


YOUR ISR SHOULD TAKE LESS THAN ONE MILLISECOND! If you think you need an ISR that takes more than a millisecond, you are doing things wrong. :(

johnwasser:
Wouldn’t it make more sense to constrain FSelect BEFORE you use it rather than AFTER?

  if (FSelect < 1)  //limiting FSelect value

{
    FSelect  = 1;
  }
  if (FSelect > 25) //limiting FSelect value
  {
    FSelect  = 25;
  }





The Arduino way to do that:


FSelect = constrain(FSelect, 1, 25);





If you are interrupting ever 10 milliseconds and your ISR has a delay of 20 half-milliseconds (Round*500) then your next interrupt will occur during your ISR and as soon as the ISR exits it will be called again. That is probably why your sketch hangs after Round 19.


YOUR ISR SHOULD TAKE LESS THAN ONE MILLISECOND! If you think you need an ISR that takes more than a millisecond, you are doing things wrong. :(

I was not aware of constrain function and usage. I am mechanical engineer and my C++ is limited.
The delay in ISR is microseconds. ISR occurrence is every 10mS. so as long as my ISR routine finishes within safe limit of 8mS it should be fine.

milanraul:
I was not aware of constrain function and usage. I am mechanical engineer and my C++ is limited.
The delay in ISR is microseconds. ISR occurrence is every 10mS. so as long as my ISR routine finishes within safe limit of 8mS it should be fine.

It’s not a C++ standard function - its part of the arduino library.

This will do funny things when micros() rolls over at 1 hour, 11 minutes:

  time1 = micros();             //note time for delay
  ZVCcount ++;                  //increase ZVCcount
  time2 = micros();             //note time for delay

  while (time2 < time1 + 25) {   //sort of delay for IGBT natural commutation
    ;
    time2 = micros();
  }            //note time for delayloop

Try:

  while (time2 - time1 < 25) {   //sort of delay for IGBT natural commutation
    ;
    time2 = micros();
  }            //note time for delayloop

Also your selectdivfactors may get out-of-bounds issues. Try:

const int divFactors[] = {
  -1, // not used
    2,    4,    6,   10,  20,
   32,   40,   50,   56,   66,
   80,  100,  110,  124,  142,
  166,  200,  250,  332,  400,
  420,  440,  460,  480,  500
};

void SelectDivFactor() {       //function to select DivFactor as per user btn elect
  FSelect = constrain(FSelect, 1, 25);
  DivFactor = divFactors[FSelect];
}

There are another interrupts which have to be performed, not only this one.

delayMicroseconds() will not work for large values - limiting the argument to 4000 I think will be reliable.

Better still don't use delay!!