ac dimming via inMojo AC Dimmer Module Lite

Status
Not open for further replies.

stephanschulz

Well-known member
i am working on a project for which i need to dim an AC light bulb.

i purchased this board and with the code below the dimming works great, when using an arduino uno.
http://www.inmojo.com/store/inmojo-market/item/digital-ac-dimmer-module-lite-v.2/

but when i try using the code with the teensy 3.0 the light flickers.

Code:
//http://www.youtube.com/watch?v=ztXRjyCQxlE
//backyard amusement
int redPin = 3;
int zeroPin = 2;

int minDimValue = 0; //0 is brightness value
int maxDimValue = 340; //550; //550 is lowest brihtness value
int dimValue = maxDimValue;


int dimStep = 5;
int dimDir = -1;

long crosstime = 0;
long currentcycle = 0;

unsigned long timer = 0;

boolean bNewCycle = true;
boolean bAutoFade = true;
boolean bOn = true;

void setup(){
  Serial.begin(9600);
  Serial.println("ac_dimmer_youtube_4");
  pinMode(redPin, OUTPUT);
  pinMode(zeroPin,INPUT);
}

void loop(){

  if (Serial.available()){
    handleInput(Serial.read());
  }

  if(digitalRead(zeroPin)){
    //Serial.println("read");
    crosstime = micros();
  } 
  zeroCross();

  if(bAutoFade){
    if(micros() - timer > 1500){
      timer = micros();
      dimValue += dimDir;

      if(dimValue >= maxDimValue){
        dimDir = -1;
        dimValue = maxDimValue;
      }
      if(dimValue <= minDimValue){
        // delay(2000);
        dimDir = 1;
        dimValue = minDimValue;

      }
    }
  }

}

void zeroCross(){

  if(bOn){
    if(micros() - crosstime < 8200){
      currentcycle = micros() - crosstime;
      if(currentcycle > (dimValue * 16)) digitalWrite(redPin,1);
      digitalWrite(redPin, 0); 
    }
  } else{
    digitalWrite(redPin, 0); 
  }
}

i also tried using an interrupt on pin 2, every time a zero crossing happens, and have it call zeroCross()

attachInterrupt(2, zero_crosss_int, RISING);

still flickers.

what might the difference be here, between the arduino and the teensy.

thanks.
 
this code works a bit better but still has moments where it goes off or on when it should not.

Code:
/*
AC Light Control
 
 Updated by Robert Twomey <rtwomey@u.washington.edu>
 
 Changed zero-crossing detection to look for RISING edge rather
 than falling.  (originally it was only chopping the negative half
 of the AC wave form). 
 
 Also changed the dim_check() to turn on the Triac, leaving it on 
 until the zero_cross_detect() turn's it off.
 
 Adapted from sketch by Ryan McLaughlin <ryanjmclaughlin@gmail.com>
 http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30
 
 */

//#include <TimerOne.h>           // Avaiable from http://www.arduino.cc/playground/Code/Timer1

volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 3;                // Output to Opto Triac
int dim = 0;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int inc=1;                      // counting up or down, 1=up, -1=down

IntervalTimer dimmingTimer;

int freqStep = 65;    // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want. 
// 
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply. 

// To calculate freqStep you divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps. 
//
// (1000000 uS / 120 Hz) / 128 brightness steps = 65 uS / brightness step
//
// 1000000 us / 120 Hz = 8333 uS, length of one half-wave.

void setup() {                                      // Begin setup
  pinMode(AC_pin, OUTPUT);  
  pinMode(2, INPUT);  // Set the Triac pin as output
  attachInterrupt(2, zero_cross_detect, RISING);   // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  // Timer1.initialize(freqStep);                      // Initialize TimerOne library for the freq we need
  // attachInterrupt(dim_check, freqStep);   
  dimmingTimer.begin(dim_check, freqStep);
  // Use the TimerOne Library to attach an interrupt
  // to the function we use to check to see if it is 
  // the right time to fire the triac.  This function 
  // will now run every freqStep in microseconds.                                            
}

