#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"
#define PWM_IN 0 // Pino de entrada do PWM
#define BTN_0 1 // Pino do botão de reset
// Buffer do display e variáveis de controle
uint8_t display_buffer[128 * SSD1306_HEIGHT / 8] = {0};
uint8_t update_trip_meter = 0;
uint8_t update_total_odometer = 0;
uint16_t timer = 0;
uint8_t reset_odometer = 0;
// Strings para armazenar os valores do odômetro
static uint8_t value_trip_meter[10] = "0000.0 Km"; // 100 metros por incremento
static uint8_t value_total_odometer[10] = "000000 Km"; // Odometer total
static uint8_t edge_count_partial = 0;
static uint8_t edge_count_total = 0;
void up_odo_parcial(uint gpio);
void up_odo_total(uint gpio);
void system_init(void);
void trip_meter(void);
void total_odometer(void);
void reset_trip_meter(void);
void timer_reset(void);
int main(void)
{
stdio_init_all();
system_init();
SSD1306_init();
ssd1306_clear_buffer(display_buffer);
ssd1306_send_data(display_buffer, 128 * SSD1306_HEIGHT / 8);
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, "0000.0 Km");
ssd1306_write_text(display_buffer, 0, 50, "---------------");
ssd1306_write_text(display_buffer, 32, 62, "000000 Km");
ssd1306_send_data(display_buffer, 128 * SSD1306_HEIGHT / 8);
sleep_ms(2000);
while (true)
{
trip_meter();
total_odometer();
reset_trip_meter();
}
}
// Inicializa o sistema
void system_init(void)
{
gpio_init(PWM_IN);
gpio_set_dir(PWM_IN, GPIO_IN);
gpio_init(BTN_0);
gpio_set_dir(BTN_0, GPIO_IN);
gpio_pull_up(BTN_0);
gpio_set_irq_enabled_with_callback(PWM_IN, GPIO_IRQ_EDGE_FALL, true, (gpio_irq_callback_t)&up_odo_parcial);
gpio_set_irq_enabled_with_callback(PWM_IN, GPIO_IRQ_EDGE_FALL, true, (gpio_irq_callback_t)&up_odo_total);
}
// Função de interrupção para contar pulsos no odômetro parcial
void up_odo_parcial(uint gpio)
{
if (gpio == PWM_IN)
{
if (edge_count_partial == 500) // 500 pulsos representam 100 metros
{
update_trip_meter = 1;
edge_count_partial = 0;
}
else
{
edge_count_partial++;
}
}
}
// Função de interrupção para contar pulsos no odômetro total
void up_odo_total(uint gpio)
{
if (gpio == PWM_IN)
{
if (edge_count_total == 5000)
{
update_total_odometer = 1;
edge_count_total = 0;
}
else
{
edge_count_total++;
}
}
}
// Função que atualiza o odômetro parcial
void trip_meter(void)
{
if (update_trip_meter == 1)
{
// Limpa a área do odômetro parcial no display
ssd1306_write_text(display_buffer, 32, 47, " ");
ssd1306_write_text(display_buffer, 32, 47, value_trip_meter);
// Envia o novo valor ao display
ssd1306_send_data(display_buffer, 128 * SSD1306_HEIGHT / 8);
sleep_ms(2000);
// Atualiza o valor do trip meter (incremente a posição adequada da string)
value_trip_meter[5]++; // Incrementa os décimos de quilômetro (100 metros)
// Verifica se precisa atualizar outras posições
if (value_trip_meter[5] > 0x39)
{
value_trip_meter[5] = 0x30;
value_trip_meter[3]++;
if (value_trip_meter[3] > 0x39)
{
value_trip_meter[3] = 0x30;
value_trip_meter[2]++;
if (value_trip_meter[2] > 0x39)
{
value_trip_meter[2] = 0x30;
value_trip_meter[1]++;
if (value_trip_meter[1] > 0x39)
{
value_trip_meter[1] = 0x30;
value_trip_meter[0]++;
}
}
}
}
update_trip_meter = 0;
}
}
// Função que atualiza o odômetro total (sem alterações)
void total_odometer(void)
{
if (update_total_odometer == 1)
{
ssd1306_write_text(display_buffer, 32, 62, " ");
ssd1306_write_text(display_buffer, 32, 62, value_total_odometer);
ssd1306_send_data(display_buffer, 128 * SSD1306_HEIGHT / 8);
sleep_ms(2000);
value_total_odometer[5]++;
if (value_total_odometer[5] > 0x39)
{
value_total_odometer[5] = 0x30;
value_total_odometer[4]++;
if (value_total_odometer[4] > 0x39)
{
value_total_odometer[4] = 0x30;
value_total_odometer[3]++;
if (value_total_odometer[3] > 0x39)
{
value_total_odometer[3] = 0x30;
value_total_odometer[2]++;
if (value_total_odometer[2] > 0x39)
{
value_total_odometer[2] = 0x30;
value_total_odometer[1]++;
if (value_total_odometer[1] > 0x39)
{
value_total_odometer[1] = 0x30;
value_total_odometer[0]++;
}
}
}
}
}
update_total_odometer = 0;
}
}
// Função que reseta o odômetro parcial se o botão for pressionado por 7 segundos
void reset_trip_meter(void)
{
uint8_t button = gpio_get(BTN_0);
static uint8_t flag = 0;
if (button == 0) // Botão pressionado
{
if (timer == 0)
{
if (flag == 0)
{
timer = 7000; // Tempo de 7 segundos
flag = 1;
}
else if (timer == 7000)
{
reset_odometer = 1;
flag = 0;
}
}
}
else
{
flag = 0;
timer = 0; // Botão não pressionado, reseta o timer
}
// Se for para resetar o odômetro parcial
if (reset_odometer == 1)
{
value_trip_meter[5] = 0x30;
value_trip_meter[3] = 0x30;
value_trip_meter[2] = 0x30;
value_trip_meter[1] = 0x30;
value_trip_meter[0] = 0x30;
reset_odometer = 0;
}
}
void timer_reset(void)
{
// Função não utilizada
}