En cada intersección, siempre hay un pequeño tablero de control que gobierna los tiempos en verde, amarillo y rojo. Y justamente hoy, vamos a aprender a crear la tarjeta de control, el cerebro que gestiona toda la secuencia del grupo de semáforos. Veremos desde el esquemático electrónico, el diseño de la PCB y la programación.
DATOS TÉCNICOS

- Tensión de alimentación……………………….…………100-240Vac
- Corriente de alimentación………………….……………60mA
- Entrada Digital ………………………………..…………………1
- Pulsadores de configuracion de tiempos………………Sí
- Puerto programacion ISP……………………………………Sí
- Pantalla lcd 16*2……………………………………………….Sí
- Barra de led señalizadores de nivel de semaforo……….Sí
- Entorno de programación-………………………………………..Arduino IDE
- Condiciones ambientales min………………………….-10°
- Condiciones ambientales max…………………..…….55
- capacidad de control…………………………………………….4 fases
- Salida a triac 6A…………………………………… 12
LISTA DE MATERIALES

| Qtity | Comment | Designator | Footprint | Value | Manufacturer Part | Manufacturer | Supplier Part |
| 1 | BS-2-1 | B1 | BAT-TH_BS-2-1 | BS-2-1 | Q&J | C70376 | |
| 11 | 100nF | C1,C3,C4,C5,C8,C11, C12,C13,C14,C15,C17 |
C0603 | 100nF | CC0603KRX7R9BB104 | YAGEO(国巨) | C14663 |
| 3 | 10uF | C2,C6,C7 | CAP-SMD_L3.2-W1.6-RD-C7171 | 10uF | TAJA106K016RNJ | Kyocera AVX | C7171 |
| 2 | 22pF | C9,C10 | C0603 | 22pF | CL10C220JB8NNNC | SAMSUNG(三星) | C1653 |
| 1 | 470uF | C16 | CAP-SMD_BD8.0-L8.3-W8.3-LS8.9-FD | 470uF | CK1C471M-CRF10 | ROQANG(容强) | C5162359 |
| 12 | 100nF | C18,C19,C20,C21,C22,C23, C24,C25,C26,C27,C28,C29 |
CAP-TH_L12.0-W4.0-P10.00-D0.6 | 100nF | CFC2E104JE1I120B5100 | Dersonic(德尔创) | C2681661 |
| 3 | 1N5819WS | D1,D2,D3 | SOD-323_L1.8-W1.3-LS2.5-RD | 1N5819WS | Hottech(合科泰) | C191023 | |
| 1 | 5x20BLX-A型保险丝支架XC-7 | F1 | FUSE-TH_L22.6-W9.0 | 5x20BLX-A型保险丝支架XC-7 | xcfuse(旭程) | C3131 | |
| 24 | fuse_Holder | FH1,FH2,FH3,FH4,FH5,FH6,FH7, FH8,FH9,FH10,FH11,FH12,FH13, FH14,FH15,FH16,FH17,FH18,FH19, FH20,FH21,FH22,FH23,FH24 |
Fuse_Holder | ||||
| 1 | 2.54-1x6P直针 | H1 | HDR-TH_6P-P2.54-V-M-1 | 2.54-1x6P直针 | BOOMELE(博穆精密) | C37208 | |
| 1 | PZ254R-11-06P | H2 | HDR-TH_6P-P2.54-H-M-W10.4 | PZ254R-11-06P | XFCN(兴飞) | C492414 | |
| 1 | LCD-16X2 | LCD1 | LCD-16X2 | ||||
| 4 | NCD0805R1 | LED1,LED4,LED7,LED10 | LED0805-R-RD | NCD0805R1 | 国星光电 | C84256 | |
| 4 | KT-0805Y | LED2,LED5,LED8,LED11 | LED0805-R-RD | KT-0805Y | KENTO | C2296 | |
| 4 | KT-0805G | LED3,LED6,LED9,LED12 | LED0805-R-RD | KT-0805G | KENTO | C2297 | |
| 1 | WJ128V-5.0-3P | P1 | CONN-TH_3P-P5.00_WJ128V-5.0-3P | WJ128V-5.0-3P | KANGNEX(康奈克斯电气) | C8270 | |
| 1 | WJ45C-B-9.5-2P | P2 | CONN-TH_2P-P9.50_WJ45C-B-2P | WJ45C-B-9.5-2P | KANGNEX(康奈克斯电气) | C8397 | |
| 4 | HB9500-9.5-4P | P3,P4,P5,P6 | CONN-TH_4P-P9.50_WJ9500-9.5-4P-13-00A | HB9500-9.5-4P | KANGNEX(康奈克斯电气) | C72338 | |
| 1 | S8550(RANGE:120-200) | Q1 | SOT-23-3_L2.9-W1.6-P1.90-LS2.8-BR | S8550(RANGE:120-200) | CJ(江苏长电/长晶) | C105432 | |
| 12 | MMBT2222A 1P | Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9, Q10,Q11,Q12,Q13 |
SOT-23-3_L2.9-W1.3-P1.90-LS2.4-BR | MMBT2222A 1P | CJ(江苏长电/长晶) | C8512 | |
| 12 | BTB16Q-600BW | Q14,Q15,Q16,Q17,Q18,Q19, Q20,Q21,Q22,Q23,Q24,Q25 |
TO-263AB_L10.0-W9.2-P5.08-LS15.4-BL | BTB16Q-600BW | FUXINSEMI(富芯森美) | C918191 | |
| 1 | 10kΩ | R1 | RES-ADJ-SMD_3P-L3.0-W3.8-P1.75-BR | 10kΩ | TC33X-2-103E | BOURNS | C719176 |
| 1 | 200Ω | R2 | R0805 | 200Ω | 0805W8F2000T5E | UNI-ROYAL(厚声) | C17540 |
| 3 | 4.7kΩ | R3,R4,R5 | R0603 | 4.7kΩ | 0603WAF4701T5E | UNI-ROYAL(厚声) | C23162 |
| 1 | 510kΩ | R6 | R0603 | 510kΩ | 0603WAF5103T5E | UNI-ROYAL(厚声) | C23192 |
| 19 | 10kΩ | R7,R11,R12,R15,R16,R17,R18,R19,R21, R23,R25,R27,R29,R31,R33,R35,R37,R39,R41 |
R0603 | 10kΩ | 0603WAF1002T5E | UNI-ROYAL(厚声) | C25804 |
| 2 | 1MΩ | R8,R9 | R0603 | 1MΩ | 0603WAF1004T5E | UNI-ROYAL(厚声) | C22935 |
| 26 | 330Ω | R10,R14,R43,R44,R45,R46,R47,R48,R49, R50,R51,R52,R53,R54,R55,R56,R57,R58, R59,R60,R61,R62,R63,R64,R65,R66 |
R0805 | 330Ω | 0805W8F3300T5E | UNI-ROYAL(厚声) | C17630 |
| 13 | 1kΩ | R13,R20,R22,R24,R26,R28,R30,R32, R34,R36,R38,R40,R42 |
R0603 | 1kΩ | 0603WAF1001T5E | UNI-ROYAL(厚声) | C21190 |
| 24 | 120Ω | R67,R68,R69,R70,R71,R72,R73, R74,R75,R76,R77,R78,R79,R80,R81, R82,R83,R84,R85,R86,R87,R88,R89,R90 |
R1206 | 120Ω | 1206W4F1200T5E | UNI-ROYAL(厚声) | C17909 |
| 7 | TS665CJ | SW1,SW2,SW3,SW5,SW6,SW7,SW8 | SW-TH_4P-L6.0-W6.0-P4.50-LS6.5 | TS665CJ | SHOU HAN(首韩) | C393938 | |
| 1 | DSWB02LHGET | SW4 | SW-TH_DSWB02LHGET | DSWB02LHGET | YE | C99421 | |
| 1 | ATMEGA328P-AU | U1 | TQFP-32_L7.0-W7.0-P0.80-LS9.0-BL | ATMEGA328P-AU | MICROCHIP(美国微芯) | C14877 | |
| 1 | DS1307ZN+T&R | U2 | SOP-8_L4.9-W3.9-P1.27-LS6.0-BL | DS1307ZN+T&R | ADI(亚德诺)/MAXIM(美信) | C26858 | |
| 1 | AT24C02 | U3 | SOP-8_L4.9-W3.9-P1.27-LS6.0-BL | AT24C02 | HXY MOSFET(华轩阳电子) | C7470930 | |
| 1 | PCF8574T/TR | U4 | SO-16_L10.3-W7.5-P1.27-LS10.3-BL | PCF8574T/TR | HGSEMI(华冠) | C2987288 | |
| 2 | EL3H7(B)(TA)-G | U5,U7 | SOP-4_L4.4-W2.8-P1.27-LS7.0-TL | EL3H7(B)(TA)-G | EVERLIGHT(亿光) | C32565 | |
| 2 | 74HC595D,118 | U6,U8 | SOIC-16_L9.9-W3.9-P1.27-LS6.0-BL | 74HC595D,118 | Nexperia(安世) | C5947 | |
| 1 | TAS5-5-WEDT | U9 | PWRM-TH_TAS5-X-WEDT | TAS5-5-WEDT | TDPOWER(腾达电源) | C2687651 | |
| 12 | MOC3083S-TA1 | U10,U11,U12,U13,U14,U15, U16,U17,U18,U19,U20,U21 |
SMD-6_L7.3-W6.5-P2.54-LS10.2-BL | MOC3083S-TA1 | LITEON(光宝) | C115474 | |
| 1 | 10D561K | VR1 | RES-TH_L13.0-W6.0-P7.50-D0.9-S6.00 | 10D561K | HEL(鸿志) | C113236 | |
| 1 | 32.768kHz | X1 | FC-135R_L3.2-W1.5 | 32.768kHz | Q13FC13500004 | EPSON(爱普生) | C32346 |
| 1 | 16MHz | X2 | CRYSTAL-SMD_4P-L3.2-W2.5-BL | 16MHz | TAXM16M4RLBCCT2T | YJX(雅晶鑫) | C164049 |
CONEXIONES EXTERNAS


