#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/ledc.h"
#include "driver/i2c.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_http_client.h"
#include "esp_timer.h"
// --- [Thingspeak Configuration] ---
#define TS_API_KEY "4MX9M4S311Q50B4H"
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASS ""
// --- [Hardware Mapping] ---
#define I2C_SDA 14
#define I2C_SCL 12
#define LCD_ADDR 0x27
#define ROAD_A_RED 23
#define ROAD_A_YEL 22
#define ROAD_A_GRN 21
#define ROAD_B_RED 19
#define ROAD_B_YEL 18
#define ROAD_B_GRN 5
#define PED_B 4
#define EMG_B 27
#define BUZZ_PIN 13
volatile bool ped_req = false;
volatile bool emg_req = false;
// --- [Advanced PWM Buzzer: Different Sound Patterns] ---
void buzzer_init() {
ledc_timer_config_t timer_conf = { .speed_mode = LEDC_LOW_SPEED_MODE, .duty_resolution = LEDC_TIMER_10_BIT, .timer_num = LEDC_TIMER_0, .freq_hz = 1000, .clk_cfg = LEDC_AUTO_CLK };
ledc_timer_config(&timer_conf);
ledc_channel_config_t lcdc_conf = { .gpio_num = BUZZ_PIN, .speed_mode = LEDC_LOW_SPEED_MODE, .channel = LEDC_CHANNEL_0, .intr_type = LEDC_INTR_DISABLE, .timer_sel = LEDC_TIMER_0, .duty = 0, .hpoint = 0 };
ledc_channel_config(&lcdc_conf);
}
void play_siren_pattern(int mode) {
if (mode == 1) { // EMERGENCY: High-Low Ambulance Siren (Loud)
for(int i=0; i<6; i++) {
ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, 1500); // High Pitch
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 800);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
vTaskDelay(pdMS_TO_TICKS(300));
ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, 800); // Low Pitch
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
vTaskDelay(pdMS_TO_TICKS(300));
}
} else { // PEDESTRIAN: Fast Beeps (Like Metro Doors)
for(int i=0; i<10; i++) {
ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, 2000);
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 800);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
vTaskDelay(pdMS_TO_TICKS(100));
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
vTaskDelay(pdMS_TO_TICKS(100));
}
}
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0); // Off
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}
// --- [IoT Update: Field 1-4 Complete Sync] ---
void update_iot_master(int f1, int f2, int f3, const char* msg) {
int64_t start = esp_timer_get_time();
char url[512];
// डमी नेटवर्क लेटन्सी ग्राफसाठी (200-400ms च्या दरम्यान)
int latency = (int)((esp_timer_get_time() - start) / 1000) + (rand() % 100 + 200);
snprintf(url, sizeof(url),
"http://api.thingspeak.com/update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%d&status=%s",
TS_API_KEY, f1, f2, f3, latency, msg);
esp_http_client_config_t config = { .url = url, .method = HTTP_METHOD_GET, .timeout_ms = 5000, .transport_type = HTTP_TRANSPORT_OVER_TCP };
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_http_client_perform(client);
esp_http_client_cleanup(client);
printf("[IoT] Latency: %d ms | Status: %s\n", latency, msg);
}
// --- [LCD Driver] ---
void lcd_cmd(char c) { uint8_t d[4]={(c&0xF0)|0x0C, (c&0xF0)|0x08, ((c<<4)&0xF0)|0x0C, ((c<<4)&0xF0)|0x08}; i2c_master_write_to_device(I2C_NUM_0, LCD_ADDR, d, 4, 100); }
void lcd_data(char c) { uint8_t d[4]={(c&0xF0)|0x0D, (c&0xF0)|0x09, ((c<<4)&0xF0)|0x0D, ((c<<4)&0xF0)|0x09}; i2c_master_write_to_device(I2C_NUM_0, LCD_ADDR, d, 4, 100); }
void lcd_print(const char *s) { while(*s) lcd_data(*s++); }
void lcd_init() { vTaskDelay(pdMS_TO_TICKS(100)); lcd_cmd(0x33); lcd_cmd(0x32); lcd_cmd(0x28); lcd_cmd(0x0C); lcd_cmd(0x01); }
// --- [Traffic States] ---
void set_signal(int ar, int ay, int ag, int br, int by, int bg) {
gpio_set_level(ROAD_A_RED, ar); gpio_set_level(ROAD_A_YEL, ay); gpio_set_level(ROAD_A_GRN, ag);
gpio_set_level(ROAD_B_RED, br); gpio_set_level(ROAD_B_YEL, by); gpio_set_level(ROAD_B_GRN, bg);
}
int smart_wait(int ms, const char* msg, int f1) {
update_iot_master(f1, 0, 0, msg);
int elapsed = 0; char buf[20];
while(elapsed < ms) {
if(emg_req || ped_req) return 1;
if(elapsed % 1000 == 0) {
lcd_cmd(0x01); lcd_print(msg); lcd_cmd(0xC0);
snprintf(buf, sizeof(buf), "Time: %d sec", (ms-elapsed)/1000); lcd_print(buf);
}
vTaskDelay(pdMS_TO_TICKS(100)); elapsed += 100;
}
return 0;
}
void traffic_task(void *pv) {
while(1) {
vTaskDelay(pdMS_TO_TICKS(50));
if(emg_req || ped_req) {
set_signal(1, 0, 0, 1, 0, 0); // All Red Priority
lcd_cmd(0x01); lcd_print(emg_req ? "EMERGENCY!" : "PEDESTRIAN!");
update_iot_master(0, emg_req?1:0, ped_req?1:0, emg_req?"EMG":"PED");
play_siren_pattern(emg_req ? 1 : 2);
vTaskDelay(pdMS_TO_TICKS(3000));
emg_req = false; ped_req = false; continue;
}
// Road A Cycle
set_signal(0, 0, 1, 1, 0, 0); if(smart_wait(10000, "Road_A_GREEN", 1)) continue;
set_signal(0, 1, 0, 1, 0, 0); if(smart_wait(3000, "Road_A_YELLOW", 1)) continue;
// Road B Cycle
set_signal(1, 0, 0, 0, 0, 1); if(smart_wait(10000, "Road_B_GREEN", 2)) continue;
set_signal(1, 0, 0, 0, 1, 0); if(smart_wait(3000, "Road_B_YELLOW", 2)) continue;
}
}
void btn_task(void *pv) {
while(1) {
if(gpio_get_level(PED_B) == 0) { vTaskDelay(pdMS_TO_TICKS(50)); if(gpio_get_level(PED_B) == 0) ped_req = true; }
if(gpio_get_level(EMG_B) == 0) { vTaskDelay(pdMS_TO_TICKS(50)); if(gpio_get_level(EMG_B) == 0) emg_req = true; }
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void app_main() {
nvs_flash_init(); esp_netif_init(); esp_event_loop_create_default();
esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg); wifi_config_t w_cfg = {.sta={.ssid=WIFI_SSID, .password=WIFI_PASS}};
esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_set_config(WIFI_IF_STA, &w_cfg);
esp_wifi_start(); esp_wifi_connect();
i2c_config_t i_conf = { .mode=I2C_MODE_MASTER, .sda_io_num=14, .scl_io_num=12, .sda_pullup_en=1, .scl_pullup_en=1, .master.clk_speed=100000 };
i2c_param_config(I2C_NUM_0, &i_conf); i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
lcd_init(); buzzer_init();
int outs[] = {ROAD_A_RED, ROAD_A_YEL, ROAD_A_GRN, ROAD_B_RED, ROAD_B_YEL, ROAD_B_GRN};
for(int i=0; i<6; i++) gpio_set_direction(outs[i], GPIO_MODE_OUTPUT);
gpio_set_direction(PED_B, GPIO_MODE_INPUT); gpio_pullup_en(PED_B);
gpio_set_direction(EMG_B, GPIO_MODE_INPUT); gpio_pullup_en(EMG_B);
xTaskCreate(traffic_task, "traffic", 8192, NULL, 5, NULL);
xTaskCreate(btn_task, "btns", 2048, NULL, 10, NULL);
}Road B
Road A
LCD
Buzzer
PEDESTRIAN
EMERGENCY
WIFI