Thanks big time.
I changed the value to 41 and the flicker is nearly gone.
Here is the code I translated:
/*
DIMMERS 120V 60Hz (8-channel Possibly more)
by Gromain59
Translated By Mike Deuschle
mike.dausch@gmail.com
Material part:
- Triac driven by a digital output via an optocoupler
- AC opto-coupler for detecting the zero crossing of phase
Software part:
- A hardware interrupt input 2 at the zero crossing of phase
- A software interrupt that occurs between 100us and 1400us.
=> Interrupt interval is variable to obtain a light curve by linear orders, because of the shape of the sinusoidal signal.
we have:
1. Detection of the transition to zero on input 2
2. execution of detection_zero (): processing channel with a setpoint of 0% and 100%
3. deactivating hardware interrupt, enabling the software interrupt on the basis of delay [0]
4. interrupt after delay [c2] ?s (c2 = 0)
5. execution of controle_canaux ()
=> Index increment c2
and if c2 is greater than 49, then this is the last cycle
=> Turn OFF of all channels
=> Activate the hardware interrupt
otherwise:
=> Activation of output channels with 98% to record (either a 469?s delay) or if
=> Interrupt reconfiguration of time with another delay, delay [c2]
To change the setpoint of a channel, you must send via the serial monitor a frame of the form:
" D/0/45/F"
=> Space
=> "D" to indicate the start of the frame
=> "/" As separator
=> The affected channel (0 to 7 here)
=> "/" As separator
=> The desired level (from 0% to 100%)
=> "/" As separator
=> "F" to indicate the end of the frame
Once the frame received, the function sscanf is responsible for retrieving data.
It converts the received record levels (0 to 50 levels)
Resources:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30 for first test
http://www.hoelscher-hi.de/hendrik/english/dimmer.htm for electronics
http://www.abcelectronique.com/bigonoff/domocan.php?par=3efd4 for electronics and soft (PIC)
arduino forum
*/
#include <TimerOne.h> // for the interruption time http://www.arduino.cc/playground/Code/Timer1
#include <stdio.h> // for the treatment of the frame containing the change orders
// timeout value for the reception of the frame
int tps_max_lecture = 200; // reading code, counter max between all the characters of a code
int tps_max_carte = 1000; // max meter between reception of a character
long curve[] = {
1469 , // 98 % 1 225,3V retard / zéro = 1469 ms
287 , // 96 % 2 222,7V retard / zéro = 1867 ms
234 , // 94 % 3 220,6V retard / zéro = 2154 ms
201 , // 92 % 4 218,2V retard / zéro = 2388 ms
180 , // 90 % 5 215,4V retard / zéro = 2589 ms
164 , // 88 % 6 213,3V retard / zéro = 2769 ms
152 , // 86 % 7 210,8V retard / zéro = 2933 ms
143 , // 84 % 8 208V retard / zéro = 3085 ms
135 , // 82 % 9 205,7V retard / zéro = 3228 ms
129 , // 80 % 10 202,8V retard / zéro = 3363 ms
124 , // 78 % 11 200,5V retard / zéro = 3492 ms
120 , // 76 % 12 197,6V retard / zéro = 3616 ms
116 , // 74 % 13 195,2V retard / zéro = 3736 ms
112 , // 72 % 14 192,4V retard / zéro = 3852 ms
110 , // 70 % 15 189,6V retard / zéro = 3964 ms
108 , // 68 % 16 186,8V retard / zéro = 4074 ms
106 , // 66 % 17 184V retard / zéro = 4182 ms
105 , // 64 % 18 180,9V retard / zéro = 4288 ms
103 , // 62 % 19 178,1V retard / zéro = 4393 ms
102 , // 60 % 20 175,1V retard / zéro = 4496 ms
101 , // 58 % 21 172,1V retard / zéro = 4598 ms
101 , // 56 % 22 168,9V retard / zéro = 4699 ms
100 , // 54 % 23 166,2V retard / zéro = 4800 ms
100 , // 52 % 24 162,6V retard / zéro = 4900 ms
100 , // 50 % 25 159,3V retard / zéro = 5000 ms
101 , // 48 % 26 155,8V retard / zéro = 5100 ms
100 , // 46 % 27 152,6V retard / zéro = 5201 ms
101 , // 44 % 28 149,1V retard / zéro = 5301 ms
102 , // 42 % 29 145,3V retard / zéro = 5402 ms
103 , // 40 % 30 141,8V retard / zéro = 5504 ms
105 , // 38 % 31 138V retard / zéro = 5607 ms
106 , // 36 % 32 133,8V retard / zéro = 5712 ms
108 , // 34 % 33 130V retard / zéro = 5818 ms
110 , // 32 % 34 126V retard / zéro = 5926 ms
112 , // 30 % 35 121,7V retard / zéro = 6036 ms
116 , // 28 % 36 117,1V retard / zéro = 6148 ms
120 , // 26 % 37 112,6V retard / zéro = 6264 ms
124 , // 24 % 38 107,7V retard / zéro = 6384 ms
129 , // 22 % 39 102,4V retard / zéro = 6508 ms
135 , // 20 % 40 97,2V retard / zéro = 6637 ms
143 , // 18 % 41 92V retard / zéro = 6772 ms
152 , // 16 % 42 85,7V retard / zéro = 6915 ms
164 , // 14 % 43 79,4V retard / zéro = 7067 ms
180 , // 12 % 44 72,8V retard / zéro = 7231 ms
201 , // 10 % 45 64,8V retard / zéro = 7411 ms
234 , // 8 % 46 56,4V retard / zéro = 7612 ms
286 , // 6 % 47 46V retard / zéro = 7846 ms
399 , // 4 % 48 32,4V retard / zéro = 8132 ms
500 , //
1469 // 2 % 49 0V retard / zéro = 8531 ms
};
int set[] = { // set channel level (0 = 100%, 50 = 0%)
0, // Output 0
0, // output 1
0, // output 2
0, // output 3
0, // output 4
0, // output 5
0, // output 6
0, // output 7
};
int output [] = { // assign a pin for each channel.
4, // Output 0
3, // output 1
5, // output 2
0, // output 3
0, // output 4
0, // output 5
0, // output 6
0, // output 7
};
volatile int c1 = 0; // index c1 for reading data from each channel (No pin, luggage)
volatile int c2 = 0; // c2 index number passing through the loop control phase delay (49 passages)
// Definition of macros to drive the output
#define lightON(index) (digitalWrite(output[index], HIGH))
#define lightOFF(index) (digitalWrite(output[index], LOW))
void setup () {// Start of setup
// Initialize the serial
Serial.begin (9600);
// Initialize the channel outputs (triacs)
for (c1 = 0; c1 <= 7; c1++) {// we traverse the 8 channels to configure
pinMode(output[c1], OUTPUT); // we associate each channel has a pin, which sets the output digital
lightOFF(output[c1]); // and we switch off the output
}
Serial.println( "Gromain 8-CHANNEL DIMMER v0.2");
Serial.println( "FRAME EXPECTED: <space> 'D' / 'Output Port' / 'Value of DIM' / 'F'");
// Initialize the interruption time Timer1
Timer1.initialize(); // Initialize TimerOne library for the freq we need
// Attach the interrupt 0 to pin 2 for the detection of zero crossing (Zero Cross Detection)
attachInterrupt(0, detection_zero, FALLING); // Attach an Interrupt to Pin 2 (Interrupt 0) for Zero Cross Detection
} // End of setup
void detection_zero() {// function associated with the interrupt 0
detachInterrupt(0); // disables the interrupt on zero crossing
c2 = 0;
for (c1 = 0; c1 <= 7; c1++) {// we scan the 8 outputs to check their orders
if (set[c1] >= 49 ) {// if set 0%
lightOFF(c1); // then we switch off
}
if (set[c1]<= 0){// if set 100%
lightON(c1); // then we light
}
}
Timer1.attachInterrupt(controle_canaux, curve[c2]); // we attach the interruption time
} // End of detection_zero
void controle_canaux() {// here we verified whether the triac must be initiated
c2=c2++;
attachInterrupt(0, detection_zero, FALLING); // we attach an interrupt on pin 2 (interrupt 0)
Timer1.detachInterrupt(); // we detach the interruption time
if (c2 >= 41) {// If last cycle then (best at 41 for 60Hz)
for (c1 = 0; c1 <= 7; c1++) {// we scan the 8 outputs
lightOFF(c1); // and we put out the channel for the next cycle
}
}
else { // else
Timer1.attachInterrupt(controle_canaux, curve[c2]); // we attach a break time
for (c1 = 0; c1 <= 7; c1++) { // we scan the 8 outputs to check their orders
if (set[c1] == c2) // if is set equal to the processed (no change in the loop)
{lightON(c1);} // then we light the channel
}
} // End function controle_canaux
}
void loop() {// Main Loop
int n = 0;
if (Serial.available ()> 0) {
n = lecture();
}
}
int lecture() {// read a frame type: "D / aaa / bbb / F
// Or "D" starting character frame
// Or "yyyy" No output which is set to modify
// Or "bbbb" new set of output (between 0 and 100%)
char buf[15] = " ";
int timeout = 0;
int i = 0;
int n1 = 0;
int n2 = 0;
char c1, c2;
while (Serial.available() > 0) {
if(i!=14){
buf[i] = Serial.read ();
i++;
}
timeout++;
if (timeout>tps_max_lecture)
{Serial.println("T1");
return -1;
}
if (timeout> tps_max_lecture)
{Serial.println("T2");
return -2;
}
}
sscanf(buf, "%c/%d/%d/%c", &c1, &n1, &n2, &c2); // decoding frame
if (c1 == 'D' && c2 == 'F') {// Check if the plot starts out by D and ending in F
int nouv_cons = n2; // we store the new value for the work then
nouv_cons = constrain(nouv_cons, 0, 100); // on the new terminal value between 0 and 100%