Components and supplies
Arduino Nano R3
Pushbutton switch 12mm
Breadboard (generic)
SparkFun Breadboard Power Supply 5V/3.3V
Relay Module (Generic)
Oled display
Project description
Code
Code
c_cpp
This is the C++ code to compile and upload to the Arduino Nano
1/********************************************************************* 2 Automatisme per porta corredera motoritzada 3*********************************************************************/ 4 5// Llibreries per fer servir el display 6#include <SPI.h> 7#include <Wire.h> 8#include <Adafruit_GFX.h> 9#include <Adafruit_SSD1306.h> 10 11// Definim pins per automatisme porta 12int FOTOCELULA = 2; 13int BOMBETA = 5; //Relay 1 14int TANCAT = 7; 15int OBERT = 3; 16int MOTOR_OBRIR = 6; //Relay 2 17int MOTOR_TANCAR = 12; //Relay 3 18int OBRIR = 4; 19 20// Definim pins per display 21#define OLED_MOSI 11 22#define OLED_CLK 13 23#define OLED_DC 9 24#define OLED_CS 10 25#define OLED_RESET 8 26Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 27 28// Definim variables globals 29unsigned long TEMPS_PORTA_OBERTA = 20000; 30unsigned long TEMPS_MAXIM_RECORREGUT = 15000; //Despres ho redefinim 31int interval = 1000; // Interval is how long we wait 32int TEMPS_DISPLAY = 1; // temps en segons per imprimir en pantalla 33int DURADA = 300; // Cicle bombeta senyalitzacio 34unsigned long previousMillis = 0; // Tracks the time since last event fired 35unsigned long currentMillis = millis(); 36unsigned long TEMPS_LLUM = 1000; // temps en milisegons de estat llum senyalitzacio 37boolean LLUM = false; // Llum encessa si ON i apagada si OFF 38boolean AVARIA = false; //Excedit el temps de recorregut sense detectar finals de carrera 39 40void setup() { 41 // Inicialitzem els pins per automatisme porta 42 pinMode(FOTOCELULA, INPUT_PULLUP); 43 pinMode(TANCAT, INPUT_PULLUP); 44 pinMode(OBERT, INPUT_PULLUP); 45 pinMode(OBRIR, INPUT_PULLUP); 46 pinMode(BOMBETA, OUTPUT); 47 pinMode(MOTOR_OBRIR, OUTPUT); 48 pinMode(MOTOR_TANCAR, OUTPUT); 49 50 // Apaguem motors i llum 51 digitalWrite(MOTOR_OBRIR, HIGH); 52 digitalWrite(MOTOR_TANCAR, HIGH); 53 digitalWrite(BOMBETA, HIGH); 54 55 // Inicialitzem el display 56 Serial.begin(9600); 57 display.begin(SSD1306_SWITCHCAPVCC); 58 display.display(); // Mostra pantalla inicial de Adafruit 59 delay(1000); 60 display.clearDisplay(); 61 display.display(); 62 63 // preparem el display per texte 64 display.setTextSize(1); 65 display.setTextColor(WHITE); 66} 67 68 69 70void loop() { 71 72BUCLE_PRINCIPAL: 73 delay(2000); 74 previousMillis = millis(); 75 while (digitalRead(OBRIR) == HIGH) 76 { 77 display.clearDisplay(); 78 display.setTextSize(1); 79 display.setCursor(0, 0); 80 display.println("BUCLE PRINCIPAL ..."); 81 display.setTextSize(1); 82 display.setCursor(0, 20); 83 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 84 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 85 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 86 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 87 display.display(); 88 if (AVARIA and (millis() - previousMillis < 60000)) { 89 digitalWrite(BOMBETA, LOW); 90 } else (digitalWrite(BOMBETA, HIGH)); 91 }; //Esperem fins que premem OBRIR i anem refrescant pantalla per mostrar estat sensors 92 goto SEQUENCIA_OBERTURA; 93 94SEQUENCIA_OBERTURA: 95 interval = 28000; // TEMPS MAXIM DE RECORREGUT PORTA OBRINT !!!!!!!!! 96 previousMillis = millis(); 97 98 digitalWrite(MOTOR_OBRIR, LOW); 99 digitalWrite(BOMBETA, LOW); 100 delay(1000); 101A: 102 if (digitalRead(OBERT) == HIGH) { 103 goto PORTA_OBERTA; 104 }; 105 if (digitalRead(OBRIR) == LOW) 106 { 107 display.clearDisplay(); 108 display.setTextSize(1); 109 display.setCursor(0, 0); 110 display.println("Esperant ordre per tancar"); 111 display.setTextSize(1); 112 display.setCursor(0, 20); 113 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 114 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 115 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 116 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 117 display.display(); 118 119 digitalWrite(MOTOR_OBRIR, HIGH); 120 digitalWrite(BOMBETA, HIGH); 121 delay(1000); 122 while (digitalRead(OBRIR) == HIGH) {}; //No fem res fins que premem OBRIR 123 goto SEQUENCIA_TANCAMENT; 124 }; 125 126 //--Control-de-temps-i-impressió-en-pantalla--------------------- 127 currentMillis = millis(); 128 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 129 display.clearDisplay(); 130 display.setTextSize(1); 131 display.setCursor(0, 0); 132 display.println("Obrint porta"); 133 display.setTextSize(2); 134 display.setCursor(90, 0); 135 display.println(TEMPS_DISPLAY); 136 137 display.setTextSize(1); 138 display.setCursor(0, 20); 139 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 140 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 141 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 142 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 143 144 display.display(); 145 if ((currentMillis - previousMillis) >= interval) 146 { 147 digitalWrite(MOTOR_OBRIR, HIGH); 148 AVARIA = true; // 149 goto PORTA_OBERTA; 150 }; 151 152 //--Control-de-cadencia-de-la-llum-intermitent------------------ 153 if ((currentMillis - TEMPS_LLUM) >= 1000) // Cadencia de la llum intermitent de senyalitzacio 154 { 155 LLUM = !LLUM; 156 digitalWrite(BOMBETA, LLUM); 157 TEMPS_LLUM = currentMillis; 158 }; 159 160 goto A; 161 162 163SEQUENCIA_TANCAMENT: 164 interval = 28000; // TEMPS MAXIM DE RECORREGUT PORTA TANCANT !!!!!!!!! 165 previousMillis = millis(); 166 167 digitalWrite(MOTOR_TANCAR, LOW); 168 digitalWrite(BOMBETA, LOW); 169 if (digitalRead(TANCAT) == LOW) {delay(1000);}; 170B: 171 if (digitalRead(TANCAT) == HIGH) 172 { 173 digitalWrite(MOTOR_TANCAR, HIGH); 174 digitalWrite(BOMBETA, HIGH); 175 goto BUCLE_PRINCIPAL; 176 }; 177 if (digitalRead(OBRIR) == LOW) 178 { 179 display.clearDisplay(); 180 display.setTextSize(1); 181 display.setCursor(0, 0); 182 display.println("Esperant ordre per obrir"); 183 display.setTextSize(1); 184 display.setCursor(0, 20); 185 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 186 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 187 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 188 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 189 display.display(); 190 191 digitalWrite(MOTOR_TANCAR, HIGH); 192 digitalWrite(BOMBETA, HIGH); 193 delay(1000); 194 while (digitalRead(OBRIR) == HIGH) {}; //No fem res fins que premem OBRIR 195 goto SEQUENCIA_OBERTURA; 196 }; 197 if (digitalRead(FOTOCELULA) == HIGH) 198 { 199 digitalWrite(MOTOR_TANCAR, HIGH); 200 delay(1000); 201 202 goto SEQUENCIA_OBERTURA; 203 }; 204 205 //--Control-de-temps-i-impressió-en-pantalla--------------------- 206 currentMillis = millis(); 207 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 208 display.clearDisplay(); 209 display.setTextSize(1); 210 display.setCursor(0, 0); 211 display.println("Tancant porta"); 212 display.setTextSize(2); 213 display.setCursor(90, 0); 214 display.println(TEMPS_DISPLAY); 215 display.setTextSize(1); 216 display.setCursor(0, 20); 217 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 218 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 219 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 220 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 221 display.display(); 222 if ((currentMillis - previousMillis) >= interval) { 223 digitalWrite(MOTOR_TANCAR, HIGH); 224 AVARIA = true; 225 goto BUCLE_PRINCIPAL; 226 }; 227 228 //--Control-de-cadencia-de-la-llum-intermitent------------------ 229 if ((currentMillis - TEMPS_LLUM) >= 300) // Cadencia de la llum intermitent de senyalitzacio 230 { 231 LLUM = !LLUM; 232 digitalWrite(BOMBETA, LLUM); 233 TEMPS_LLUM = currentMillis; 234 }; 235 236 goto B; 237 238PORTA_OBERTA: 239 interval = 30000; // TEMPS MAXIM ESPERANT AMB PORTA OBERTA !!!!!!!!! 240 previousMillis = millis(); 241 digitalWrite(MOTOR_OBRIR, HIGH); 242 delay(500); 243C: 244 if (digitalRead(OBRIR) == LOW) { 245 goto SEQUENCIA_TANCAMENT; 246 }; 247 248 //--Control-de-temps-i-impressió-en-pantalla--------------------- 249 currentMillis = millis(); 250 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 251 display.clearDisplay(); 252 display.setTextSize(1); 253 display.setCursor(0, 0); 254 display.println("Porta Oberta completament"); 255 display.setTextSize(2); 256 display.setCursor(90, 0); 257 display.println(TEMPS_DISPLAY); 258 display.setTextSize(1); 259 display.setCursor(0, 20); 260 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 261 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 262 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 263 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 264 display.display(); 265 if ((currentMillis - previousMillis) >= interval) { 266 goto SEQUENCIA_TANCAMENT; 267 }; 268 269 270 //--Control-de-cadencia-de-la-llum-intermitent------------------ 271 if (LLUM == false) { 272 DURADA = 100; 273 } else DURADA = 2000; 274 if ((currentMillis - TEMPS_LLUM) >= DURADA) // Cadencia de la llum intermitent de senyalitzacio 275 { 276 LLUM = !LLUM; 277 digitalWrite(BOMBETA, LLUM); 278 TEMPS_LLUM = currentMillis; 279 }; 280 281 goto C; 282 283} 284
English Software code version
c_cpp
Here you have the code with all the comments translated to english. It includes a short list of vocabulary in order to understand the meaning of variables and labels.
1/********************************************************************* 2 Automatism for sliding motorized door 3*********************************************************************/ 4 5/* Comments are translated to english, but in order to help 6 you understand the name of the variables and labels, here 7 you have a quick vocabulary "Catalan-English": 8 9 Bucle principal = Main loop 10 Sequencia Obertura = Opening sequence 11 Sequencia Tancament = Closing sequence 12 Obrir = Open ; Obert = Opened 13 Tancar = Close ; Tancat = Closed 14 Bombeta = Light bulb 15 Llum = light 16 Porta = Gate / door 17 Avaria = Failure 18 Temps = Time 19 Recorregut = door travel 20*/ 21 22 23// Libraries for Oled Display 24#include <SPI.h> 25#include <Wire.h> 26#include <Adafruit_GFX.h> 27#include <Adafruit_SSD1306.h> 28 29// We define the pins to be used by the control circuitry 30int FOTOCELULA = 2; 31int BOMBETA = 5; //Relay 1 32int TANCAT = 7; 33int OBERT = 3; 34int MOTOR_OBRIR = 6; //Relay 2 35int MOTOR_TANCAR = 12; //Relay 3 36int OBRIR = 4; 37 38// We define the pins to be used by the Oled display 39#define OLED_MOSI 11 40#define OLED_CLK 13 41#define OLED_DC 9 42#define OLED_CS 10 43#define OLED_RESET 8 44Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 45 46// We define global variables 47unsigned long TEMPS_PORTA_OBERTA = 20000; 48unsigned long TEMPS_MAXIM_RECORREGUT = 15000; //Later we'll redefine this value 49int interval = 1000; // Interval is how long we wait 50int TEMPS_DISPLAY = 1; // Time in seconds to display 51int DURADA = 300; // Cicle for light bulb 52unsigned long previousMillis = 0; // Tracks the time since last event fired 53unsigned long currentMillis = millis(); 54unsigned long TEMPS_LLUM = 1000; // time in milliseconds for light bulb status 55boolean LLUM = false; // light ON or OFF 56boolean AVARIA = false; //door travel time exceeded without detecting limiting switch 57 58void setup() { 59 // Turn off motor and light 60 digitalWrite(MOTOR_OBRIR, HIGH); 61 digitalWrite(MOTOR_TANCAR, HIGH); 62 digitalWrite(BOMBETA, HIGH); 63 64 // We initialize the pins for the automatism 65 pinMode(FOTOCELULA, INPUT_PULLUP); 66 pinMode(TANCAT, INPUT_PULLUP); 67 pinMode(OBERT, INPUT_PULLUP); 68 pinMode(OBRIR, INPUT_PULLUP); 69 pinMode(BOMBETA, OUTPUT); 70 pinMode(MOTOR_OBRIR, OUTPUT); 71 pinMode(MOTOR_TANCAR, OUTPUT); 72 73 // Display initialization 74 Serial.begin(9600); 75 display.begin(SSD1306_SWITCHCAPVCC); 76 display.display(); // Show Adafruit initial logo 77 delay(1000); 78 display.clearDisplay(); 79 display.display(); 80 81 // We prepare the text size for the display (not important because later it is dinamically redefined) 82 display.setTextSize(1); 83 display.setTextColor(WHITE); 84} 85 86 87 88void loop() { 89 90BUCLE_PRINCIPAL: 91 delay(2000); 92 previousMillis = millis(); 93 while (digitalRead(OBRIR) == HIGH) 94 { 95 display.clearDisplay(); 96 display.setTextSize(1); 97 display.setCursor(0, 0); 98 display.println("BUCLE PRINCIPAL ..."); 99 display.setTextSize(1); 100 display.setCursor(0, 20); 101 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 102 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 103 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 104 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 105 display.display(); 106 if (AVARIA and (millis() - previousMillis < 60000)) { 107 digitalWrite(BOMBETA, LOW); 108 } else (digitalWrite(BOMBETA, HIGH)); 109 }; // We wait until Open command is issued and meanwhile the display is being refreshed showing the status of the sensors 110 goto SEQUENCIA_OBERTURA; 111 112SEQUENCIA_OBERTURA: 113 interval = 28000; // Maximum time opening the door (if exceeded it will denote some failure) 114 previousMillis = millis(); 115 116 digitalWrite(MOTOR_OBRIR, LOW); 117 digitalWrite(BOMBETA, LOW); 118 delay(1000); 119A: 120 if (digitalRead(OBERT) == HIGH) { 121 goto PORTA_OBERTA; 122 }; 123 if (digitalRead(OBRIR) == LOW) 124 { 125 display.clearDisplay(); 126 display.setTextSize(1); 127 display.setCursor(0, 0); 128 display.println("Esperant ordre per tancar"); // "Waiting order to close" 129 display.setTextSize(1); 130 display.setCursor(0, 20); 131 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 132 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 133 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 134 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 135 display.display(); 136 137 digitalWrite(MOTOR_OBRIR, HIGH); 138 digitalWrite(BOMBETA, HIGH); 139 delay(1000); 140 while (digitalRead(OBRIR) == HIGH) {}; //Do nothing until OPEN command is issued 141 goto SEQUENCIA_TANCAMENT; 142 }; 143 144 //--Time control and display refreshing--------------- 145 currentMillis = millis(); 146 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 147 display.clearDisplay(); 148 display.setTextSize(1); 149 display.setCursor(0, 0); 150 display.println("Obrint porta"); 151 display.setTextSize(2); 152 display.setCursor(90, 0); 153 display.println(TEMPS_DISPLAY); 154 155 display.setTextSize(1); 156 display.setCursor(0, 20); 157 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 158 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 159 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 160 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 161 162 display.display(); 163 if ((currentMillis - previousMillis) >= interval) 164 { 165 digitalWrite(MOTOR_OBRIR, HIGH); 166 AVARIA = true; // 167 goto PORTA_OBERTA; 168 }; 169 170 //--light Flashing frequence control------------------ 171 if ((currentMillis - TEMPS_LLUM) >= 1000) //Flashing at low speed 172 { 173 LLUM = !LLUM; 174 digitalWrite(BOMBETA, LLUM); 175 TEMPS_LLUM = currentMillis; 176 }; 177 178 goto A; 179 180 181SEQUENCIA_TANCAMENT: 182 interval = 28000; // Maximum time closing the door (if exceeded it will denote some failure)! 183 previousMillis = millis(); 184 185 digitalWrite(MOTOR_TANCAR, LOW); 186 digitalWrite(BOMBETA, LOW); 187 if (digitalRead(TANCAT) == LOW) {delay(1000);}; 188B: 189 if (digitalRead(TANCAT) == HIGH) 190 { 191 digitalWrite(MOTOR_TANCAR, HIGH); 192 digitalWrite(BOMBETA, HIGH); 193 goto BUCLE_PRINCIPAL; 194 }; 195 if (digitalRead(OBRIR) == LOW) 196 { 197 display.clearDisplay(); 198 display.setTextSize(1); 199 display.setCursor(0, 0); 200 display.println("Esperant ordre per obrir"); 201 display.setTextSize(1); 202 display.setCursor(0, 20); 203 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 204 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 205 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 206 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 207 display.display(); 208 209 digitalWrite(MOTOR_TANCAR, HIGH); 210 digitalWrite(BOMBETA, HIGH); 211 delay(1000); 212 while (digitalRead(OBRIR) == HIGH) {}; //Do nothing until OPEN command is issued 213 goto SEQUENCIA_OBERTURA; 214 }; 215 if (digitalRead(FOTOCELULA) == HIGH) 216 { 217 digitalWrite(MOTOR_TANCAR, HIGH); 218 delay(1000); 219 220 goto SEQUENCIA_OBERTURA; 221 }; 222 223 //--Time control and display refreshing--------------------- 224 currentMillis = millis(); 225 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 226 display.clearDisplay(); 227 display.setTextSize(1); 228 display.setCursor(0, 0); 229 display.println("Tancant porta"); 230 display.setTextSize(2); 231 display.setCursor(90, 0); 232 display.println(TEMPS_DISPLAY); 233 display.setTextSize(1); 234 display.setCursor(0, 20); 235 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 236 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 237 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 238 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 239 display.display(); 240 if ((currentMillis - previousMillis) >= interval) { 241 digitalWrite(MOTOR_TANCAR, HIGH); 242 AVARIA = true; 243 goto BUCLE_PRINCIPAL; 244 }; 245 246 //--light Flashing frequence control------------------ 247 if ((currentMillis - TEMPS_LLUM) >= 300) // Flashing at fast speed 248 { 249 LLUM = !LLUM; 250 digitalWrite(BOMBETA, LLUM); 251 TEMPS_LLUM = currentMillis; 252 }; 253 254 goto B; 255 256PORTA_OBERTA: 257 interval = 30000; // Time waiting before closing the door! (30 seconds to enter the car...) 258 previousMillis = millis(); 259 digitalWrite(MOTOR_OBRIR, HIGH); 260 delay(500); 261C: 262 if (digitalRead(OBRIR) == LOW) { 263 goto SEQUENCIA_TANCAMENT; 264 }; 265 266 //--Time control and display refreshing--------------------- 267 currentMillis = millis(); 268 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 269 display.clearDisplay(); 270 display.setTextSize(1); 271 display.setCursor(0, 0); 272 display.println("Porta Oberta completament"); 273 display.setTextSize(2); 274 display.setCursor(90, 0); 275 display.println(TEMPS_DISPLAY); 276 display.setTextSize(1); 277 display.setCursor(0, 20); 278 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 279 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 280 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 281 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 282 display.display(); 283 if ((currentMillis - previousMillis) >= interval) { 284 goto SEQUENCIA_TANCAMENT; 285 }; 286 287 288 //--Special compound flashing frequency in waiting state------------------ 289 // (Short flashes of 100 milliseconds between long periods of 2 seconds) 290 if (LLUM == false) { 291 DURADA = 100; 292 } else DURADA = 2000; 293 if ((currentMillis - TEMPS_LLUM) >= DURADA) // 294 { 295 LLUM = !LLUM; 296 digitalWrite(BOMBETA, LLUM); 297 TEMPS_LLUM = currentMillis; 298 }; 299 300 goto C; 301 302} 303 304
English Software code version
c_cpp
Here you have the code with all the comments translated to english. It includes a short list of vocabulary in order to understand the meaning of variables and labels.
1/********************************************************************* 2 Automatism for sliding motorized door 3*********************************************************************/ 4 5/* Comments are translated to english, but in order to help 6 you understand the name of the variables and labels, here 7 you have a quick vocabulary "Catalan-English": 8 9 Bucle principal = Main loop 10 Sequencia Obertura = Opening sequence 11 Sequencia Tancament = Closing sequence 12 Obrir = Open ; Obert = Opened 13 Tancar = Close ; Tancat = Closed 14 Bombeta = Light bulb 15 Llum = light 16 Porta = Gate / door 17 Avaria = Failure 18 Temps = Time 19 Recorregut = door travel 20*/ 21 22 23// Libraries for Oled Display 24#include <SPI.h> 25#include <Wire.h> 26#include <Adafruit_GFX.h> 27#include <Adafruit_SSD1306.h> 28 29// We define the pins to be used by the control circuitry 30int FOTOCELULA = 2; 31int BOMBETA = 5; //Relay 1 32int TANCAT = 7; 33int OBERT = 3; 34int MOTOR_OBRIR = 6; //Relay 2 35int MOTOR_TANCAR = 12; //Relay 3 36int OBRIR = 4; 37 38// We define the pins to be used by the Oled display 39#define OLED_MOSI 11 40#define OLED_CLK 13 41#define OLED_DC 9 42#define OLED_CS 10 43#define OLED_RESET 8 44Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 45 46// We define global variables 47unsigned long TEMPS_PORTA_OBERTA = 20000; 48unsigned long TEMPS_MAXIM_RECORREGUT = 15000; //Later we'll redefine this value 49int interval = 1000; // Interval is how long we wait 50int TEMPS_DISPLAY = 1; // Time in seconds to display 51int DURADA = 300; // Cicle for light bulb 52unsigned long previousMillis = 0; // Tracks the time since last event fired 53unsigned long currentMillis = millis(); 54unsigned long TEMPS_LLUM = 1000; // time in milliseconds for light bulb status 55boolean LLUM = false; // light ON or OFF 56boolean AVARIA = false; //door travel time exceeded without detecting limiting switch 57 58void setup() { 59 // Turn off motor and light 60 digitalWrite(MOTOR_OBRIR, HIGH); 61 digitalWrite(MOTOR_TANCAR, HIGH); 62 digitalWrite(BOMBETA, HIGH); 63 64 // We initialize the pins for the automatism 65 pinMode(FOTOCELULA, INPUT_PULLUP); 66 pinMode(TANCAT, INPUT_PULLUP); 67 pinMode(OBERT, INPUT_PULLUP); 68 pinMode(OBRIR, INPUT_PULLUP); 69 pinMode(BOMBETA, OUTPUT); 70 pinMode(MOTOR_OBRIR, OUTPUT); 71 pinMode(MOTOR_TANCAR, OUTPUT); 72 73 // Display initialization 74 Serial.begin(9600); 75 display.begin(SSD1306_SWITCHCAPVCC); 76 display.display(); // Show Adafruit initial logo 77 delay(1000); 78 display.clearDisplay(); 79 display.display(); 80 81 // We prepare the text size for the display (not important because later it is dinamically redefined) 82 display.setTextSize(1); 83 display.setTextColor(WHITE); 84} 85 86 87 88void loop() { 89 90BUCLE_PRINCIPAL: 91 delay(2000); 92 previousMillis = millis(); 93 while (digitalRead(OBRIR) == HIGH) 94 { 95 display.clearDisplay(); 96 display.setTextSize(1); 97 display.setCursor(0, 0); 98 display.println("BUCLE PRINCIPAL ..."); 99 display.setTextSize(1); 100 display.setCursor(0, 20); 101 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 102 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 103 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 104 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 105 display.display(); 106 if (AVARIA and (millis() - previousMillis < 60000)) { 107 digitalWrite(BOMBETA, LOW); 108 } else (digitalWrite(BOMBETA, HIGH)); 109 }; // We wait until Open command is issued and meanwhile the display is being refreshed showing the status of the sensors 110 goto SEQUENCIA_OBERTURA; 111 112SEQUENCIA_OBERTURA: 113 interval = 28000; // Maximum time opening the door (if exceeded it will denote some failure) 114 previousMillis = millis(); 115 116 digitalWrite(MOTOR_OBRIR, LOW); 117 digitalWrite(BOMBETA, LOW); 118 delay(1000); 119A: 120 if (digitalRead(OBERT) == HIGH) { 121 goto PORTA_OBERTA; 122 }; 123 if (digitalRead(OBRIR) == LOW) 124 { 125 display.clearDisplay(); 126 display.setTextSize(1); 127 display.setCursor(0, 0); 128 display.println("Esperant ordre per tancar"); // "Waiting order to close" 129 display.setTextSize(1); 130 display.setCursor(0, 20); 131 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 132 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 133 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 134 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 135 display.display(); 136 137 digitalWrite(MOTOR_OBRIR, HIGH); 138 digitalWrite(BOMBETA, HIGH); 139 delay(1000); 140 while (digitalRead(OBRIR) == HIGH) {}; //Do nothing until OPEN command is issued 141 goto SEQUENCIA_TANCAMENT; 142 }; 143 144 //--Time control and display refreshing--------------- 145 currentMillis = millis(); 146 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 147 display.clearDisplay(); 148 display.setTextSize(1); 149 display.setCursor(0, 0); 150 display.println("Obrint porta"); 151 display.setTextSize(2); 152 display.setCursor(90, 0); 153 display.println(TEMPS_DISPLAY); 154 155 display.setTextSize(1); 156 display.setCursor(0, 20); 157 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 158 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 159 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 160 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 161 162 display.display(); 163 if ((currentMillis - previousMillis) >= interval) 164 { 165 digitalWrite(MOTOR_OBRIR, HIGH); 166 AVARIA = true; // 167 goto PORTA_OBERTA; 168 }; 169 170 //--light Flashing frequence control------------------ 171 if ((currentMillis - TEMPS_LLUM) >= 1000) //Flashing at low speed 172 { 173 LLUM = !LLUM; 174 digitalWrite(BOMBETA, LLUM); 175 TEMPS_LLUM = currentMillis; 176 }; 177 178 goto A; 179 180 181SEQUENCIA_TANCAMENT: 182 interval = 28000; // Maximum time closing the door (if exceeded it will denote some failure)! 183 previousMillis = millis(); 184 185 digitalWrite(MOTOR_TANCAR, LOW); 186 digitalWrite(BOMBETA, LOW); 187 if (digitalRead(TANCAT) == LOW) {delay(1000);}; 188B: 189 if (digitalRead(TANCAT) == HIGH) 190 { 191 digitalWrite(MOTOR_TANCAR, HIGH); 192 digitalWrite(BOMBETA, HIGH); 193 goto BUCLE_PRINCIPAL; 194 }; 195 if (digitalRead(OBRIR) == LOW) 196 { 197 display.clearDisplay(); 198 display.setTextSize(1); 199 display.setCursor(0, 0); 200 display.println("Esperant ordre per obrir"); 201 display.setTextSize(1); 202 display.setCursor(0, 20); 203 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 204 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 205 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 206 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 207 display.display(); 208 209 digitalWrite(MOTOR_TANCAR, HIGH); 210 digitalWrite(BOMBETA, HIGH); 211 delay(1000); 212 while (digitalRead(OBRIR) == HIGH) {}; //Do nothing until OPEN command is issued 213 goto SEQUENCIA_OBERTURA; 214 }; 215 if (digitalRead(FOTOCELULA) == HIGH) 216 { 217 digitalWrite(MOTOR_TANCAR, HIGH); 218 delay(1000); 219 220 goto SEQUENCIA_OBERTURA; 221 }; 222 223 //--Time control and display refreshing--------------------- 224 currentMillis = millis(); 225 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 226 display.clearDisplay(); 227 display.setTextSize(1); 228 display.setCursor(0, 0); 229 display.println("Tancant porta"); 230 display.setTextSize(2); 231 display.setCursor(90, 0); 232 display.println(TEMPS_DISPLAY); 233 display.setTextSize(1); 234 display.setCursor(0, 20); 235 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 236 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 237 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 238 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 239 display.display(); 240 if ((currentMillis - previousMillis) >= interval) { 241 digitalWrite(MOTOR_TANCAR, HIGH); 242 AVARIA = true; 243 goto BUCLE_PRINCIPAL; 244 }; 245 246 //--light Flashing frequence control------------------ 247 if ((currentMillis - TEMPS_LLUM) >= 300) // Flashing at fast speed 248 { 249 LLUM = !LLUM; 250 digitalWrite(BOMBETA, LLUM); 251 TEMPS_LLUM = currentMillis; 252 }; 253 254 goto B; 255 256PORTA_OBERTA: 257 interval = 30000; // Time waiting before closing the door! (30 seconds to enter the car...) 258 previousMillis = millis(); 259 digitalWrite(MOTOR_OBRIR, HIGH); 260 delay(500); 261C: 262 if (digitalRead(OBRIR) == LOW) { 263 goto SEQUENCIA_TANCAMENT; 264 }; 265 266 //--Time control and display refreshing--------------------- 267 currentMillis = millis(); 268 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 269 display.clearDisplay(); 270 display.setTextSize(1); 271 display.setCursor(0, 0); 272 display.println("Porta Oberta completament"); 273 display.setTextSize(2); 274 display.setCursor(90, 0); 275 display.println(TEMPS_DISPLAY); 276 display.setTextSize(1); 277 display.setCursor(0, 20); 278 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 279 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 280 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 281 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 282 display.display(); 283 if ((currentMillis - previousMillis) >= interval) { 284 goto SEQUENCIA_TANCAMENT; 285 }; 286 287 288 //--Special compound flashing frequency in waiting state------------------ 289 // (Short flashes of 100 milliseconds between long periods of 2 seconds) 290 if (LLUM == false) { 291 DURADA = 100; 292 } else DURADA = 2000; 293 if ((currentMillis - TEMPS_LLUM) >= DURADA) // 294 { 295 LLUM = !LLUM; 296 digitalWrite(BOMBETA, LLUM); 297 TEMPS_LLUM = currentMillis; 298 }; 299 300 goto C; 301 302} 303 304
Code
c_cpp
This is the C++ code to compile and upload to the Arduino Nano
1/********************************************************************* 2 Automatisme per porta corredera motoritzada 3*********************************************************************/ 4 5// Llibreries per fer servir el display 6#include <SPI.h> 7#include <Wire.h> 8#include <Adafruit_GFX.h> 9#include <Adafruit_SSD1306.h> 10 11// Definim pins per automatisme porta 12int FOTOCELULA = 2; 13int BOMBETA = 5; //Relay 1 14int TANCAT = 7; 15int OBERT = 3; 16int MOTOR_OBRIR = 6; //Relay 2 17int MOTOR_TANCAR = 12; //Relay 3 18int OBRIR = 4; 19 20// Definim pins per display 21#define OLED_MOSI 11 22#define OLED_CLK 13 23#define OLED_DC 9 24#define OLED_CS 10 25#define OLED_RESET 8 26Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 27 28// Definim variables globals 29unsigned long TEMPS_PORTA_OBERTA = 20000; 30unsigned long TEMPS_MAXIM_RECORREGUT = 15000; //Despres ho redefinim 31int interval = 1000; // Interval is how long we wait 32int TEMPS_DISPLAY = 1; // temps en segons per imprimir en pantalla 33int DURADA = 300; // Cicle bombeta senyalitzacio 34unsigned long previousMillis = 0; // Tracks the time since last event fired 35unsigned long currentMillis = millis(); 36unsigned long TEMPS_LLUM = 1000; // temps en milisegons de estat llum senyalitzacio 37boolean LLUM = false; // Llum encessa si ON i apagada si OFF 38boolean AVARIA = false; //Excedit el temps de recorregut sense detectar finals de carrera 39 40void setup() { 41 // Inicialitzem els pins per automatisme porta 42 pinMode(FOTOCELULA, INPUT_PULLUP); 43 pinMode(TANCAT, INPUT_PULLUP); 44 pinMode(OBERT, INPUT_PULLUP); 45 pinMode(OBRIR, INPUT_PULLUP); 46 pinMode(BOMBETA, OUTPUT); 47 pinMode(MOTOR_OBRIR, OUTPUT); 48 pinMode(MOTOR_TANCAR, OUTPUT); 49 50 // Apaguem motors i llum 51 digitalWrite(MOTOR_OBRIR, HIGH); 52 digitalWrite(MOTOR_TANCAR, HIGH); 53 digitalWrite(BOMBETA, HIGH); 54 55 // Inicialitzem el display 56 Serial.begin(9600); 57 display.begin(SSD1306_SWITCHCAPVCC); 58 display.display(); // Mostra pantalla inicial de Adafruit 59 delay(1000); 60 display.clearDisplay(); 61 display.display(); 62 63 // preparem el display per texte 64 display.setTextSize(1); 65 display.setTextColor(WHITE); 66} 67 68 69 70void loop() { 71 72BUCLE_PRINCIPAL: 73 delay(2000); 74 previousMillis = millis(); 75 while (digitalRead(OBRIR) == HIGH) 76 { 77 display.clearDisplay(); 78 display.setTextSize(1); 79 display.setCursor(0, 0); 80 display.println("BUCLE PRINCIPAL ..."); 81 display.setTextSize(1); 82 display.setCursor(0, 20); 83 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 84 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 85 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 86 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 87 display.display(); 88 if (AVARIA and (millis() - previousMillis < 60000)) { 89 digitalWrite(BOMBETA, LOW); 90 } else (digitalWrite(BOMBETA, HIGH)); 91 }; //Esperem fins que premem OBRIR i anem refrescant pantalla per mostrar estat sensors 92 goto SEQUENCIA_OBERTURA; 93 94SEQUENCIA_OBERTURA: 95 interval = 28000; // TEMPS MAXIM DE RECORREGUT PORTA OBRINT !!!!!!!!! 96 previousMillis = millis(); 97 98 digitalWrite(MOTOR_OBRIR, LOW); 99 digitalWrite(BOMBETA, LOW); 100 delay(1000); 101A: 102 if (digitalRead(OBERT) == HIGH) { 103 goto PORTA_OBERTA; 104 }; 105 if (digitalRead(OBRIR) == LOW) 106 { 107 display.clearDisplay(); 108 display.setTextSize(1); 109 display.setCursor(0, 0); 110 display.println("Esperant ordre per tancar"); 111 display.setTextSize(1); 112 display.setCursor(0, 20); 113 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 114 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 115 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 116 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 117 display.display(); 118 119 digitalWrite(MOTOR_OBRIR, HIGH); 120 digitalWrite(BOMBETA, HIGH); 121 delay(1000); 122 while (digitalRead(OBRIR) == HIGH) {}; //No fem res fins que premem OBRIR 123 goto SEQUENCIA_TANCAMENT; 124 }; 125 126 //--Control-de-temps-i-impressió-en-pantalla--------------------- 127 currentMillis = millis(); 128 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 129 display.clearDisplay(); 130 display.setTextSize(1); 131 display.setCursor(0, 0); 132 display.println("Obrint porta"); 133 display.setTextSize(2); 134 display.setCursor(90, 0); 135 display.println(TEMPS_DISPLAY); 136 137 display.setTextSize(1); 138 display.setCursor(0, 20); 139 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 140 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 141 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 142 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 143 144 display.display(); 145 if ((currentMillis - previousMillis) >= interval) 146 { 147 digitalWrite(MOTOR_OBRIR, HIGH); 148 AVARIA = true; // 149 goto PORTA_OBERTA; 150 }; 151 152 //--Control-de-cadencia-de-la-llum-intermitent------------------ 153 if ((currentMillis - TEMPS_LLUM) >= 1000) // Cadencia de la llum intermitent de senyalitzacio 154 { 155 LLUM = !LLUM; 156 digitalWrite(BOMBETA, LLUM); 157 TEMPS_LLUM = currentMillis; 158 }; 159 160 goto A; 161 162 163SEQUENCIA_TANCAMENT: 164 interval = 28000; // TEMPS MAXIM DE RECORREGUT PORTA TANCANT !!!!!!!!! 165 previousMillis = millis(); 166 167 digitalWrite(MOTOR_TANCAR, LOW); 168 digitalWrite(BOMBETA, LOW); 169 if (digitalRead(TANCAT) == LOW) {delay(1000);}; 170B: 171 if (digitalRead(TANCAT) == HIGH) 172 { 173 digitalWrite(MOTOR_TANCAR, HIGH); 174 digitalWrite(BOMBETA, HIGH); 175 goto BUCLE_PRINCIPAL; 176 }; 177 if (digitalRead(OBRIR) == LOW) 178 { 179 display.clearDisplay(); 180 display.setTextSize(1); 181 display.setCursor(0, 0); 182 display.println("Esperant ordre per obrir"); 183 display.setTextSize(1); 184 display.setCursor(0, 20); 185 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 186 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 187 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 188 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 189 display.display(); 190 191 digitalWrite(MOTOR_TANCAR, HIGH); 192 digitalWrite(BOMBETA, HIGH); 193 delay(1000); 194 while (digitalRead(OBRIR) == HIGH) {}; //No fem res fins que premem OBRIR 195 goto SEQUENCIA_OBERTURA; 196 }; 197 if (digitalRead(FOTOCELULA) == HIGH) 198 { 199 digitalWrite(MOTOR_TANCAR, HIGH); 200 delay(1000); 201 202 goto SEQUENCIA_OBERTURA; 203 }; 204 205 //--Control-de-temps-i-impressió-en-pantalla--------------------- 206 currentMillis = millis(); 207 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 208 display.clearDisplay(); 209 display.setTextSize(1); 210 display.setCursor(0, 0); 211 display.println("Tancant porta"); 212 display.setTextSize(2); 213 display.setCursor(90, 0); 214 display.println(TEMPS_DISPLAY); 215 display.setTextSize(1); 216 display.setCursor(0, 20); 217 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 218 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 219 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 220 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 221 display.display(); 222 if ((currentMillis - previousMillis) >= interval) { 223 digitalWrite(MOTOR_TANCAR, HIGH); 224 AVARIA = true; 225 goto BUCLE_PRINCIPAL; 226 }; 227 228 //--Control-de-cadencia-de-la-llum-intermitent------------------ 229 if ((currentMillis - TEMPS_LLUM) >= 300) // Cadencia de la llum intermitent de senyalitzacio 230 { 231 LLUM = !LLUM; 232 digitalWrite(BOMBETA, LLUM); 233 TEMPS_LLUM = currentMillis; 234 }; 235 236 goto B; 237 238PORTA_OBERTA: 239 interval = 30000; // TEMPS MAXIM ESPERANT AMB PORTA OBERTA !!!!!!!!! 240 previousMillis = millis(); 241 digitalWrite(MOTOR_OBRIR, HIGH); 242 delay(500); 243C: 244 if (digitalRead(OBRIR) == LOW) { 245 goto SEQUENCIA_TANCAMENT; 246 }; 247 248 //--Control-de-temps-i-impressió-en-pantalla--------------------- 249 currentMillis = millis(); 250 TEMPS_DISPLAY = (currentMillis - previousMillis) / 1000; 251 display.clearDisplay(); 252 display.setTextSize(1); 253 display.setCursor(0, 0); 254 display.println("Porta Oberta completament"); 255 display.setTextSize(2); 256 display.setCursor(90, 0); 257 display.println(TEMPS_DISPLAY); 258 display.setTextSize(1); 259 display.setCursor(0, 20); 260 display.print("Fotocel.lula: "); display.println(digitalRead(FOTOCELULA)); 261 display.print("Sensor TANCAT: "); display.println(digitalRead(TANCAT)); 262 display.print("Sensor OBERT: "); display.println(digitalRead(OBERT)); 263 display.print("Ordre OBRIR: "); display.println(!digitalRead(OBRIR)); 264 display.display(); 265 if ((currentMillis - previousMillis) >= interval) { 266 goto SEQUENCIA_TANCAMENT; 267 }; 268 269 270 //--Control-de-cadencia-de-la-llum-intermitent------------------ 271 if (LLUM == false) { 272 DURADA = 100; 273 } else DURADA = 2000; 274 if ((currentMillis - TEMPS_LLUM) >= DURADA) // Cadencia de la llum intermitent de senyalitzacio 275 { 276 LLUM = !LLUM; 277 digitalWrite(BOMBETA, LLUM); 278 TEMPS_LLUM = currentMillis; 279 }; 280 281 goto C; 282 283} 284
Downloadable files
Schematics
Screenshoot from fritzing schematics
Schematics
Main circuitry for control unit in FZZ format
How to connect the wiring to sensors, relays and radio module from the main control unit.
Main circuitry for control unit in FZZ format
Main circuitry for control unit in FZZ format
How to connect the wiring to sensors, relays and radio module from the main control unit.
Main circuitry for control unit in FZZ format
Safety relay
This hardware addon is in response to the question from irshad2318 (see the posts for this project)
Safety relay
Pinouts
This is the list of the used Arduino pins and how to connect them to the rest of the components.
Pinouts
Schematics
Screenshoot from fritzing schematics
Schematics
Safety relay
This hardware addon is in response to the question from irshad2318 (see the posts for this project)
Safety relay
Comments
Only logged in users can leave comments
DVDMDN
0 Followers
•0 Projects
0