Guest User

Untitled

a guest
Mar 8th, 2012
2,335
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. by Gromain59
  3. Translated By Mike Deuschle
  4. mike.dausch@gmail.com
  5.  
  6. Material part:
  7. - Triac driven by a digital output via an optocoupler
  8. - AC opto-coupler for detecting the zero crossing of phase
  9.  
  10. Software part:
  11. - A hardware interrupt input 2 at the zero crossing of phase
  12. - A software interrupt that occurs between 100us and 1400us.
  13.      => Interrupt interval is variable to obtain a light curve by linear orders, because of the shape of the sinusoidal signal.
  14. we have:
  15. 1. Detection of the transition to zero on input 2
  16. 2. execution of detection_zero (): processing channel with a setpoint of 0% and 100%
  17. 3. deactivating hardware interrupt, enabling the software interrupt on the basis of delay [0]
  18. 4. interrupt after delay [c2] ?s (c2 = 0)
  19. 5. execution of controle_canaux ()
  20.      => Index increment c2
  21.      and if c2 is greater than 49, then this is the last cycle
  22.            => Turn OFF of all channels
  23.            => Activate the hardware interrupt
  24.      otherwise:
  25.            => Activation of output channels with 98% to record (either a 469?s delay) or if
  26.            => Interrupt reconfiguration of time with another delay, delay [c2]
  27.          
  28. To change the setpoint of a channel, you must send via the serial monitor a frame of the form:
  29.            " D/0/45/F"
  30.      => Space
  31.      => "D" to indicate the start of the frame
  32.      => "/" As separator
  33.      => The affected channel (0 to 7 here)
  34.      => "/" As separator
  35.      => The desired level (from 0% to 100%)
  36.      => "/" As separator
  37.      => "F" to indicate the end of the frame
  38.    
  39.      Once the frame received, the function sscanf is responsible for retrieving data.
  40.      It converts the received record levels (0 to 50 levels)
  41.    
  42. Resources:
  43. http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30 for first test
  44. http://www.hoelscher-hi.de/hendrik/english/dimmer.htm for electronics
  45. http://www.abcelectronique.com/bigonoff/domocan.php?par=3efd4 for electronics and soft (PIC)
  46. arduino forum
  47.  
  48. */
  49.  
  50. #include <TimerOne.h>  // for the interruption time http://www.arduino.cc/playground/Code/Timer1
  51. #include <stdio.h>  // for the treatment of the frame containing the change orders
  52.  
  53.                      // timeout value for the reception of the frame
  54. int tps_max_lecture = 200; // reading code, counter max between all the characters of a code
  55. int tps_max_carte = 1000; // max meter between reception of a character
  56.  
  57.  
  58. long curve[] = {
  59. 1469 , // 98 % 1 225,3V retard / zéro = 1469 ms
  60. 287 , // 96 % 2 222,7V retard / zéro = 1867 ms
  61. 234 , // 94 % 3 220,6V retard / zéro = 2154 ms
  62. 201 , // 92 % 4 218,2V retard / zéro = 2388 ms
  63. 180 , // 90 % 5 215,4V retard / zéro = 2589 ms
  64. 164 , // 88 % 6 213,3V retard / zéro = 2769 ms
  65. 152 , // 86 % 7 210,8V retard / zéro = 2933 ms
  66. 143 , // 84 % 8 208V retard / zéro = 3085 ms
  67. 135 , // 82 % 9 205,7V retard / zéro = 3228 ms
  68. 129 , // 80 % 10 202,8V retard / zéro = 3363 ms
  69. 124 , // 78 % 11 200,5V retard / zéro = 3492 ms
  70. 120 , // 76 % 12 197,6V retard / zéro = 3616 ms
  71. 116 , // 74 % 13 195,2V retard / zéro = 3736 ms
  72. 112 , // 72 % 14 192,4V retard / zéro = 3852 ms
  73. 110 , // 70 % 15 189,6V retard / zéro = 3964 ms
  74. 108 , // 68 % 16 186,8V retard / zéro = 4074 ms
  75. 106 , // 66 % 17 184V retard / zéro = 4182 ms
  76. 105 , // 64 % 18 180,9V retard / zéro = 4288 ms
  77. 103 , // 62 % 19 178,1V retard / zéro = 4393 ms
  78. 102 , // 60 % 20 175,1V retard / zéro = 4496 ms
  79. 101 , // 58 % 21 172,1V retard / zéro = 4598 ms
  80. 101 , // 56 % 22 168,9V retard / zéro = 4699 ms
  81. 100 , // 54 % 23 166,2V retard / zéro = 4800 ms
  82. 100 , // 52 % 24 162,6V retard / zéro = 4900 ms
  83. 100 , // 50 % 25 159,3V retard / zéro = 5000 ms
  84. 101 , // 48 % 26 155,8V retard / zéro = 5100 ms
  85. 100 , // 46 % 27 152,6V retard / zéro = 5201 ms
  86. 101 , // 44 % 28 149,1V retard / zéro = 5301 ms
  87. 102 , // 42 % 29 145,3V retard / zéro = 5402 ms
  88. 103 , // 40 % 30 141,8V retard / zéro = 5504 ms
  89. 105 , // 38 % 31 138V retard / zéro = 5607 ms
  90. 106 , // 36 % 32 133,8V retard / zéro = 5712 ms
  91. 108 , // 34 % 33 130V retard / zéro = 5818 ms
  92. 110 , // 32 % 34 126V retard / zéro = 5926 ms
  93. 112 , // 30 % 35 121,7V retard / zéro = 6036 ms
  94. 116 , // 28 % 36 117,1V retard / zéro = 6148 ms
  95. 120 , // 26 % 37 112,6V retard / zéro = 6264 ms
  96. 124 , // 24 % 38 107,7V retard / zéro = 6384 ms
  97. 129 , // 22 % 39 102,4V retard / zéro = 6508 ms
  98. 135 , // 20 % 40 97,2V retard / zéro = 6637 ms
  99. 143 , // 18 % 41 92V retard / zéro = 6772 ms
  100. 152 , // 16 % 42 85,7V retard / zéro = 6915 ms
  101. 164 , // 14 % 43 79,4V retard / zéro = 7067 ms
  102. 180 , // 12 % 44 72,8V retard / zéro = 7231 ms
  103. 201 , // 10 % 45 64,8V retard / zéro = 7411 ms
  104. 234 , // 8 % 46 56,4V retard / zéro = 7612 ms
  105. 286 , // 6 % 47 46V retard / zéro = 7846 ms
  106. 399 , // 4 % 48 32,4V retard / zéro = 8132 ms
  107. 500 , //
  108. 1469  // 2 % 49 0V retard / zéro = 8531 ms
  109. };
  110.  
  111. int set[] = {    // set channel level (0 = 100%, 50 = 0%)
  112. 0, // Output 0
  113. 0, // output 1
  114. 0, // output 2
  115. 0, // output 3
  116. 0, // output 4
  117. 0, // output 5
  118. 0, // output 6
  119. 0, // output 7
  120. };
  121.  
  122. int output [] = { // assign a pin for each channel.
  123. 4, // Output 0
  124. 3, // output 1
  125. 5, // output 2
  126. 0, // output 3
  127. 0, // output 4
  128. 0, // output 5
  129. 0, // output 6
  130. 0, // output 7
  131. };
  132.  
  133. volatile int c1 = 0; // index c1 for reading data from each channel (No pin, luggage)
  134. volatile int c2 = 0; // c2 index number passing through the loop control phase delay (49 passages)
  135.  
  136. // Definition of macros to drive the output
  137. #define lightON(index) (digitalWrite(output[index], HIGH))
  138. #define lightOFF(index) (digitalWrite(output[index], LOW))
  139.  
  140.  
  141. void setup () {// Start of setup
  142.  
  143. // Initialize the serial
  144. Serial.begin (9600);
  145.  
  146. // Initialize the channel outputs (triacs)
  147.      for (c1 = 0; c1 <= 7; c1++) {// we traverse the 8 channels to configure
  148.                  pinMode(output[c1], OUTPUT); // we associate each channel has a pin, which sets the output digital
  149.                  lightOFF(output[c1]); // and we switch off the output
  150.                                  }
  151.  
  152.      Serial.println( "Gromain 8-CHANNEL DIMMER v0.2");
  153.      Serial.println( "FRAME EXPECTED: <space> 'D' / 'Output Port' / 'Value of DIM' / 'F'");
  154.  
  155.  
  156. // Initialize the interruption time Timer1
  157.      Timer1.initialize(); // Initialize TimerOne library for the freq we need
  158.  
  159.  
  160. // Attach the interrupt 0 to pin 2 for the detection of zero crossing (Zero Cross Detection)
  161.      attachInterrupt(0, detection_zero, FALLING); // Attach an Interrupt to Pin 2 (Interrupt 0) for Zero Cross Detection
  162.  
  163. } // End of setup
  164.  
  165. void detection_zero() {// function associated with the interrupt 0
  166.  
  167.      detachInterrupt(0); // disables the interrupt on zero crossing
  168.  
  169.      c2 = 0;
  170.    
  171.      for (c1 = 0; c1 <= 7; c1++) {// we scan the 8 outputs to check their orders
  172.              if (set[c1] >= 49 ) {// if set 0%
  173.                  lightOFF(c1); // then we switch off
  174.              }
  175.          
  176.            if (set[c1]<= 0){// if set 100%
  177.                  lightON(c1); // then we light
  178.            }
  179.          
  180.      }
  181.  
  182.      Timer1.attachInterrupt(controle_canaux, curve[c2]); // we attach the interruption time
  183.    
  184. } // End of detection_zero
  185.  
  186. void controle_canaux() {// here we verified whether the triac must be initiated
  187.  
  188.     c2=c2++;
  189.    
  190.      attachInterrupt(0, detection_zero, FALLING); // we attach an interrupt on pin 2 (interrupt 0)
  191.      Timer1.detachInterrupt(); // we detach the interruption time
  192.  
  193.      if (c2 >= 49) {// If last cycle then (49 for 50hz - 41 for 60Hz)
  194.  
  195.      for (c1 = 0; c1 <= 7; c1++) {// we scan the 8 outputs
  196.            lightOFF(c1);  // and we put out the channel for the next cycle
  197.      }
  198.  
  199.    
  200.      }
  201. else { // else
  202.  
  203.      Timer1.attachInterrupt(controle_canaux, curve[c2]); // we attach a break time
  204.  
  205.      for (c1 = 0; c1 <= 7; c1++) { // we scan the 8 outputs to check their orders
  206.              if (set[c1] == c2) // if is set equal to the processed (no change in the loop)
  207.            {lightON(c1);} // then we light the channel
  208.      }
  209.                
  210. } // End function controle_canaux
  211.  
  212. }
  213. void loop() {// Main Loop
  214.  
  215.      int n = 0;
  216.    
  217.      if (Serial.available ()> 0) {
  218.            n = lecture();
  219.      }
  220.  
  221. }
  222.  
  223. int lecture() {// read a frame type: "D / aaa / bbb / F
  224.                              // Or "D" starting character frame
  225.                              // Or "yyyy" No output which is set to modify
  226.                              // Or "bbbb" new set of output (between 0 and 100%)
  227.  
  228.  
  229.  
  230.      char buf[15] = "              ";
  231.      int timeout = 0;
  232.      int i = 0;
  233.      int n1 = 0;
  234.      int n2 = 0;
  235.      char c1, c2;
  236.    
  237.      while (Serial.available() > 0) {
  238.            if(i!=14){
  239.            buf[i] = Serial.read ();
  240.            i++;
  241.            }
  242.  
  243.      timeout++;
  244.    
  245.      if (timeout>tps_max_lecture)
  246.            {Serial.println("T1");
  247.            return -1;
  248.            }
  249.      if (timeout> tps_max_lecture)
  250.            {Serial.println("T2");
  251.            return -2;
  252.            }
  253.        }
  254.      sscanf(buf, "%c/%d/%d/%c", &c1, &n1, &n2, &c2); // decoding frame
  255.    
  256.      if (c1 == 'D' && c2 == 'F') {// Check if the plot starts out by D and ending in F
  257.          
  258.            int nouv_cons = n2;  // we store the new value for the work then
  259.          
  260.            nouv_cons = constrain(nouv_cons, 0, 100); // on the new terminal value between 0 and 100%
  261.            Serial.print("Output ");
  262.            Serial.print(n1);
  263.            Serial.print(" , new value of: ");
  264.            Serial.print(nouv_cons);
  265.            Serial.print(" % index, delay: ");
  266.                
  267.            set[n1] = (50 - (nouv_cons / 2)); // it converts the value 0-100% in no phase delay
  268.                
  269.            Serial.println (set[n1]);
  270.      }
  271.      else // if character from the beginning or end of frame not recognized
  272.      {Serial.println("Code Unknown");}
  273.    
  274.      return i;
  275.    
  276. }
RAW Paste Data