void zero_cross_detect() {    
  zero_cross = true;               // set the boolean to true to tell our dimming function that a zero cross has occured
  i=0;
  digitalWrite(AC_pin, LOW);       // turn off TRIAC (and AC)
}                                 

// Turn on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      digitalWrite(AC_pin, HIGH); // turn on light       
      i=0;  // reset time step counter                         
      zero_cross = false; //reset zero cross detection
    } 
    else {
      i++; // increment time step counter                     
    }                                
  }                                  
}                                   

void loop() {                        
  dim+=inc;
  if((dim>=128) || (dim<=0))
    inc*=-1;
  delay(30);
}
 
Here is my code for the same device, Right now it just smoothly moves from off to on and back:

Code:
int PinInt1 = 23;

int AC_LOAD = 14;    // Output to Opto Triac pin
int dimming = 6200; 
int maxVal = 6200;
int incVal = 1;

elapsedMicros  sinceInterrupt;
int thePeriod = 0;
// int haveTriggered = 0;
int theOffset = 2048;
IntervalTimer timer0;

void setup()
{
  pinMode(AC_LOAD, OUTPUT);	      // Set the AC Load as output
  pinMode(PinInt1, INPUT);
  attachInterrupt(PinInt1, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
  
  Serial.begin(500);
}

void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  // Ignore spurious interrupts
  if (sinceInterrupt < 2000)
    return;
  thePeriod = sinceInterrupt;
  sinceInterrupt = 0;
  // haveTriggered = 0;
   
  timer0.begin(triacFire, theOffset + dimming);  // 4 mSec
}


void triacFire()
{
  timer0.end();
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(8.33);         // triac On propogation delay
  digitalWrite(AC_LOAD, LOW);    // triac Off  
}


void loop()
{
  dimming = dimming + incVal;
  
  if (dimming > maxVal) {
    incVal = -1;
    dimming = maxVal;
  }
  
  if (dimming < 0) {
    incVal = 1;
    dimming = 0;
  }
  
  if (Serial.available()) {
    int ser = Serial.read();
    if (ser > 10) {
      // Serial.print("Received character: ");
      // Serial.println(ser);
      
      ser = ser - 64;
      
      // Serial.print("Ser: ");
      // Serial.println(ser);
      
      if (ser > 32) {
        ser = ser - 33;
      }
      // Serial.print("Ser: ");
      // Serial.println(ser);
      
      if ((ser >= 0) && (ser < 9)) {
        dimming = ser * 16;
        Serial.println(dimming);
      }
    }
  }
  delayMicroseconds(500);
}
 
my next challenge is to use the FastLED.h library and try to use ws2801 led drivers to drive multiple AC dimmer circuits.
So far no luck. I am wondering if the ws2801 are too fast?
 
i gave up on trying to use the ws2801 to generate the on/off for the ac dimming.

@iblsys
what would you suggest to do in order to remove the delayMicroseconds(500); at the end of your loop ?
 
finally had some more time to work on this.
i am now able to dim 22 channels.
https://github.com/antimodular/multi-channel-ac-dimmer

but since i am using just one timer that gets called every 40 micros i see a very slight flicker in the lights.
i should mention that i am using AC LED light bulbs, which seem less forgiving then regular incandescent lights.

i also tried timer.begin() for 4 different lights during the zero crossing which produced flicker free lights.
but teensy 3.1 only has 4 interval timers. right?
i did read something about 12 hardware timers somewhere…

any input would be great.

maybe there is a hardware fix using a ac capacitor per channel to reduce the flicker?
or could one use many 555 timers and set their threshold values via the teensy? at the end of this post an 555 timer option is discussed: http://www.alfadex.com/dimming-230v-ac-with-arduino-2/
 
Status
Not open for further replies.
Back
Top