hey, can someone help me with this one.
I have been searching some way to dim ac light, and i have been managing to control, but just one channel.
i found this thread and it was looking nice, but could some one say how to control those channel values through serial?
im not a code wizard. thanks for the trouble
http://forum.arduino.cc/index.php?topic=6970.75
/*
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.
It also tracks the rollover of the internal microseconds counter
to avoid the glitch that would arise about every 70 minutes otherwise.
*/
// General
volatile unsigned long int ZeroXTime1 = 0; // Timestamp in micros() of the latest zero crossing interrupt
volatile unsigned long int ZeroXTime2 = 0; // Timestamp in micros() of the previous zero crossing interrupt
volatile unsigned long int XTimePeriod; // The calculated micros() between the last two zero crossings
byte TriacFireWidth = 2; // How many microseconds to leave the triac trigger high
unsigned int DimChangeDelay = 500; // How many millis() between changes of dimmer level
unsigned long int DimChangeTime = 0; // Timestamp in millis() when the dimmer was changed
// Channel specific
# define Channels 4 // How many dimmer channels (triacs) are there?
unsigned long int DimLevel[Channels]; // Dimming level (high value = more dim, low value = more light)
unsigned long int DimDelay[Channels]; // How many micros() to wait after zero cross to fire the triacs
unsigned long int NextTriacFire[Channels]; // Timestamp in micros() when it's OK to fire the triacs again.
volatile boolean zero_cross[Channels]; // Boolean to store a "switch" to tell us if we have crossed zero
// Associate pins to each channel (triac)
byte TriacPin[Channels] = {4,5,6,7};
void setup() { // Begin setup
for ( byte c=0; c<Channels; c++ ) { // Loop through and set pin modes
pinMode(TriacPin[c], 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
ZeroXTime2 = ZeroXTime1; // shift the current zero cross value to the previous
ZeroXTime1 = micros(); // set the new current zero cross time in micros()
XTimePeriod = ZeroXTime1 - ZeroXTime2; // Calculate the time since the last zero crossing
for ( byte c=0; c<Channels; c++ ) {
DimDelay[c] = XTimePeriod / DimLevel[c]; // Calc how long to wait after zero cross to fire the triacs
NextTriacFire[c] = ZeroXTime1 + DimDelay[c]; // Calc the next triac fire time
zero_cross[c] = 1; // set the boolean to true to tell our dimming function that a zero cross has occured
}
} // End zero_cross_detect
void loop() { // Main Loop
// Set DimLevel in some fashion.
DimLevel[0] = analogRead(0); // For testing, we're just reading an analog input
DimLevel[1] = analogRead(0); // For testing, we're just reading an analog input
DimLevel[2] = analogRead(0); // For testing, we're just reading an analog input
DimLevel[3] = analogRead(0); // For testing, we're just reading an analog input
// DimLevel is used to set NextTriacFire in zero_cross_detect()
for ( byte d=0; d<Channels; d++ ) { // Loop through each channel
if ( zero_cross[d] ) {
if ( micros() >= NextTriacFire[d] ) { // Check to see if it's time to fire the triac
digitalWrite(TriacPin[d], HIGH); // Fire the Triac mid-phase
delayMicroseconds(TriacFireWidth); // Pause briefly to ensure the triac turned on
digitalWrite(TriacPin[d], LOW); // Turn off the Triac gate (Triac will not turn off until next zero cross)
NextTriacFire[d] = NextTriacFire[d] + XTimePeriod;
zero_cross[d] = 0; // Reset the zero cross detection
}
}
}
}