IF FOR loop problem

This is my code to work as a dimmer circuit using I2C.
Whenever I get ‘243’ from I2C then the bulb should get dim,
but instead of that my resistor burnt two times. So what I’m assuming is I made a wrong step calling for loop inside the ‘if’ loop. (I’m not much good at coding)
So help me through this obstacle.
Thanks

#include <Wire.h>
int led1=4;
int led2=5;
//int led3=5;
int DIM_AC_LOAD = 11;
int SC_AC_LOAD = 9; 
int dimming = 128;
//int temp=A0;

void dim_zero_crosss_int()
{ 
  int dimtime = (75*dimming);     
  delayMicroseconds(dimtime);  
  digitalWrite(DIM_AC_LOAD, HIGH); 
  delayMicroseconds(10);       
  digitalWrite(DIM_AC_LOAD, LOW);
}

void sc_zero_crosss_int()
{ 
  int dimtime = (75*dimming);     
  delayMicroseconds(dimtime);  
  digitalWrite(SC_AC_LOAD, HIGH); 
  delayMicroseconds(10);       
  digitalWrite(SC_AC_LOAD, LOW);
}

void setup() 
{
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
//  pinMode(led3, OUTPUT);
  pinMode(DIM_AC_LOAD, OUTPUT);
  pinMode(SC_AC_LOAD, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), dim_zero_crosss_int, RISING);
  attachInterrupt(digitalPinToInterrupt(3), sc_zero_crosss_int, RISING);
}

void loop() 
{
  delay(100);
}
void del()
{
  for (int a=5; a <= 128; a++)
        {
        dimming=a;
        delay(100);
        }
}
void receiveEvent(int howMany) 
{
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
  
  if(x==243)
  {
  digitalWrite(led1,HIGH);
    del();
  }
  else 
  digitalWrite(led1,LOW);
  
  if(x==255)
  digitalWrite(led2,HIGH);
  else 
  digitalWrite(led2,LOW);

}

This is my Dimmer circuit which runs perfectly when there is no conditional loop (that is when for loop is not inside if loop) , but when I insert for loop inside if loop then the 1K resistor is getting burnt.
help appreciated
Thanks

dimmer_circuit.jpg

 if(x==255)

digitalWrite(led2,HIGH);
 else
 digitalWrite(led2,LOW);

Multi-line if() statements without braces are going to cause you problems. Never write this without the braces.

Run the CTRL-T auto-format function. If it seems to scramble your code then the code was wrong, not the formatter. After a while you will understand what it is training you to do and you'll do that without thinking.

void receiveEvent(int howMany) 

{
 int x = Wire.read();    // receive byte as an integer
 Serial.println(x);         // print the integer

You understand that receiveEvent() is an interrupt handler? You just attached it to an interrupt when you designated it as the onReceive event handler. You should never use Serial output inside an interrupt handler. Yes it works most of the time but sometimes it doesn't and things get burned.

void sc_zero_crosss_int()

{
 int dimtime = (75*dimming);    
 delayMicroseconds(dimtime);

Same problem again - delays aren't reliable inside interrupts.

Thanks for the reply.
Sir,
if there is a single statement inside an if() loop then {} braces aren’t important no Sir.
That’s the reason I haven’t kept.

When I’m using this Dimmer Code then its working fine even for a long time and nothing is getting burnt nor heated up.

/*

AC Voltage dimmer with Zero cross detection
Author: Charith Fernanado <a href="http://www.inmojo.com">  http://www.inmojo.com

</a>
Adapted by DIY_bloke
License: Creative Commons Attribution Share-Alike 3.0 License.
Attach the Zero cross pin of the module to Arduino External Interrupt pin
Select the correct Interrupt # from the below table 
(the Pin numbers are digital pins, NOT physical pins: 
digital pin 2 [INT0]=physical pin 4 and digital pin 3 [INT1]= physical pin 5)
check: <a href="http://arduino.cc/en/Reference/attachInterrupt">  http://www.inmojo.com

</a>

Pin    |  Interrrupt # | Arduino Platform
---------------------------------------
2      |  0            |  All -But it is INT1 on the Leonardo
3      |  1            |  All -But it is INT0 on the Leonardo
18     |  5            |  Arduino Mega Only
19     |  4            |  Arduino Mega Only
20     |  3            |  Arduino Mega Only
21     |  2            |  Arduino Mega Only
0      |  0            |  Leonardo
1      |  3            |  Leonardo
7      |  4            |  Leonardo
The Arduino Due has no standard interrupt pins as an iterrupt can be attached to almosty any pin. 

In the program pin 2 is chosen
*/
int AC_LOAD = 3;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

void setup()
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
 // digitalPinToInterrupt(2);
  attachInterrupt(digitalPinToInterrupt(2), zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}

//the interrupt function must take no parameters and return nothing
void zero_crosss_int()  //function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms 
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) 
  // For 60Hz => 8.33ms (10.000/120)
  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

  int dimtime = (75*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC    
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(10);         // triac On propogation delay 
         // (for 60Hz use 8.33) Some Triacs need a longer period
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}

void loop()  {
  for (int i=5; i <= 128; i++){
    dimming=i;
    delay(100);
   }
}

But when I want to run this code when I receive something from I2C then my resistor is getting burnt and the hunch what I have is that keeping the for() loop inside the if() loop is causing me this problem .

 if (x == 243)
  {
    digitalWrite(led1, HIGH);
      for (int a = 5; a <= 128; a++)
  {
    dimming = a;
    delay(100);
  }
  }
  else
    digitalWrite(led1, LOW);

So I want any hint how to control Dimming when I receive some data from I2C (like DIM5 means it should DIM upto 5, DIM80 means more DIM etc…)

if there is a single statement inside an if() loop then {} braces aren't important no Sir.

Important ? No
Required ? No
A good idea ? Yes

Hi,
Which resistor is getting hot and burnt?

Tom... :slight_smile:

the 1K resistor which is connected to MOC3021 6th pin and connected back to AC supply.

receiveEvent is an interrupt handler and it is very poorly crafted.

It is calling a function del() which uses delay(100). millis() and delay() do not work with in ISR because additional interrupts(timer 0 overflow) are disabled within the ISR.

Furthermore, I believe that there is also a conflict between the zero cross interrupt and the receive event interrupt. When the code is in the very length receive event block, the other interrupt for zero cross can not be executed.

I think that receiveEvent has to be redone to just receive the instruction(243 or 255) and pass that value into code running in loop()

delayMicroseconds() should work correctly within the zero crossing ISR, but the ISR is very long (milliseconds)
and the receiveEvent is blocked out during that period.

The AC dimmer program in the playground, uses a timer interrupt, rather than a blocking delay to trigger the triac. http://playground.arduino.cc/Main/ACPhaseControl

As you said I’ve changed the code and kept all the delay functions inside the loop instead of ISR, but even now its not working fine,I’m receiving the data too slowly.
Any solution appreciated
Thanks

#include <Wire.h>
int led1 = 4;
int led2 = 5;
int DIM_AC_LOAD = 11;
int volatile dimming = 128;
int wireValue;
void dim_zero_crosss_int()
{
int dimtime = (75 * dimming);
delayMicroseconds(dimtime);
digitalWrite(DIM_AC_LOAD, HIGH);
delayMicroseconds(10);
digitalWrite(DIM_AC_LOAD, LOW);
}
void setup()
{
Wire.begin(8);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
// pinMode(led3, OUTPUT);
pinMode(DIM_AC_LOAD, OUTPUT);
pinMode(SC_AC_LOAD, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), dim_zero_crosss_int, RISING);
}
void loop()
{
delay(100);
if ( wireValue != 0 ) {
if (wireValue == 243)
{
digitalWrite(led1, HIGH);
for (int a = 5; a <= 128; a++)
{
dimming = a;
delay(100);
}
}
else
digitalWrite(led1, LOW);
if (wireValue == 255)
{
digitalWrite(led2, HIGH);
for (int a = 5; a <= 128; a++)
{
dimming = a;
delay(100);
}
}
else
digitalWrite(led2, LOW);
}
}
void receiveEvent(int howMany)
{
Serial.print(howMany);
Serial.print('\n');
int x = Wire.read();
Serial.println(x);
wireValue = x;
}

,I'm receiving the data too slowly.

then remove the delays and increase the baud rate.

I'm receiving the data too slowly.

Please explain more. You receive a number. You enter a 12 second "for" loop. What is too slow?

What is sending the 243 or 255? How frequently is the data being sent?

void receiveEvent(int howMany)
{
Serial.print(howMany);
Serial.print('\n');
int x = Wire.read();
Serial.println(x);
wireValue = x;
}

You have been told several times to not place Serial.print statements within an interrupt handler. For debug purposes, set a boolean flag newData = true inside the interrupt handler. Check for the flag in loop. If it is true, print out whatever you want to see from the interrupt, and then set it false .

ishtiaqshaheer:
the 1K resistor which is connected to MOC3021 6th pin and connected back to AC supply.

What AC supply?

data is being sent from other UNO board with a delay of 7seconds

Ok I'll remove the serial statements :slight_smile:

AC Supply means to the 230V :slight_smile:

AC Supply means to the 230V

You said:-

the 1K resistor which is connected to MOC3021 6th pin and connected back to AC supply.

Tell me you are not connecting anything back to the AC supply please.

I think he is saying that the 1k resistor between his circuit and the AC supply is getting hot for some reason.

Imagine what would happen if it went short-circuit!

The original poster has not said any thing about the resistor on the output side of the MOC carrying the gate trigger to the triac getting hot since he fixed the ISR. He has not come back and explained about the “too slow”.
New data arrives every 7 seconds to modify a 12 second “for” loop.

In place of For loop I kept just "dimming=128" etc... (the dimming level) and now its working fine without any problem
Thanks for the replies

New data arrives every 7 seconds to modify a 12 second "for" loop.

Should I increase this 7sec to 13seconds???

Please post your revised code. Does it modify the output as you want?

Should I increase this 7sec to 13seconds???

Why not try it? The Arduino is an experimental and learning environment. You can see the effect of that change before you can get a reply from the forum.

How frequently do you want to send a new instruction? If it was “too slow” with 7 second updates, I would think it will be slower with 13? What are you trying to achieve?