Pages: 1 2 3 [4] 5 6 ... 8   Go Down
Author Topic: Arduino AC Power Shield!  (Read 25047 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 74
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have seen alot of heater, fan, etc dimming doing exactly what you are describing.  SSR with a specific duty cycle, however I have not seen much lighting this way.

When I was doing some testing, I tried this without doing the zero crossing, but with lighting I could never the the flickering (which was major flickering) to go away.  But, this could just because I could not find the right duty cycle.

There two main types of light dimming.  These are the two found in your house.  Forward-phase control and Reverse-phase control. http://en.wikipedia.org/wiki/Phase_fired_controllers  

Forward phase control is waiting a specific amount of time after a zero cross, then turning on the device to let the remaining part of the wave power the load.  This is exactly what this project is doing.  Wait a specific amount of time after a zero cross and momentarily fire the triac to power the load.  Using zero-crossing triacs the triac will stay latched until the next zero cross.  This makes the device easy to control because you only have to control the firing once, and not ensure you turn off again at zero, which can be hard to time right.

Reverse phase control is the opposite where you turn on the triac at the zero cross and cut the power after a specified interval, cutting the trailing end of the wave.  This type of control is not as common, but the technology used to dim low voltage transformers for LV lighting in houses.  It is not as common because it is more expensive and only used where needed.  Go on Lutron or another lighting switch company and you will see that most of the high-end dimmers have an electronic low voltage style dimmer that uses this type of control.

Zero crossing SSR's are more popular because of this reason and they are cheaper.  I am not an EE, but if you look at the theroy behind a triac, it is setup to latch until a zero cross.  You need to find a special random-phase SSR to be able to turn off the power mid wave.

Quote
Switching time being about 0.1 ms. (10ms for the half cycle on European (etc) 50Hz mains remember.) So plenty fast enough switching!

Remember that that is only the 1/2 cycle, you still need to have the dimming resolution within that half cycle.  If you want smooth light dimming you are talking about > 50 divisions = 156 microseconds.  But, if you are doing element, fan dimming, this resolution can be far less as that_chap suggested
Logged

Atascadero, CA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 468
Arduino addict
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Some countries run at 400Hz, which is the high end that I've been testing against.  That's a 1.25ms (1250us) half-period - not very much time to work with.  For one channel of dimming control, I've gotten the minimum delay down to about 50us.  That's referenced to the falling edge of the previous half-period, so it gives a little wiggle room.
Logged

What about elevensies? Luncheon? Afternoon tea? Dinner? Supper?

0
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I guess my research isn't that bad after all.
Logged

Atascadero, CA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 468
Arduino addict
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I just connected a couple dots....    smiley-grin

that_chap kept talking about SSRs (Solid State Relays) and I kept reading it as SCRs (Silicon Controlled Rectifiers).

To clear things up a little: SSRs are made from a back-to-back pair of opto-controlled triacs, which means they are functionally the same as the triacs on Ryan's board.  So yes, you could use SSRs to do the load switching. However, when I look up the cost of SSRs vs. the cost of triacs with similar specs, the SSRs are an order of magnitude more expensive and considerably larger.

SCRs are sort of similar to triacs, but only conduct on one half of the wave, so you need two of them in inverse parallel to work like a triac.  But that would be pointless since you can just use a triac.

EDIT: NEW CODE IS FINISHED!!

OK, it works great at 50/60Hz but it's range isn't all that good at 400Hz.  The problem is that it takes about 500us to do all the timing calculations on four channels, which is about 2/5 of the half-period at 400Hz.  If you wanted just one channel, you could scale down the code and 400Hz would work fine with about 125us minimum dim.  But the dimming is smooth and more-or-less frequency agnostic. The lower the frequency, the better.

I intentionally did not use loops to cycle through the channels.  Loops added processing overhead and with four channels, it really wasn't that hard to keep track of.   Another weird-but-intentional thing is the placement of the OKToFire=0; lines.  I did this because it really didn't matter where these lines went in each section and it adds a little time delay between the digitalWrite lines without using delayMicroseconds() smiley-wink

You can see the code in action if you have a dual trace oscilloscope.  Attach one input to the interrupt pin and another to an output pin.  Sync to the interrupt pin and you will see how all the timing works together.

I fought with this code for days until I re-read the attachInterrupt() doc.  It states that millis() and delay() don't work in the ISR function.  That was key to success since I was trying to calculate all the timing in the ISR function, but was getting weird and inconsistent results.  Once I took all that out and put it in void loop(), all was better.

Code:
/*
  AC Light Control
  
  Ryan McLaughlin <ryanjmclaughlin@gmail.com>
  
  The hardware consists of an Triac to act as an A/C switch and
  an opto-isolator to give us a zero-crossing reference.
  The software uses two interrupts to control dimming of the light.
  The first is a hardware interrupt to detect the zero-cross of
  the AC sine wave, the second is software based and always running
  at 1/128 of the AC wave speed. After the zero-cross is detected
  the function check to make sure the proper dimming level has been
  reached and the light is turned on mid-wave, only providing
  partial current and therefore dimming our AC load.
  
  Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445
    and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm
 */
 
/*
  Modified by Mark Chester <mark@chesterfamily.org>
  
  to use the AC line frequency (half-period) as a reference point
  and fire the triacs based on that plus a dimmer delay value.
  I removed the second timer-based interrupt and replaced it with a
  means to reference the zero-crossing point as per interrupt 0.
*/

// General
unsigned long int ZeroXTime1 = 0;                      // Timestamp in micros() of the latest zero crossing interrupt
unsigned long int ZeroXTime2 = 0;                      // Timestamp in micros() of the previous zero crossing interrupt
unsigned long int NextTriacFire[4];                    // Timestamp in micros() when it's OK to fire the triacs again.
unsigned long int DimStep;                             // How many micros() in each step of dimming
int Dimmer[4];                                         // The dimmer input variable. One for each channel
byte TriacPin[4] = {4,5,6,7};                          // Which digital IO pins to use
boolean OKToFire[4];                                   // Bit to say it's OK for the triacs to fire
volatile boolean zero_cross = 0;                       // Boolean to store a "switch" to tell us if we have crossed zero

void setup() {                                         // Begin setup
  pinMode(TriacPin[0], OUTPUT);                        // Set the Triac pin as output
  pinMode(TriacPin[1], OUTPUT);                        // Set the Triac pin as output
  pinMode(TriacPin[2], OUTPUT);                        // Set the Triac pin as output
  pinMode(TriacPin[3], OUTPUT);                        // Set the Triac pin as output
  attachInterrupt(0, zero_cross_detect, FALLING);      // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  delay(50);                                           // Give the interrupt time to capture a few AC cycles
}                                                      // End setup
  
void zero_cross_detect() {                             // function to be fired at the zero crossing
  zero_cross = 1;                                      // All we do is set a variable that's picked up later in the code
}

void loop() {                                              // Main Loop
  if ( zero_cross ) {                                      // Did we detect a zero cross?
    ZeroXTime2 = ZeroXTime1;                               // shift the current zero cross value to the previous
    ZeroXTime1 = micros();                                 // set the new current zero cross time in micros()
    DimStep = (ZeroXTime1 - ZeroXTime2)/1024;              // Calc the duration of each dimming step
    Dimmer[0] = analogRead(0);                             // Read in a dimmer value (change to suit needs)
    Dimmer[1] = analogRead(1);
    Dimmer[2] = analogRead(2);
    Dimmer[3] = analogRead(3);
    NextTriacFire[0] = ZeroXTime1 + (Dimmer[0] * DimStep); // Calc the next triac fire time
    NextTriacFire[1] = ZeroXTime1 + (Dimmer[1] * DimStep);
    NextTriacFire[2] = ZeroXTime1 + (Dimmer[2] * DimStep);
    NextTriacFire[3] = ZeroXTime1 + (Dimmer[3] * DimStep);
    OKToFire[0] = 1;                                       // Tell us it's OK to fire the triacs
    OKToFire[1] = 1;
    OKToFire[2] = 1;
    OKToFire[3] = 1;
    zero_cross = 0;                                        // Done.  Don't try again until we cross zero again
  }
  if ( OKToFire[0] && micros() >= NextTriacFire[0] ) { // Are we OK and past the delay time?
    digitalWrite(TriacPin[0], HIGH);                   // Fire the Triac mid-phase
    OKToFire[0] = 0;                                   // We fired - no longer OK to fire
    digitalWrite(TriacPin[0], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  if ( OKToFire[1] && micros() >= NextTriacFire[1] ) { // Are we OK and past the delay time?
    digitalWrite(TriacPin[1], HIGH);                   // Fire the Triac mid-phase
    OKToFire[1] = 0;                                   // We fired - no longer OK to fire
    digitalWrite(TriacPin[1], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  if ( OKToFire[2] && micros() >= NextTriacFire[2] ) { // Are we OK and past the delay time?
    digitalWrite(TriacPin[2], HIGH);                   // Fire the Triac mid-phase
    OKToFire[2] = 0;                                   // We fired - no longer OK to fire
    digitalWrite(TriacPin[2], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  if ( OKToFire[3] && micros() >= NextTriacFire[3] ) { // Are we OK and past the delay time?
    digitalWrite(TriacPin[3], HIGH);                   // Fire the Triac mid-phase
    OKToFire[3] = 0;                                   // We fired - no longer OK to fire
    digitalWrite(TriacPin[3], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
}
« Last Edit: April 02, 2009, 05:33:49 am by koyaanisqatsi » Logged

What about elevensies? Luncheon? Afternoon tea? Dinner? Supper?

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 74
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks koyaanisqatsi that looks great, the code is so short!  I will try this on my own board soon.

My only question is what do you do about if you need to run other code?  If you are using the Arduino for anything else (LCD, I/O, etc) won't it mess with the timing?  I just ask because this was why I started to use Timer1 so I ensured the dimming function worked as a software interrupt and my regular code would not interfere.

Let me know your thoughts.  Great work!  I guess I should get working on a final design now.  In your testing were you getting much buzz from the Triac?  I am trying to figure out how to silence it a bit, maybe an inductor but I need to pick a few up to try it.
Logged

England
Offline Offline
Newbie
*
Karma: 0
Posts: 44
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

koyaanisquatsi -
Quote
Some countries run at 400Hz ...
Domestic mains electricty at 400 Hz? Really? Where about would that be??
I think that all large populations get their mains notionally at either 50 or 60 Hz (though it always varies slightly with the supply/demand balance varying).


Regarding SSRs (Solid State Relays), my thinking of their usefulness is that :
- they are a sealed module, even the terminals are usually well-shrouded
- they provide excellent opto-isolation of the controller from the mains
- they can be immediately usable (driven absolutely direct from an Arduino digital-out pin)
- their 'pinout' encourages the physical separation of mains and logic-level control voltages

They aren't tiny. The "25 amp" units I mention are about the same footprint as a standard Arduino.
But with mains, size and space are good for you. Cramming mains things tightly together is not a great idea. Space allows heat dissipation and physical isolation.

I don't think SSRs need be very expensive. (Even though I admit to being 'cost-conscious'!) Searching eBay.com turned up a few vendors seemingly competing at the US$8 price point including delivery worldwide - for units able to switch a nominal 25 amps (with a suitably big heatsink). They should switch 5 amps (or run 3 amps pretty continuously) of resistive load, happily without any heatsink.
You can find (smaller) lower power rated devices, but probably not much cheaper.

IMHO, SSRs are a great way for "Arduino tinkerers" to explore mains control with a massively greater degree of safety than with Ryan's shield. Even so, I'd still advise great care be taken.
But, as I said to Ryan, his quad-triac with sensing of mains timing could be a neat unit to have, as long as it was really well isolated from the Arduino (or other tinkerers' platform) and from the fingers (etc) of the 'tinkerers' themselves.
Absent that, an SSR seems to me to tick the right boxes.
« Last Edit: April 02, 2009, 10:59:03 am by wdh » Logged

Atascadero, CA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 468
Arduino addict
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Domestic mains electricty at 400 Hz? Really? Where about would that be??
Well, you got me on that one.  It seems my memory has misled me.  400Hz is used in certain systems, but not as a municipal/utility power grid due to efficiency issues.  So with 400Hz support, this project can be used in certain aerospace applications.   smiley-grin

http://en.wikipedia.org/wiki/Utility_frequency#400_Hz

It's just as well.  The performance of the code at 400Hz wasn't very good, and now I don't have to be annoyed about it.

Ryan, I am concerned about the performance of the code with other things going on too - and it _will_ suffer if much more than a few very simple tasks are being done.  I hadn't thought of a good way to handle that as of last night.  But since you mentioned the software interrupt, I'm rolling that around in my head now.  We'll see what I can come up with over the weekend.  I should know better than to say "NEW CODE IS FINISHED!!"  Is software every really finished?   smiley-wink
Logged

What about elevensies? Luncheon? Afternoon tea? Dinner? Supper?

Atascadero, CA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 468
Arduino addict
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, I am really stoked with this version of code!  Oddly enough, some of it boiled back down to something similar to what you were doing originally.  But it has the following features now (again):

o Four independent output channels with their own inputs.
o Interrupt driven triggering for timing accuracy, even with other code in loop()
o Tracks changes in the line frequency and adjusts accordingly
o Tested with up to 512 steps of dimming resolution (could go higher? max is dependent on line freq, YMMV)

Here's a couple thoughts that may save a few clock cycles:
1. The triac pulse is 6us in the current code.  Removing the 2us delay reduces it to a 4us pulse.  How long does the pulse need to persist to properly fire the triac?
2. If we can leave the triac pins high until the next zero cross, we can save even more clocks.

Code:
/*
  AC Light Control
  
  Ryan McLaughlin <ryanjmclaughlin@gmail.com>
  
  The hardware consists of an Triac to act as an A/C switch and
  an opto-isolator to give us a zero-crossing reference.
  The software uses two interrupts to control dimming of the light.
  The first is a hardware interrupt to detect the zero-cross of
  the AC sine wave, the second is software based and always running
  at 1/128 of the AC wave speed. After the zero-cross is detected
  the function check to make sure the proper dimming level has been
  reached and the light is turned on mid-wave, only providing
  partial current and therefore dimming our AC load.
  
  Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445
    and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm
 */
 
/*
  Modified by Mark Chester <mark@chesterfamily.org>
  
  to use the AC line frequency (half-period) as a reference point
  and fire the triacs based on that plus a count of dimming steps.
  Tracks the line frequency and adjusts accordingly.  Can set up to
  an estimated 512 steps of dimmer resolution.
  
*/

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

// General
unsigned long int ZeroXTime[4] = {0,0,0,0};            // Timestamp in micros() of the zero crossing interrupts
unsigned long int DimStep;                             // How many micros() in each step of dimming
unsigned long int AvgPeriod;                           // The average line voltage period in micros()
unsigned long int PeriodResync = 3000;                 // Number of milliseconds between line freq measurements
unsigned long int ResetPeriod = PeriodResync;          // The timestamp in millis() when we will measure the period again
unsigned long int DimRes = 256;                        // How many steps of dimmer resolution
volatile unsigned long int DimStepCounter;             // For counting Timer1 interrupts
volatile unsigned long int FireTriac[4] = {0,0,0,0};   // When it's OK to fire the triacs, in counts of DimRes
volatile boolean zero_cross = 0;                       // Tels us we've crossed the zero line
byte TriacPin[4] = {4,5,6,7};                          // Which digital IO pins to use

void setup() {                                         // Begin setup
  Timer1.initialize(DimStep);                          // Start up the Timer1 timer
  attachInterrupt(0, zero_cross_detect, FALLING);      // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  pinMode(TriacPin[0], OUTPUT);                        // Set the Triac pin as output
  pinMode(TriacPin[1], OUTPUT);                        // Set the Triac pin as output
  pinMode(TriacPin[2], OUTPUT);                        // Set the Triac pin as output
  pinMode(TriacPin[3], OUTPUT);                        // Set the Triac pin as output
  measure_half_period();                               // Initially measure the half period
}                                                      // End setup

void measure_half_period() {
  zero_cross = 0;                                      // Clearing this here increases the accuracy of the measurement
  byte F = 0;                                          // Frequency counter counter  ;)
  while ( F < 4 ) {                                    // This loop takes 4 zero cross samples
    if ( zero_cross ) {                                // Only run if a zero cross is detected
      ZeroXTime[F] = micros();                         // Set the new current zero cross time in micros()
      zero_cross = 0;                                  // Reset zero_cross
      F++;                                             // Bump the counter for the next sample
    }
  }                                                    // Now we calc the length of each DimStep
  DimStep = (((ZeroXTime[1]-ZeroXTime[0]) + (ZeroXTime[2]-ZeroXTime[1]) + (ZeroXTime[3]-ZeroXTime[2])) / 3) / DimRes;
  Timer1.attachInterrupt(fire_triacs, DimStep);        // (Re)Associate fire_triacs() with the Timer1 interrupt and the latest DimStep period
  ResetPeriod = ResetPeriod + PeriodResync;            // Set the next time when we'll measure the half period again
}
  
void zero_cross_detect() {                             // function to be fired at the zero crossing
  zero_cross = 1;                                      // set a variable that's picked up later
  DimStepCounter = 0;                                  // Reset the step counter for the next round of triac firings
}

void fire_triacs() {                                   // Called every DimStep (Timer1 interrupt, checks FireTriac[n] and fires if it's time
  if ( FireTriac[0] == DimStepCounter ) {              // Is it time to fire?
    digitalWrite(TriacPin[0], HIGH);                   // Fire the Triac mid-phase
    delayMicroseconds(2);
    digitalWrite(TriacPin[0], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  if ( FireTriac[1] == DimStepCounter ) {              // Is it time to fire?
    digitalWrite(TriacPin[1], HIGH);                   // Fire the Triac mid-phase
    delayMicroseconds(2);
    digitalWrite(TriacPin[1], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  if ( FireTriac[2] == DimStepCounter ) {              // Is it time to fire?
    digitalWrite(TriacPin[2], HIGH);                   // Fire the Triac mid-phase
    delayMicroseconds(2);
    digitalWrite(TriacPin[2], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  if ( FireTriac[3] == DimStepCounter ) {              // Is it time to fire?
    digitalWrite(TriacPin[3], HIGH);                   // Fire the Triac mid-phase
    delayMicroseconds(2);
    digitalWrite(TriacPin[3], LOW);                    // Turn off the Triac gate (Triac will not turn off until next zero cross)
  }
  DimStepCounter++;                                    // This counter increments every time fire_triacs runs
}

void loop() {                                          // Main Loop
  if ( millis() >= ResetPeriod ) {                     // Measure the half period every PeriodResync milliseconds to prevent drift
    measure_half_period();
  }
    FireTriac[0] = (DimRes * analogRead(0)) / 1024;    // Read input and calc the next triac fire time
    FireTriac[1] = (DimRes * analogRead(1)) / 1024;    // Read input and calc the next triac fire time
    FireTriac[2] = (DimRes * analogRead(2)) / 1024;    // Read input and calc the next triac fire time
    FireTriac[3] = (DimRes * analogRead(3)) / 1024;    // Read input and calc the next triac fire time
}
Logged

What about elevensies? Luncheon? Afternoon tea? Dinner? Supper?

Syrascuse, New York
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Could I join in you guys?

I am trying to build the similar circuit for my power control project with the arduino. But  I use high current triac (15A MAC15SD) for my power monster. For safe propose, I use two opto-isolators (M11A1 and MOC3063), which one is for zero crossing detector and the other one is for triac, to separate  AC and DC sides, although AC and DC circuits are on the same small solder less breadboard. But AC circuit is AC, and DC is only DC. My reference circuit comes from here.  (Keyword: fairchild  AN-3006.pdf)(Sorry, I can't post web address when my first post is. I will add it later)
 
I adjusted several pars of this circuit to suit my need. One 555 timer is used in my circuit. I think a outside timer is better than arduino.  According to my previous tests, arduino works at high speed (less 10 microseconds. Min limitation is 3 or 4 usec). I often found a lot noise from circuits. But I am not sure it comes from arduino or not.

Reminder: to use isolator transformer (120v to 120v) before oscilloscope's probes contact your AC circuit, if you are new. Otherwise, the circuit will burn out!!! Due to AC circuit and the oscilloscope don't share the same ground. I burned my circuit three times. :'(

To ryanjmclaughlin: for buzz from the triac, you can probably use a small capacitor to filter it, like the upper reference circuit.  An inductor will let ac phase changed.  Or noise comes from arduino?

To Koyaanisqatsi:  I tried to compile your latest code(Version: April smiley-cool.  I got a error from this line.
"ZeroXTime[F] = micros(); "
Could  you please let me know what value of micros() is?

To  that_chap
Your advice is a good ideal for several applications which don't need phase control. Some projects like mine, I have to get continuous power output, not discrete power output. They are totally different. Fast on and off switch doesn't suit for phase control applications, like lamp dimming. I have done this switch circuit with my arduino. I captured zero crossing signal, synchronized the signal, and use PWM function on the arduino to generate a fast on-off switch. I did it. I can even control output power very accurate.  Unfortunately,  I get a flickering light. We need a phase control , not a high speed switch.
Logged

Syrascuse, New York
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The reference circuit website is:
www.fairchildsemi.com/an/AN/AN-3006.pdf
smiley
Logged

Atascadero, CA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 468
Arduino addict
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi bluefish,

Here's the description of micros().  You may need a minimum version of the IDE for it to work.  I'm running 0013.
http://arduino.cc/en/Reference/Micros

Please let us know if you are able to use the code.  That was my first real project and I'm very curious to know how it works for people.

Cheers!
Logged

What about elevensies? Luncheon? Afternoon tea? Dinner? Supper?

Syrascuse, New York
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

To koyaanisqatsi:
For DelayMicroseconds function
http://arduino.cc/en/Reference/DelayMicroseconds

"This function works very accurately in the range 3 microseconds and up. We cannot assure that delayMicroseconds will perform precisely for smaller delay-times."
 
2usec is too small for arduino.  I will try 2usec first and let you know what I get. But I suggest we use 6 usec or up. (Twice of the mini level of arduino)

Although I used 5usec for my previous tests, the strength of pulses is very difficult to trigger triac. Due to weak pulse signal, a lot of noise is observed in my circuit.
Logged

Atascadero, CA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 468
Arduino addict
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm assuming you're referring to this statement in one of my previous posts:
Quote
1. The triac pulse is 6us in the current code.  Removing the 2us delay reduces it to a 4us pulse.  How long does the pulse need to persist to properly fire the triac?
I actually measured this on my oscilloscope.  With delayMicroseconds(2), I get a 6us pulse and without it I get a 4us pulse.  It's a pretty small difference, but in this application, every spare clock cycle counts.   smiley-wink   I'm not sure what triacs require for a minimum trigger pulse width and I would not be surprised if we actually need a wider pulse to get a reliable trigger.

The minimum delayMicroseconds() is due to clock cycle rounding and processing latency.  So adding a 1us delay may do some good in some cases because it will "slightly slow down" the surrounding code.  You just can't set a value of 1us and observe an exact 1us delay period.  Down in that low range, you'd have to do a lot of testing to see how the code behaves.  The minimum value they describe in the docs is not a minimum resolution, but rather a lowest usable value.  So any value above 3us should be accurate.

I will be interested to know what your results are on that.
Logged

What about elevensies? Luncheon? Afternoon tea? Dinner? Supper?

Syrascuse, New York
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi koyaanisqatsi,

I took some time to update my arduino software from 0012 to 0015 and read codes. These codes have been compiled now. I have learned new functions after 0012. smiley-wink

After read codes, I have two points. (If I misunderstand it, please let me know.)

1. Digital pin 02 is used for interrupt. Therefore,digital pin 02 has to be connect with the zero crossing detector.

2. For this lines "FireTriac[1]=(DimRes*analogRead(1))/1024", the reading value of Analog Pin 01 is used to set when triac is triggered. This is a great ideal. Therefore,we can use 4 potentiometers or 4 different values to get 4 different power outputs at the same time. ;D

Only one small problem is here. DimRes is 256. When the value of analogread is 0, the value of firetriac is 0. When the value of analogread is 512, the value of firetriac is 128. Trigger level is from 0 to 128. Therefore, total trigger level is 129.

For next step, I will try these codes with my circuit and let you know what result I get.

Cheers 8-)
« Last Edit: April 10, 2009, 03:24:19 pm by bluefish » Logged

Syrascuse, New York
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi koyaanisqatsi,

I used one 1 to 1 isolator transformer, one oscilloscope, one P3 kill a wall, one 100w lamp and the adjusted circuit from reference circuit.

After I tested codes, it works very good. The range of output power is between 16w and 93w, compared with input value from 1024 to 125. Yes, it's opposite due to my circuit. The 16w mini output is due to one to one isolator transformer. It is a big and heavy power pig. When input value is 100, triac is off.

I have taken five pictures from the oscilloscope: one is ac to zero crossing(zero crossing signal is over 200usec than ac waveform. But it's not a problem.), and the others are different phase control results. (the value of AnalogRead is: 225, 550, 825, 975). For delay 2usc, you are right. It doesn't bother me. 8-)

When I watched the lamp, the lamp doesn't flick. The bright of the lamp is very stable. Of course, I got different bright of the lamp from different input value. I also measured the output power from 100 to 1024 (input value). I made a curve for input value to output power.

If someone can let me know how to attach these pictures on this forum, I will post them.

Hi ryanjmclaughlin,

I did't find a lot of buzz from AC output. I am interested in your AC shield.
Could you please let me know how it is going?

Happy Holiday smiley
« Last Edit: April 12, 2009, 03:53:57 pm by bluefish » Logged

Pages: 1 2 3 [4] 5 6 ... 8   Go Up
Jump to: