1

I am using an Arduino to control an AC Phase Control Circuit to control some lamps. The problem is that the interrupts seem to break the code inside the loop(). This Code should just blink one lamp. But it doesnt! What I found out so far: The Led always has dim_level[22] so it seems like (at least the first) delay in the loop is skipped. The strange thing: When i add a statement that takes some time between the delays everything is working For example

void loop() {
  CH[0] = dim_level[0];
  Serial.println("---------------------------------------------------------");
  delay(500);
  CH[0] = dim_level[22];
  Serial.println("---------------------------------------------------------");
  delay(500);
}

The not working code:

#include <TimerOne.h>

unsigned char channel_1 = 7;    // Output to Opto Triac pin, channel 1
unsigned char channel_2 = 6;    // Output to Opto Triac pin, channel 2
unsigned char channel_3 = 5;    // Output to Opto Triac pin, channel 3
unsigned char channel_4 = 4;    // Output to Opto Triac pin, channel 4
unsigned char CH1, CH2, CH3, CH4;
unsigned char i = 0;
unsigned char delay_time = 1;   // delay ms or flashing SPEED
unsigned char clock_tick;        // variable for Timer1
unsigned char CHANNEL_SELECT;    // variable for channel select

unsigned char CH[] = {CH1, CH2, CH3, CH4};

unsigned char dim_level[] = {5, 8, 10, 12, 15, 18, 20, 25, 30, 35, 45, 50, 55, 60, 65, 70, 75, 80, 82, 85, 88, 92, 95}; // don't use this massive for 60Hz
// create new massive for 60Hz
void setup() {
  Serial.begin(2000000);
  pinMode(channel_1, OUTPUT);// Set AC Load pin as output
  pinMode(channel_2, OUTPUT);// Set AC Load pin as output
  pinMode(channel_3, OUTPUT);// Set AC Load pin as output
  pinMode(channel_4, OUTPUT);// Set AC Load pin as output
  attachInterrupt(1, zero_crosss_int, RISING);
  Timer1.initialize(100); // set a timer of length 100 microseconds for 50Hz or 83 microseconds for 60Hz;
  Timer1.attachInterrupt( timerIsr ); // attach the service routine here
  
}

void timerIsr()
{
  clock_tick++;
  if (CH[0] == clock_tick)
  {
    
    digitalWrite(channel_1, HIGH);   // triac firing
    delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
    digitalWrite(channel_1, LOW);    // triac Off
  }

  if (CH[1] == clock_tick)
  {
    digitalWrite(channel_2, HIGH);   // triac firing
    delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
    digitalWrite(channel_2, LOW);    // triac Off
  }

  if (CH[2] == clock_tick)
  {
    digitalWrite(channel_3, HIGH);   // triac firing
    delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
    digitalWrite(channel_3, LOW);    // triac Off
  }

  if (CH[3] == clock_tick)
  {
    digitalWrite(channel_4, HIGH);   // triac firing
    delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
    digitalWrite(channel_4, LOW);    // triac Off
  }
}



void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  clock_tick = 0;
}



void loop() {
  CH[0] = dim_level[0];

  delay(500);
  CH[0] = dim_level[22];

  delay(500);
}

Im new to arduino maybeIi miss some concepts but I read that interupts should not break delays outside interrupt

3
  • 1
    volatile qualify CH.
    – timemage
    Jun 28 at 16:09
  • I don't know whether or not it's appropriate to mark as as duplicate for this, but have a look at this question and the answer given there. If that makes things work, then maybe it makes sense.
    – timemage
    Jun 28 at 16:13
  • @timemage yes thats is - thank you. you want to post an answer? Jun 28 at 16:53
2

Like timemage mentioned i had to qualify ch as volatile. so:

volatile unsigned char CH[] = {CH1, CH2, CH3, CH4};

is the fix

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.