CODIGO

#include <EEPROM.h>
#include <Wire.h>
#include "RTClib.h"
#define SW4_A 2
#define SW4_B 3
#define link_in 9
#define link_out 10
#define no_use 17
#define spi1 13
#define spi2 12
#define spi3 11
// Pines para el 74hc595
byte clockpin = 14; // SH
byte data = 15; // DS
byte latch = 16; // ST
// Objeto RTC
RTC_DS1307 rtc;
// Variables de control
enum Estado { NORMAL,
AMARILLO,
TODOS_ROJO,
APAGADO };
Estado estado = NORMAL;
unsigned long tiempoInicioFase;
int faseActual = 0;
// Configuraciones almacenadas en EEPROM
byte contador_fases_M = 2;
byte duracionesVerde[4];
const int duracionAmarillo = 3;
const int duracionTodosRojo = 2;
byte hora_apagado_M = 23;
byte minu_apagado_M = 30;
byte hora_encendido_M = 4;
byte minu_encendido_M = 30;
// Patrones de luces
const int lights_1_8[] = {0, 50, 82, 134, 138, 144, 145, 146, 146, 146};
const int lights_9_16[] = {0, 64, 76, 74, 65, 193, 76, 29, 39, 64};
void setup() {
Wire.begin();
rtc.begin();
// Configurar pines
pinMode(clockpin, OUTPUT);
pinMode(data, OUTPUT);
pinMode(latch, OUTPUT);
pinMode(SW4_A, INPUT);
pinMode(SW4_B, INPUT);
pinMode(link_in, INPUT);
pinMode(link_out, OUTPUT);
pinMode(no_use, OUTPUT);
pinMode(spi1, OUTPUT);
pinMode(spi2, OUTPUT);
pinMode(spi3, OUTPUT);
// Leer configuración de EEPROM
contador_fases_M = EEPROM.read(direc_fases);
loadDuracionesDeEEPROM();
hora_apagado_M = EEPROM.read(direc_hora_apagado);
minu_apagado_M = EEPROM.read(direc_minu_apagado);
hora_encendido_M = EEPROM.read(direc_hora_encendido);
minu_encendido_M = EEPROM.read(direc_minu_encendido);
tiempoInicioFase = rtc.now().unixtime();
cambiarFase(0);
}
void loop() {
DateTime now = rtc.now();
int horaActual = now.hour();
int minutoActual = now.minute();
// Verificar horario de apagado
bool fueraHorario = false;
if (hora_apagado_M < hora_encendido_M ||
(hora_apagado_M == hora_encendido_M && minu_apagado_M < minu_encendido_M)) {
fueraHorario = (horaActual > hora_apagado_M ||
(horaActual == hora_apagado_M && minutoActual >= minu_apagado_M)) &&
(horaActual < hora_encendido_M ||
(horaActual == hora_encendido_M && minutoActual < minu_encendido_M));
} else {
fueraHorario = (horaActual > hora_apagado_M ||
(horaActual == hora_apagado_M && minutoActual >= minu_apagado_M)) ||
(horaActual < hora_encendido_M ||
(horaActual == hora_encendido_M && minutoActual < minu_encendido_M));
}
if (fueraHorario) {
if (estado != APAGADO) {
estado = APAGADO;
apagarLuces();
}
return;
}
if (estado == APAGADO) {
estado = NORMAL;
tiempoInicioFase = now.unixtime();
cambiarFase(faseActual);
}
unsigned long tiempoActual = now.unixtime();
unsigned long tiempoTranscurrido = tiempoActual - tiempoInicioFase;
switch (estado) {
case NORMAL:
if (tiempoTranscurrido >= duracionesVerde[faseActual]) {
iniciarTransicion();
}
break;
case AMARILLO:
if (tiempoTranscurrido >= duracionAmarillo) {
estado = TODOS_ROJO;
tiempoInicioFase = now.unixtime();
apagarLuces();
lights = 9;
lights_OUT();
}
break;
case TODOS_ROJO:
if (tiempoTranscurrido >= duracionTodosRojo) {
estado = NORMAL;
tiempoInicioFase = now.unixtime();
cambiarFase((faseActual + 1) % contador_fases_M);
}
break;
}
}
// Funciones de control de luces
void iniciarTransicion() {
estado = AMARILLO;
tiempoInicioFase = rtc.now().unixtime();
lights = (faseActual * 2) + 2;
lights_OUT();
}
void cambiarFase(int nuevaFase) {
apagarLuces();
lights = (nuevaFase * 2) + 1;
lights_OUT();
faseActual = nuevaFase;
}
void apagarLuces() {
lights = 0;
lights_OUT();
}
void lights_OUT() {
digitalWrite(latch, LOW);
shiftOut(data, clockpin, LSBFIRST, lights_9_16[lights]);
shiftOut(data, clockpin, LSBFIRST, lights_1_8[lights]);
digitalWrite(latch, HIGH);
}
// Funciones EEPROM
void loadDuracionesDeEEPROM() {
EEPROM.get(direc_tiempo_ledGreen_Fase1, duracionesVerde[0]);
EEPROM.get(direc_tiempo_ledGreen_Fase2, duracionesVerde[1]);
EEPROM.get(direc_tiempo_ledGreen_Fase3, duracionesVerde[2]);
EEPROM.get(direc_tiempo_ledGreen_Fase4, duracionesVerde[3]);
}


