/*====================================================================
Leonardo Lundquist da Costa RA: 1600732413018
Cesar Augusto Fernandes da Silva 1600732413018
====================================================================*/
#include "ssd1306.h"
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "hardware/gpio.h"
//====================================================================
// Definicoes do Projeto
//====================================================================
#define LED 28
#define BUTTON_PIN 22
#define BOTAO_RST 15
#define IGNITION_PIN 14 // Nova chave de ignição
#define ALARM_NUM 0
#define ALARM_IRQ TIMER_IRQ_0
#define DELAY 10000 // 10ms por interrupção
uint8_t display_buffer[128 * SSD1306_HEIGHT / 8] = {0};
uint16_t tmr = 0;
uint8_t atualiza_odo_parcial = 0;
uint8_t atualiza_odo_total = 0;
uint8_t reset_odometro = 0;
volatile bool ignition_on = false; // Estado da chave de ignição
void system_init(void);
void alarm_irq(void);
void init_timer_irq(void);
void odometro_parcial(void);
void odometro_total(void);
void reset_odometro_parcial(void);
void button_callback(uint gpio);
void ignition_callback(uint gpio); // Novo callback da chave de ignição
int main()
{
stdio_init_all();
system_init();
SSD1306_init();
ssd1306_clear_buffer(display_buffer);
ssd1306_send_data(display_buffer, sizeof(display_buffer));
sleep_ms(2000);
ssd1306_write_text(display_buffer, 32, 0, "FATEC ");
ssd1306_write_text(display_buffer, 10, 8, "SANTO ANDRE");
ssd1306_write_text(display_buffer, 0, 24, "Sist. Conforto");
ssd1306_write_text(display_buffer, 32, 47, " 000.0 Km");
ssd1306_write_text(display_buffer, 0, 50, "---------------");
ssd1306_write_text(display_buffer, 32, 62, "000000 Km");
ssd1306_send_data(display_buffer, sizeof(display_buffer));
sleep_ms(2000);
while(1)
{
if (ignition_on) { // Só atualiza odômetros se chave estiver ligada
reset_odometro_parcial();
odometro_parcial();
odometro_total();
}
sleep_ms(10);
}
}
void system_init(void)
{
gpio_init(BUTTON_PIN);
gpio_set_dir(BUTTON_PIN, GPIO_IN);
gpio_pull_up(BUTTON_PIN);
gpio_init(BOTAO_RST);
gpio_set_dir(BOTAO_RST, GPIO_IN);
gpio_pull_up(BOTAO_RST);
gpio_set_irq_enabled_with_callback(BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true, (gpio_irq_callback_t)&button_callback);
gpio_init(LED);
gpio_set_dir(LED, GPIO_OUT);
gpio_put(LED,1);
// Configuração da chave de ignição
gpio_init(IGNITION_PIN);
gpio_set_dir(IGNITION_PIN, GPIO_IN);
gpio_pull_up(IGNITION_PIN);
gpio_set_irq_enabled_with_callback(IGNITION_PIN, GPIO_IRQ_EDGE_FALL, true, (gpio_irq_callback_t)&ignition_callback);
init_timer_irq();
}
void alarm_irq(void)
{
static uint16_t cont_parcial = 0;
static uint8_t cont_led = 0;
static bool toggle = false;
hw_clear_bits(&timer_hw->intr, 1u << ALARM_NUM);
timer_hw->alarm[ALARM_NUM] = timer_hw->timerawl + DELAY;
if (tmr) tmr--;
if (!ignition_on) return; // Se chave desligada, não faz nada
cont_parcial++;
if (cont_parcial >= 100) // 1 segundo
{
cont_parcial = 0;
atualiza_odo_parcial = 1;
}
cont_led++;
if (cont_led >= 20) // pisca LED a cada 200ms
{
cont_led = 0;
gpio_put(LED, toggle);
toggle = !toggle;
}
}
void init_timer_irq(void)
{
hw_set_bits(&timer_hw->inte, 1u << ALARM_NUM);
irq_set_exclusive_handler(ALARM_IRQ, alarm_irq);
irq_set_enabled(ALARM_IRQ, true);
timer_hw->alarm[ALARM_NUM] = timer_hw->timerawl + DELAY;
}
void odometro_parcial(void)
{
static uint8_t odometro_parcial[10] = " 000.0 Km";
static uint8_t contagem_odometro = 0;
if(reset_odometro)
{
static uint8_t resetado[10] = " 000.0 Km";
memcpy(odometro_parcial, resetado, sizeof(odometro_parcial));
ssd1306_write_text(display_buffer, 32, 47, " ");
ssd1306_write_text(display_buffer, 32, 47, odometro_parcial);
ssd1306_send_data(display_buffer, sizeof(display_buffer));
reset_odometro = 0;
atualiza_odo_parcial = 0;
return;
}
if(atualiza_odo_parcial)
{
odometro_parcial[5]++;
if(odometro_parcial[5] > '9')
{
odometro_parcial[5] = '0';
odometro_parcial[3]++;
}
if(odometro_parcial[3] > '9')
{
odometro_parcial[3] = '0';
odometro_parcial[2]++;
}
if(odometro_parcial[2] > '9')
{
odometro_parcial[2] = '0';
odometro_parcial[1]++;
}
contagem_odometro++;
if (contagem_odometro >= 10) {
contagem_odometro = 0;
atualiza_odo_total = 1;
}
ssd1306_write_text(display_buffer, 32, 47, " ");
ssd1306_write_text(display_buffer, 32, 47, odometro_parcial);
ssd1306_send_data(display_buffer, sizeof(display_buffer));
atualiza_odo_parcial = 0;
}
}
void odometro_total(void)
{
static uint8_t odometro_total[11] = "000000 Km";
if(atualiza_odo_total)
{
odometro_total[5]++;
if(odometro_total[5] > '9') {
odometro_total[5] = '0';
odometro_total[4]++;
}
if(odometro_total[4] > '9') {
odometro_total[4] = '0';
odometro_total[3]++;
}
if(odometro_total[3] > '9') {
odometro_total[3] = '0';
odometro_total[2]++;
}
if(odometro_total[2] > '9') {
odometro_total[2] = '0';
odometro_total[1]++;
}
ssd1306_write_text(display_buffer, 32, 62, " ");
ssd1306_write_text(display_buffer, 32, 62, odometro_total);
ssd1306_send_data(display_buffer, sizeof(display_buffer));
atualiza_odo_total = 0;
}
}
void reset_odometro_parcial(void)
{
uint8_t btn = gpio_get(BOTAO_RST);
static uint8_t flag = 0;
static uint8_t conta7_reset = 0;
if(btn == 0)
{
if(tmr == 0)
{
if(flag == 0)
{
tmr = 700; // 700 x 10ms = 7s
flag = 1;
conta7_reset = 0;
}
else
{
printf("Reset odometro parcial concluido\n");
reset_odometro = 1;
flag = 0;
conta7_reset = 0;
}
}
else if(flag == 1)
{
uint8_t segundos = 7 - tmr / 100;
if (segundos > conta7_reset)
{
printf("Botão pressionado por %d segundo(s)...\n", segundos);
conta7_reset = segundos;
}
}
}
else
{
tmr = 0;
flag = 0;
conta7_reset = 0;
}
}
void button_callback(uint gpio)
{
printf("Botão principal pressionado (GPIO %d)\n", gpio);
}
void ignition_callback(uint gpio)
{
if (gpio == IGNITION_PIN) {
ignition_on = !ignition_on;
printf("Chave de ignição %s\n", ignition_on ? "LIGADA" : "DESLIGADA");
}
}