#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h> // Biblioteca pentru DHT22
#define DHTPIN 7 // Pinul unde conectezi OUT-ul de la DHT22
#define DHTTYPE DHT22 // Specificăm tipul de senzor
DHT dht(DHTPIN, DHTTYPE); // Inițializează senzorul DHT
#define buzzerPin 6 // Sau alt pin liber
// === LEDURI SEMAFOR MAȘINI ===
#define dir1_green 50
#define dir1_yellow 53
#define dir2_green 40
#define dir2_yellow 38
#define dir3_green 49
#define dir3_yellow 48
#define dir4_green 41
#define dir4_yellow 39
#define phase_1_red 52
#define phase_2_red 51
#define intermitent_1_green 46
#define intermitent_2_green 47
// === SEMAFOR PIETONI ===
#define pietoni_1_red 45
#define pietoni_1_green 43
#define pietoni_2_red 44
#define pietoni_2_green 42
// === LCD-uri ===
LiquidCrystal_I2C lcd_faza1_stanga(0x25, 16, 2);
LiquidCrystal_I2C lcd_faza1_dreapta(0x24, 16, 2);
LiquidCrystal_I2C lcd_faza2_jos(0x26, 16, 2);
LiquidCrystal_I2C lcd_faza2_sus(0x27, 16, 2);
// === Senzori pentru direcția 1 (dar montați în dreapta) ===
#define trig1A 26
#define echo1A 27
#define trig1B 28
#define echo1B 29
// === Senzori pentru directia 2 (dar montati in stanga) ===
#define trig2A 22
#define echo2A 23
#define trig2B 24
#define echo2B 25
// === Senzori pentru directia 3 (montati in partea de jos) ===
#define trig3A 34
#define echo3A 35
#define trig3B 36
#define echo3B 37
// === Senzori pentru directia 4 (montati in partea de sus) ===
#define trig4A 30
#define echo4A 31
#define trig4B 32
#define echo4B 33
int greenCarTime = 20000;
int greenPedTime = 16000;
int yellowTime = 3000;
unsigned long blockStartTimeDir1 = 0;
unsigned long blockStartTimeDir2 = 0;
unsigned long blockStartTimeDir3 = 0;
unsigned long blockStartTimeDir4 = 0;
bool galbenConstantDir1 = false;
bool galbenConstantDir2 = false;
bool galbenConstantDir3 = false;
bool galbenConstantDir4 = false;
bool detectieDir1 = false;
bool asteaptaDeblocareDir1 = false;
bool detectieDir2 = false;
bool asteaptaDeblocareDir2 = false;
bool detectieDir3 = false;
bool asteaptaDeblocareDir3 = false;
bool detectieDir4 = false;
bool asteaptaDeblocareDir4 = false;
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(dir1_green, OUTPUT); pinMode(dir1_yellow, OUTPUT);
pinMode(dir2_green, OUTPUT); pinMode(dir2_yellow, OUTPUT);
pinMode(dir3_green, OUTPUT); pinMode(dir3_yellow, OUTPUT);
pinMode(dir4_green, OUTPUT); pinMode(dir4_yellow, OUTPUT);
pinMode(phase_1_red, OUTPUT); pinMode(phase_2_red, OUTPUT);
pinMode(intermitent_1_green, OUTPUT); pinMode(intermitent_2_green, OUTPUT);
pinMode(pietoni_1_red, OUTPUT); pinMode(pietoni_1_green, OUTPUT);
pinMode(pietoni_2_red, OUTPUT); pinMode(pietoni_2_green, OUTPUT);
// Senzori ultrasonic direcția 1 (montați în dreapta)
pinMode(trig1A, OUTPUT); pinMode(echo1A, INPUT);
pinMode(trig1B, OUTPUT); pinMode(echo1B, INPUT);
// Senzori ultrasonic direcția 2 (montați în stânga)
pinMode(trig2A, OUTPUT); pinMode(echo2A, INPUT);
pinMode(trig2B, OUTPUT); pinMode(echo2B, INPUT);
// Senzori ultrasonic direcția 3 (montați în partea de jos)
pinMode(trig3A, OUTPUT); pinMode(echo3A, INPUT);
pinMode(trig3B, OUTPUT); pinMode(echo3B, INPUT);
// Senzori ultrasonic direcția 4 (montați în partea de sus)
pinMode(trig4A, OUTPUT); pinMode(echo4A, INPUT);
pinMode(trig4B, OUTPUT); pinMode(echo4B, INPUT);
lcd_faza1_stanga.init(); lcd_faza1_stanga.backlight();
lcd_faza1_dreapta.init(); lcd_faza1_dreapta.backlight();
lcd_faza2_jos.init(); lcd_faza2_jos.backlight();
lcd_faza2_sus.init(); lcd_faza2_sus.backlight();
// Golește toate ecranele la pornire
lcd_faza1_stanga.clear();
lcd_faza1_dreapta.clear();
lcd_faza2_jos.clear();
lcd_faza2_sus.clear();
dht.begin(); // Pornim senzorul de temperatură
}
long readDistanceCM(int trigPin, int echoPin) {
digitalWrite(trigPin, LOW); delayMicroseconds(2);
digitalWrite(trigPin, HIGH); delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
return duration * 0.034 / 2;
}
void loop() {
float temperatura = dht.readTemperature(); // Citim temperatura (în grade Celsius)
// === FAZA 1 ===
// Resetare forțată afișaj + leduri direcția 3 și 4
galbenConstantDir3 = false;
detectieDir3 = false;
asteaptaDeblocareDir3 = false;
digitalWrite(dir3_yellow, LOW);
digitalWrite(dir3_green, LOW);
lcd_faza2_sus.clear();
galbenConstantDir4 = false;
detectieDir4 = false;
asteaptaDeblocareDir4 = false;
digitalWrite(dir4_yellow, LOW);
digitalWrite(dir4_green, LOW);
lcd_faza2_jos.clear();
digitalWrite(phase_1_red, LOW);
digitalWrite(phase_2_red, HIGH);
digitalWrite(dir1_green, HIGH);
digitalWrite(dir2_green, HIGH);
digitalWrite(pietoni_1_green, HIGH); digitalWrite(pietoni_1_red, LOW);
digitalWrite(pietoni_2_green, LOW); digitalWrite(pietoni_2_red, HIGH);
// === Verde intermitent pe direcția 2 ===
unsigned long startTime1 = millis();
unsigned long intermitentStart1 = startTime1 + 1000;
unsigned long intermitentEnd1 = startTime1 + greenCarTime;
while (millis() - startTime1 < greenPedTime) {
// Verde intermitent faza 1 (direcția 2)
if (millis() >= intermitentStart1 && millis() < intermitentEnd1) {
digitalWrite(intermitent_2_green, HIGH); delay(250);
digitalWrite(intermitent_2_green, LOW); delay(250);
}
//buzzer
digitalWrite(buzzerPin, HIGH);
delay(200);
digitalWrite(buzzerPin, LOW);
delay(200);
//temperatura
if (!galbenConstantDir1 && !galbenConstantDir2 && !galbenConstantDir3 && !galbenConstantDir4) {
lcd_faza1_stanga.setCursor(0, 0);
lcd_faza1_stanga.print(temperatura, 1); // afișează temperatura cu o zecimală
lcd_faza1_stanga.print((char)223);
lcd_faza1_stanga.print("C");
lcd_faza1_dreapta.setCursor(0, 0);
lcd_faza1_dreapta.print(temperatura, 1);
lcd_faza1_dreapta.print((char)223);
lcd_faza1_dreapta.print("C");
lcd_faza2_sus.setCursor(0, 0);
lcd_faza2_sus.print(temperatura, 1);
lcd_faza2_sus.print((char)223);
lcd_faza2_sus.print("C");
lcd_faza2_jos.setCursor(0, 0);
lcd_faza2_jos.print(temperatura, 1);
lcd_faza2_jos.print((char)223);
lcd_faza2_jos.print("C");
}
// Citire senzorii din DREAPTA pentru semaforul directia 1 (STANGA)
long d1 = readDistanceCM(trig1A, echo1A);
long d2 = readDistanceCM(trig1B, echo1B);
// === Detectare blocaj ===
if (d1 < 5 && d2 < 5) {
if (!detectieDir1) {
detectieDir1 = true;
blockStartTimeDir1 = millis();
}
if (!galbenConstantDir1 && millis() - blockStartTimeDir1 >= 5000) {
galbenConstantDir1 = true;
asteaptaDeblocareDir1 = false;
digitalWrite(dir1_green, LOW);
digitalWrite(dir1_yellow, HIGH);
lcd_faza1_stanga.clear();
lcd_faza1_stanga.setCursor(0, 0);
lcd_faza1_stanga.print("STOP INTERSECTIE");
lcd_faza1_stanga.setCursor(0, 1);
lcd_faza1_stanga.print("BLOCATA");
}
} else {
if (galbenConstantDir1 && !asteaptaDeblocareDir1) {
blockStartTimeDir1 = millis(); // începe cronometrul de revenire
asteaptaDeblocareDir1 = true;
}
if (asteaptaDeblocareDir1 && millis() - blockStartTimeDir1 >= 5000) {
galbenConstantDir1 = false;
detectieDir1 = false;
asteaptaDeblocareDir1 = false;
digitalWrite(dir1_yellow, LOW);
digitalWrite(dir1_green, HIGH);
lcd_faza1_stanga.clear();
}
}
// Citire senzorii din STANGA pentru semaforul directia 2 (DREAPTA)
long d3 = readDistanceCM(trig2A, echo2A);
long d4 = readDistanceCM(trig2B, echo2B);
if (d3 < 5 && d4 < 5) {
if (!detectieDir2) {
detectieDir2 = true;
blockStartTimeDir2 = millis();
}
if (!galbenConstantDir2 && millis() - blockStartTimeDir2 >= 5000) {
galbenConstantDir2 = true;
asteaptaDeblocareDir2 = false;
digitalWrite(dir2_green, LOW);
digitalWrite(dir2_yellow, HIGH);
lcd_faza1_dreapta.clear();
lcd_faza1_dreapta.setCursor(0, 0);
lcd_faza1_dreapta.print("STOP INTERSECTIE");
lcd_faza1_dreapta.setCursor(0, 1);
lcd_faza1_dreapta.print("BLOCATA");
}
} else {
if (galbenConstantDir2 && !asteaptaDeblocareDir2) {
blockStartTimeDir2 = millis(); // start timer de revenire
asteaptaDeblocareDir2 = true;
}
if (asteaptaDeblocareDir2 && millis() - blockStartTimeDir2 >= 5000) {
galbenConstantDir2 = false;
detectieDir2 = false;
asteaptaDeblocareDir2 = false;
digitalWrite(dir2_yellow, LOW);
digitalWrite(dir2_green, HIGH);
lcd_faza1_dreapta.clear();
}
}
}
// === Pietoni 1 roșu ===
digitalWrite(pietoni_1_green, LOW);
digitalWrite(pietoni_1_red, HIGH);
delay(greenCarTime - greenPedTime);
// === GALBEN faza 1 ===
digitalWrite(dir1_green, LOW); digitalWrite(dir2_green, LOW);
digitalWrite(dir1_yellow, HIGH); digitalWrite(dir2_yellow, HIGH);
delay(yellowTime);
// === ROȘU-ROȘU 2 sec ===
digitalWrite(dir1_yellow, LOW); digitalWrite(dir2_yellow, LOW);
digitalWrite(phase_1_red, HIGH);
delay(2000);
// === FAZA 2 ===
// Resetare forțată afișaj + leduri direcția 1 și 2
galbenConstantDir1 = false;
detectieDir1 = false;
asteaptaDeblocareDir1 = false;
digitalWrite(dir1_yellow, LOW);
digitalWrite(dir1_green, LOW);
lcd_faza1_stanga.clear();
galbenConstantDir2 = false;
detectieDir2 = false;
asteaptaDeblocareDir2 = false;
digitalWrite(dir2_yellow, LOW);
digitalWrite(dir2_green, LOW);
lcd_faza1_dreapta.clear();
digitalWrite(phase_2_red, LOW);
digitalWrite(dir3_green, HIGH); digitalWrite(dir4_green, HIGH);
digitalWrite(pietoni_2_green, HIGH); digitalWrite(pietoni_2_red, LOW);
unsigned long startTime2 = millis();
unsigned long intermitentStart2 = startTime2 + 1000;
unsigned long intermitentEnd2 = startTime2 + greenCarTime;
while (millis() - startTime2 < greenPedTime) {
if (millis() >= intermitentStart2 && millis() < intermitentEnd2) {
digitalWrite(intermitent_1_green, HIGH); delay(250);
digitalWrite(intermitent_1_green, LOW); delay(250);
}
//buzzer
digitalWrite(buzzerPin, HIGH);
delay(200);
digitalWrite(buzzerPin, LOW);
delay(200);
//temperatura
if (!galbenConstantDir1 && !galbenConstantDir2 && !galbenConstantDir3 && !galbenConstantDir4) {
lcd_faza1_stanga.setCursor(0, 0);
lcd_faza1_stanga.print(temperatura, 1);
lcd_faza1_stanga.print((char)223);
lcd_faza1_stanga.print("C");
lcd_faza1_dreapta.setCursor(0, 0);
lcd_faza1_dreapta.print(temperatura, 1);
lcd_faza1_dreapta.print((char)223);
lcd_faza1_dreapta.print("C");
lcd_faza2_sus.setCursor(0, 0);
lcd_faza2_sus.print(temperatura, 1);
lcd_faza2_sus.print((char)223);
lcd_faza2_sus.print("C");
lcd_faza2_jos.setCursor(0, 0);
lcd_faza2_jos.print(temperatura, 1);
lcd_faza2_jos.print((char)223);
lcd_faza2_jos.print("C");
}
// Citire senzorii de jos pentru semaforul directia 3 (SUS)
long d5 = readDistanceCM(trig3A, echo3A);
long d6 = readDistanceCM(trig3B, echo3B);
if (d5 < 5 && d6 < 5) {
if (!detectieDir3) {
detectieDir3 = true;
blockStartTimeDir3 = millis();
}
if (!galbenConstantDir3 && millis() - blockStartTimeDir3 >= 5000) {
galbenConstantDir3 = true;
asteaptaDeblocareDir3 = false;
digitalWrite(dir3_green, LOW);
digitalWrite(dir3_yellow, HIGH);
lcd_faza2_sus.clear();
lcd_faza2_sus.setCursor(0, 0);
lcd_faza2_sus.print("STOP INTERSECTIE");
lcd_faza2_sus.setCursor(0, 1);
lcd_faza2_sus.print("BLOCATA");
}
} else {
if (galbenConstantDir3 && !asteaptaDeblocareDir3) {
blockStartTimeDir3 = millis();
asteaptaDeblocareDir3 = true;
}
if (asteaptaDeblocareDir3 && millis() - blockStartTimeDir3 >= 5000) {
galbenConstantDir3 = false;
detectieDir3 = false;
asteaptaDeblocareDir3 = false;
digitalWrite(dir3_yellow, LOW);
digitalWrite(dir3_green, HIGH);
lcd_faza2_sus.clear();
}
}
// === Citire senzorii din SUS pentru semaforul directia 4 (JOS) ===
long d7 = readDistanceCM(trig4A, echo4A);
long d8 = readDistanceCM(trig4B, echo4B);
if (d7 < 5 && d8 < 5) {
if (!detectieDir4) {
detectieDir4 = true;
blockStartTimeDir4 = millis();
}
if (!galbenConstantDir4 && millis() - blockStartTimeDir4 >= 5000) {
galbenConstantDir4 = true;
asteaptaDeblocareDir4 = false;
digitalWrite(dir4_green, LOW);
digitalWrite(dir4_yellow, HIGH);
lcd_faza2_jos.clear();
lcd_faza2_jos.setCursor(0, 0);
lcd_faza2_jos.print("STOP INTERSECTIE");
lcd_faza2_jos.setCursor(0, 1);
lcd_faza2_jos.print("BLOCATA");
}
} else {
if (galbenConstantDir4 && !asteaptaDeblocareDir4) {
blockStartTimeDir4 = millis(); // start timer de revenire
asteaptaDeblocareDir4 = true;
}
if (asteaptaDeblocareDir4 && millis() - blockStartTimeDir4 >= 5000) {
galbenConstantDir4 = false;
detectieDir4 = false;
asteaptaDeblocareDir4 = false;
digitalWrite(dir4_yellow, LOW);
digitalWrite(dir4_green, HIGH);
lcd_faza2_jos.clear();
}
}
}
// === Pietoni 2 roșu ===
digitalWrite(pietoni_2_green, LOW);
digitalWrite(pietoni_2_red, HIGH);
delay(greenCarTime - greenPedTime);
// === GALBEN faza 2 ===
digitalWrite(dir3_green, LOW); digitalWrite(dir4_green, LOW);
digitalWrite(dir3_yellow, HIGH); digitalWrite(dir4_yellow, HIGH);
delay(yellowTime);
// === ROȘU-ROȘU final ===
digitalWrite(dir3_yellow, LOW); digitalWrite(dir4_yellow, LOW);
digitalWrite(phase_2_red, HIGH);
delay(2000);
}