//Valmir F Silva - Matrícula 202421511720090
/*/
A ideia básica foi modela o semáfaro como algo próximo à máquina de
estados finitos para facilitar a estrutura e implemtação. Foi usando uma modulação
em pwm para acionar o buzzer, bem como uma medição de tempo adequada.
/*/
#include <stdio.h>
#include<math.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "pico/cyw43_arch.h"
#define LED_RED_CAR 20
#define LED_YELLOW_CAR 19
#define LED_GREEN_CAR 18
#define LED_GREEN_PED 17
#define PUSHBUTTON 16
#define BUZZER 0
//0x0000_0000_0000_0000
int next_time = 8;
int current = 0;
long long int t0 = 0;
bool flag_time=true;
bool button;
enum estados {
GREEN_CAR ,
YELLOW_CAR ,
YELLOW_PED ,
RED_CAR
};
void setStatePin(bool,bool,bool,bool);
void semafaro(bool);
void buzzer(bool);
int main() {
stdio_init_all();
gpio_init_mask(1 << LED_RED_CAR | 1 << LED_YELLOW_CAR | 1 << LED_GREEN_CAR | 1 << LED_GREEN_PED | 1 << PUSHBUTTON);
gpio_set_dir_masked(1 << LED_RED_CAR | 1 << LED_YELLOW_CAR | 1 << LED_GREEN_CAR | 1 << LED_GREEN_PED,1 << LED_RED_CAR | 1 << LED_YELLOW_CAR | 1 << LED_GREEN_CAR | 1 << LED_GREEN_PED);
gpio_set_dir(PUSHBUTTON,GPIO_IN);
gpio_set_function(BUZZER, GPIO_FUNC_PWM);
int slice = pwm_gpio_to_slice_num(BUZZER);
int channel = pwm_gpio_to_channel(BUZZER);
int pwm_inc =0;
pwm_set_enabled(slice,true);
while (true) {
button = next_time == 15 ? 0 : gpio_get(PUSHBUTTON);
semafaro(button);//Dinâmica do semáfaro
sleep_ms(100);//Alívio de processamento necessário para a simulação
pwm_set_gpio_level(BUZZER,pwm_inc);
pwm_inc = next_time == 15? pwm_inc+1:0;
}
}
void semafaro(bool button){
//gpioTick
//Principais estados do semáfaro
switch(current){
case GREEN_CAR: //8seg
setStatePin(1,0,0,0);
if(flag_time){
t0 = (float)time_us_64()/pow(10,6);//captura do instânte de tempo
flag_time = false;
}
else if(abs(t0 -(float)time_us_64()/pow(10,6)) >= next_time){//pseudo crônommetro
current = YELLOW_CAR;
next_time = 2;
flag_time = true;
}
else {
current = button ? YELLOW_PED : current;
next_time = button ? 5 : next_time;
flag_time =button ? true: flag_time;
}
break;
case YELLOW_CAR: //2seg
setStatePin(0,1,0,0);
if(flag_time){
t0 = (float)time_us_64()/pow(10,6);
flag_time = false;
}
else if(abs(t0 -(float)time_us_64()/pow(10,6)) >= next_time){
current = RED_CAR ;
next_time = 10 ;
flag_time = true;
}
else {
current = button ? YELLOW_PED : current;
next_time = button ? 5 : next_time;
flag_time =button ? true: flag_time;
}
break;
case RED_CAR: //10seg
setStatePin(0,0,1,next_time==15);
if(flag_time){
t0 = (float)time_us_64()/pow(10,6);
flag_time = false;
}
else if(abs(t0 -(float)time_us_64()/pow(10,6)) >= next_time){
current = GREEN_CAR;
next_time = 8;
flag_time = true;
}
else {
current = button ? YELLOW_PED : current;
next_time = button ? 5 : next_time;
flag_time =button ? true: flag_time;
}
break;
case YELLOW_PED: //10seg
setStatePin(0,1,0,0);
if(flag_time){
t0 = (float)time_us_64()/pow(10,6);
flag_time = false;
}
else if(abs(t0 -(float)time_us_64()/pow(10,6)) >= next_time){
current = RED_CAR;
next_time = 15;
flag_time = true;
}
else{
current = current;
next_time = next_time;
flag_time = flag_time;
}
break;
}
}
void setStatePin(bool green,bool yellow,bool red, bool green_pe){
gpio_put(LED_GREEN_CAR , green);
gpio_put(LED_YELLOW_CAR , yellow);
gpio_put(LED_RED_CAR , red);
gpio_put(LED_GREEN_PED , green_pe);
}