Guest User

Untitled

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