I am trying to make a three way traffic controlling system i have already configured and made my block diagram i am using ultra sonic sensors to control the traffic lights so that if the sensor detects more traffic the time for the light to stay green increases i am also using a sensor for the pedestrians but my code isnt working correctly the sensors arent taking readings correctly and the lights arent function as i want i am attaching my code below please help me pinpoint the issue
Mod: please use Code quotes
Mod: please use Code quotes
C-like:
#include "stm32f4xx.h"
// Delay using SysTick
void delay_us(int us) {
SysTick->LOAD = 16 - 1; // 1 us tick at 16 MHz
SysTick->VAL = 0;
SysTick->CTRL = 5; // ENABLE + CLKSOURCE
for (int i = 0; i < us; i++) {
while (!(SysTick->CTRL & (1 << 16)));
}
SysTick->CTRL = 0;
}
void delay_ms(int ms) {
for (int i = 0; i < ms; i++) {
delay_us(1000);
}
}
void GPIO_Init(void) {
// Enable clocks for GPIOA, GPIOB, and GPIOE
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOEEN;
// GPIOA0–A8 as outputs (traffic lights)
GPIOA->MODER &= ~(0x3FFFF);
GPIOA->MODER |= (0x15555); // 01 = output
GPIOA->OTYPER &= ~(0x1FF); // Push-pull
GPIOA->OSPEEDR |= (0x3FFFF);
GPIOA->PUPDR &= ~(0x3FFFF);
// PA9 = TRIG A (output), PA10 = ECHO A (input, default)
GPIOA->MODER &= ~(3 << (9 * 2));
GPIOA->MODER |= (1 << (9 * 2)); // PA9 output
// PB10 (TRIG B), PB12 (TRIG C), PB5 (TRIG Pedestrian) -> output
GPIOB->MODER &= ~((3 << (10 * 2)) | (3 << (12 * 2)) | (3 << (5 * 2)));
GPIOB->MODER |= ((1 << (10 * 2)) | (1 << (12 * 2)) | (1 << (5 * 2)));
// PB11 (ECHO B), PB13 (ECHO C), PB4 (ECHO Pedestrian) -> input (default)
// PB8, PB9: Pedestrian LEDs -> output
GPIOB->MODER &= ~((3 << (8 * 2)) | (3 << (9 * 2)));
GPIOB->MODER |= ((1 << (8 * 2)) | (1 << (9 * 2)));
GPIOB->OTYPER &= ~((1 << 5) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 12));
GPIOB->OSPEEDR |= ((3 << (5 * 2)) | (3 << (8 * 2)) | (3 << (9 * 2)) |
(3 << (10 * 2)) | (3 << (12 * 2)));
GPIOB->PUPDR &= ~((3 << (4 * 2)) | (3 << (5 * 2)) |
(3 << (8 * 2)) | (3 << (9 * 2)) |
(3 << (10 * 2)) | (3 << (12 * 2)));
// Enable clock for GPIOE
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
// Set PE7 as output (Debug LED)
GPIOE->MODER &= ~(3 << (7 * 2)); // Clear mode
GPIOE->MODER |= (1 << (7 * 2)); // Set as output
GPIOE->OTYPER &= ~(1 << 7); // Push-pull
GPIOE->OSPEEDR |= (3 << (7 * 2)); // High speed
GPIOE->PUPDR &= ~(3 << (7 * 2)); // No pull-up, no pull-down
}
// Ultrasonic distance reading in cm
uint32_t read_distance_cm(GPIO_TypeDef* TRIG_PORT, int trig_pin, GPIO_TypeDef* ECHO_PORT, int echo_pin) {
TRIG_PORT->ODR &= ~(1 << trig_pin);
delay_us(2);
TRIG_PORT->ODR |= (1 << trig_pin);
delay_us(10);
TRIG_PORT->ODR &= ~(1 << trig_pin);
int timeout = 30000;
while (!(ECHO_PORT->IDR & (1 << echo_pin)) && timeout--);
int count = 0;
timeout = 30000;
while ((ECHO_PORT->IDR & (1 << echo_pin)) && timeout--) {
delay_us(1);
count++;
}
return count / 58;
}
uint32_t get_stable_distance(GPIO_TypeDef* TRIG_PORT, int trig_pin, GPIO_TypeDef* ECHO_PORT, int echo_pin) {
int readings = 5;
int valid = 0;
uint32_t total = 0;
for (int i = 0; i < readings; i++) {
uint32_t dist = read_distance_cm(TRIG_PORT, trig_pin, ECHO_PORT, echo_pin);
if (dist > 0) { // Accept all non-zero readings
total += dist;
valid++;
}
delay_ms(20);
}
if (valid >= 3) // Use if at least 3 readings were successful
return total / valid;
else
return 999; // Signal: no object reliably detected
}
void set_light(int base_pin, int red, int yellow, int green) {
GPIOA->ODR &= ~(0x7 << base_pin);
if (red) GPIOA->ODR |= (1 << base_pin);
if (yellow) GPIOA->ODR |= (1 << (base_pin + 1));
if (green) GPIOA->ODR |= (1 << (base_pin + 2));
}
void turn_red_all() {
set_light(0, 1, 0, 0); // A
set_light(3, 1, 0, 0); // B
set_light(6, 1, 0, 0); // C
}
int get_green_time(uint32_t dist) {
int green_time = 5000;
if (dist < 20) green_time = 10000;
if (dist < 10) green_time = 15000;
return green_time;
}
void run_traffic_cycle(int road) {
int base_pins[3] = {0, 3, 6};
int base = base_pins[road];
turn_red_all();
int green_time = 5000;
if (road == 0)
green_time = get_green_time(get_stable_distance(GPIOA, 9, GPIOA, 10));
else if (road == 1)
green_time = get_green_time(get_stable_distance(GPIOB, 10, GPIOB, 11));
else if (road == 2)
green_time = get_green_time(get_stable_distance(GPIOB, 12, GPIOB, 13));
set_light(base, 0, 0, 1); delay_ms(green_time);
set_light(base, 0, 1, 0); delay_ms(2000);
set_light(base, 1, 0, 0);
}
void check_pedestrian_and_run() {
uint32_t pdist = get_stable_distance(GPIOB, 5, GPIOB, 4); // Get distance from pedestrian sensor
// Debugging: Check the distance reading
if (pdist < 40) { // If a pedestrian is detected within 40 cm
// Turn off the red LED and turn on the green LED for pedestrian
GPIOB->ODR &= ~(1 << 8); // Red OFF
GPIOB->ODR |= (1 << 9); // Green ON
// Debugging: Turn on the debug LED (PE7) to indicate pedestrian detected
GPIOE->ODR |= (1 << 7); // Debug LED ON
delay_ms(5000); // Pedestrian green LED stays on for 5 seconds
// After the pedestrian has crossed, turn off the green LED
GPIOB->ODR &= ~(1 << 9); // Green OFF
GPIOB->ODR |= (1 << 8); // Red ON
// Debugging: Turn off the debug LED (PE7) after pedestrian is done
GPIOE->ODR &= ~(1 << 7); // Debug LED OFF
} else {
// No pedestrian detected, ensure the green LED is off
GPIOB->ODR &= ~(1 << 9); // Green OFF
GPIOB->ODR |= (1 << 8); // Red ON
}
}
int main(void) {
GPIO_Init();
GPIOB->ODR |= (1 << 8); // Pedestrian red initially ON
while (1) {
run_traffic_cycle(0);
check_pedestrian_and_run();
run_traffic_cycle(1);
check_pedestrian_and_run();
run_traffic_cycle(2);
check_pedestrian_and_run();
}
}
Last edited by a moderator: