Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- 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 >= 49) {// If last cycle then (49 for 50hz - 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%
- Serial.print("Output ");
- Serial.print(n1);
- Serial.print(" , new value of: ");
- Serial.print(nouv_cons);
- Serial.print(" % index, delay: ");
- set[n1] = (50 - (nouv_cons / 2)); // it converts the value 0-100% in no phase delay
- Serial.println (set[n1]);
- }
- else // if character from the beginning or end of frame not recognized
- {Serial.println("Code Unknown");}
- return i;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement