Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: ac dimming via inMojo AC Dimmer Module Lite

  1. #1

    ac dimming via inMojo AC Dimmer Module Lite

    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-m...dule-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.

  2. #2
    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);
    }

  3. #3
    Junior Member
    Join Date
    Mar 2014
    Posts
    1
    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);
    }

  4. #4
    that works great. thanks a bunch.

  5. #5
    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?

  6. #6
    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 ?

  7. #7
    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/

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •