Advertisement
kartonman

level crossing 3 track annotated in model

May 4th, 2022 (edited)
845
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.53 KB | None | 0 0
  1. /*level crossing 3 track 2may update
  2. This code is an adaptation of the originalcode written by Ruud Boer. The orginal can be obtained by visiting his site
  3. at https://rudysarduinoprojects.wordpress.com/2019/03/10/fun-with-arduino-20-railway-crossing-part-4-putting-it-all-together/
  4. The changes to that code, done by Gary Granai, https://steamtraininfo.com/admin/home/arduino-projects, consist of changing pin
  5. definitions, adding connections for a third track and defining pin numbers to make wiring the circuit board
  6. easier. Explanitory comments have also been added.
  7. This adapted sketch is copywrite Gary Granai and you are free to use it and make changes as long as these credits
  8. remain intact and unchanged.
  9. */
  10. #define GATE_SPEED 30 // [ms] lower number is higher servo speed
  11. #define BLINK_SPEED 400 // [ms] smaller number is faster blinking
  12. #define GATE_DELAY 1500 // [ms] time between start blinking and gate closing
  13. #define END_OF_TRAIN_DELAY 2000 // [ms] time to wait before deciding this was the end of the train
  14. #define GATE_OPEN_ANGLE_1 90 //change as you wish
  15. #define GATE_CLOSED_ANGLE_1 10 //change as you wish
  16. #define GATE_OPEN_ANGLE_2 90 //change as you wish
  17. #define GATE_CLOSED_ANGLE_2 10 //change as you wish
  18. #define SERVO1_PIN 10 /*a pwm pin. Two externally powered servos are controlled by this pin. These servos
  19. are on the road entrance side of the track. They move first when a train enters the protected area and second when
  20. the crossing is clear of trains,*/
  21. #define SERVO2_PIN 11 /*a pwm pin. Two externally powered servos are controlled by this pin. These servos
  22. are on the road exit side of the track. They move second when a train enters the protected area and first when
  23. the crossing is clear of trains,*/
  24. #define LED1_PIN 8 //one of the flashing lights.
  25. #define LED2_PIN 9 //the second flashing light.
  26. #define NUM_SENSORS 6 // two sensors per track, one left and one right of the gate
  27. byte sensor_pin[NUM_SENSORS] = {2, 3, 4, 5, 6, 7}; // sensor "OUT" wires connect to these pins.
  28.  
  29. //leave eerything below as it is.
  30. byte state = 1;
  31. byte train_counter, n;
  32. byte led1, led2, blink_enabled;
  33. byte angle1 = GATE_OPEN_ANGLE_1;
  34. byte setpoint1 = GATE_OPEN_ANGLE_1;
  35. byte angle2 = GATE_OPEN_ANGLE_2;
  36. byte setpoint2 = GATE_OPEN_ANGLE_2;
  37. byte sensor_state[NUM_SENSORS]; // 0 idle, 1 detect arrival, 2 detect departure, 3 detect end of train
  38. byte end_of_train[NUM_SENSORS]; // 0 idle, 1 end of train detected
  39. unsigned long time_to_blink;
  40. unsigned long time_to_close_gate;
  41. unsigned long time_for_servo_step;
  42. unsigned long time_end_of_train[NUM_SENSORS];
  43.  
  44. #include <Servo.h>
  45. Servo gate_servo1;
  46. Servo gate_servo2;
  47.  
  48. void setup() {
  49. pinMode(LED1_PIN, OUTPUT);
  50. pinMode(LED2_PIN, OUTPUT);
  51. for (byte i = 0; i < NUM_SENSORS; i++) pinMode(sensor_pin[i], INPUT_PULLUP);
  52. gate_servo1.attach(SERVO1_PIN);
  53. gate_servo1.write(angle1);
  54. gate_servo2.attach(SERVO2_PIN);
  55. gate_servo2.write(angle2);
  56. delay(1000);
  57. gate_servo1.detach();
  58. gate_servo2.detach();
  59. Serial.begin(9600);
  60. Serial.println("Railway Crossing Control Ready");
  61. Serial.println();
  62. Serial.println("Waiting for train");
  63. for (byte i = 0; i < NUM_SENSORS; i++) sensor_state[i] = 1; // enable sensors for train detection
  64. }
  65.  
  66. void loop() {
  67.  
  68. for (byte i = 0; i < NUM_SENSORS; i++) {
  69. if (sensor_state[i] == 1) { // detect arrival of new train
  70. if (!digitalRead(sensor_pin[i])) { // train detected
  71. train_counter++;
  72. sensor_state[i] = 0;
  73. if (i % 2) n = i - 1; else n = i + 1;
  74. sensor_state[n] = 2; // buddy sensor departure detection enabled
  75. Serial.print("Arrival: ");
  76. Serial.println(i);
  77. Serial.print("Trains: ");
  78. Serial.println(train_counter);
  79. }
  80. }
  81. else if (sensor_state[i] > 1) {
  82. if (!digitalRead(sensor_pin[i])) { // departure detected
  83. time_end_of_train[i] = millis() + (unsigned long)END_OF_TRAIN_DELAY;
  84. if (i % 2) n = i - 1; else n = i + 1;
  85. sensor_state[n] = 1; // buddy sensor enabled again
  86. if (sensor_state[i] == 2) {
  87. Serial.print("Departure: ");
  88. Serial.println(i);
  89. }
  90. sensor_state[i] = 3;
  91. }
  92. if (sensor_state[i] == 3) // decide if end of train has passed based on a timer
  93. if (millis() > time_end_of_train[i]) end_of_train[i] = 1;
  94. if (end_of_train[i]) { // this takes care train_counter-- is executed only once
  95. train_counter--;
  96. end_of_train[i] = 0;
  97. sensor_state[i] = 1;
  98. Serial.print("Trains: ");
  99. Serial.println(train_counter);
  100. }
  101. }
  102. }
  103.  
  104. switch (state) {
  105. case 1: // Gates open. Not blinking. Waiting for train.
  106. if (train_counter) { // A train is detected.
  107. Serial.println("Binking started");
  108. blink_enabled = 1;
  109. time_to_close_gate = millis() + (unsigned long)GATE_DELAY;
  110. state = 2;
  111. }
  112. break;
  113.  
  114. case 2: // Blinking. Wait until it's time to close the gates
  115. if (millis() > time_to_close_gate) { // Gate delay time has passed
  116. Serial.println("Gate1 closing");
  117. gate_servo1.attach(SERVO1_PIN);
  118. setpoint1 = GATE_CLOSED_ANGLE_1;
  119. state = 3;
  120. }
  121. break;
  122.  
  123. case 3: // Gate1 closing. Blinking.
  124. if (angle1 == setpoint1) { // Gate1 closed
  125. gate_servo1.detach();
  126. Serial.println("Gate1 closed");
  127. Serial.println("Gate2 closing");
  128. gate_servo2.attach(SERVO2_PIN);
  129. setpoint2 = GATE_CLOSED_ANGLE_2;
  130. state = 4;
  131. }
  132. break;
  133.  
  134. case 4: // Gate2 closing. Blinking.
  135. if (angle2 == setpoint2) { // Gate2 is fully closed
  136. gate_servo2.detach();
  137. Serial.println("Gate2 closed");
  138. state = 5;
  139. }
  140. break;
  141.  
  142. case 5: // Gate2 closed. Blinking. Wait until all trains are gone.
  143. if (!train_counter) { // End of last train detected
  144. Serial.println("Gate2 opening");
  145. gate_servo2.attach(SERVO2_PIN);
  146. setpoint2 = GATE_OPEN_ANGLE_2;
  147. state = 6;
  148. }
  149. break;
  150.  
  151. case 6: // Gate2 opening. Blinking.
  152. if (train_counter) state = 3; // Another train is coming
  153. else if (angle2 == setpoint2) { // Gate2 open
  154. gate_servo2.detach();
  155. Serial.println("Gate2 open");
  156. Serial.println("Gate1 opening");
  157. gate_servo1.attach(SERVO1_PIN);
  158. setpoint1 = GATE_OPEN_ANGLE_1;
  159. state = 7;
  160. }
  161. break;
  162.  
  163. case 7: // Gate1 opening. Blinking.
  164. if (train_counter) state = 2; // Another train is coming
  165. else if (angle1 == setpoint1) { // Gate1 open
  166. gate_servo1.detach();
  167. Serial.println("Gate1 open");
  168. Serial.println("Stop blinking");
  169. blink_enabled = 0; // Stop blinking
  170. led1 = 0;
  171. led2 = 0;
  172. Serial.println();
  173. Serial.println("Waiting for train");
  174. state = 1;
  175. }
  176. break;
  177. }
  178.  
  179. if (millis() > time_for_servo_step) {
  180. time_for_servo_step = millis() + (unsigned long)GATE_SPEED;
  181. if (angle1 < setpoint1) angle1++;
  182. if (angle1 > setpoint1) angle1--;
  183. if (angle2 < setpoint2) angle2++;
  184. if (angle2 > setpoint2) angle2--;
  185. gate_servo1.write(angle1);
  186. gate_servo2.write(angle2);
  187. }
  188.  
  189. if (blink_enabled == 1) {
  190. if (millis() > time_to_blink) {
  191. time_to_blink = millis() + (unsigned long)BLINK_SPEED;
  192. led1 = !led1;
  193. led2 = !led1;
  194. }
  195. }
  196.  
  197. digitalWrite(LED1_PIN, led1);
  198. digitalWrite(LED2_PIN, led2);
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement