#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/gpio.h"
#include "hardware/timer.h"
// Definición de constantes
// GPIO - Punto decimal
#define GPIO_INICIAL 0
#define PUNTO_DECIMAL (1 << 11) // Pin para el punto decimal
// Displays
#define DISPLAY_1 (1 << 7)
#define DISPLAY_2 (1 << 8)
#define DISPLAY_3 (1 << 9)
#define DISPLAY_4 (1 << 10)
// Convertidor digital a analógico
#define ENTRADA_VOLTAJE 26
#define ENTRADA_CORRIENTE 27
// Botón de selección
#define BOTON 14
// Variables globales
bool enviar_valor_voltaje = true;
volatile int estado_digito = 0;
int valor = 0;
// Definición de valores decodificados para 7-segmentos
int segmentos[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67};
int leer_adc(uint channel) {
const int valor_numerico = 10;
uint32_t total = 0;
for (int i = 0; i < valor_numerico; i++) {
adc_select_input(channel);
total += adc_read();
sleep_ms(10);
}
uint16_t average = total / valor_numerico;
float valor;
if (channel == 0) { // Voltaje
valor = average * (3.3f / 4095.0f);
} else { // Corriente
valor = average * (12.0f / 4095.0f);
}
return (int)(valor * 100); // Convertir a un número entero (0.00 a 3.30 -> 0 a 330)
}
void interrupcion_boton(uint gpio, uint32_t events) {
if (gpio == BOTON) {
enviar_valor_voltaje = !enviar_valor_voltaje;
}
}
// Lógica para el conteo
bool interrupcion_timer (struct repeating_timer *t) {
int digito[4];
digito[0] = valor / 1000;
digito[1] = (valor % 1000) / 100;
digito[2] = (valor % 100) / 10;
digito[3] = valor % 10;
int display_segmentos[4] = {DISPLAY_1, DISPLAY_2, DISPLAY_3, DISPLAY_4};
// Apagar todos los displays y el punto decimal
gpio_clr_mask(DISPLAY_1 | DISPLAY_2 | DISPLAY_3 | DISPLAY_4 | PUNTO_DECIMAL | 0x7F);
// Mostrar el dígito actual
gpio_set_mask(display_segmentos[estado_digito] | segmentos[digito[estado_digito]]);
// Activar el punto decimal después del segundo dígito
if (estado_digito == 0 || estado_digito == 2 || estado_digito == 3) {
gpio_set_mask(PUNTO_DECIMAL);
}
// Pasar al siguiente dígito
estado_digito = (estado_digito + 1) % 4;
return true;
}
int main() {
stdio_init_all();
gpio_init_mask(0x0FFF);
gpio_set_dir_out_masked(0x0FFF);
for (int gpio = GPIO_INICIAL; gpio < GPIO_INICIAL + 7; gpio++) {
gpio_set_outover(gpio, GPIO_OVERRIDE_INVERT);
}
adc_init();
adc_gpio_init(ENTRADA_VOLTAJE);
adc_gpio_init(ENTRADA_CORRIENTE);
gpio_init(BOTON);
gpio_set_dir(BOTON, GPIO_IN);
gpio_pull_down(BOTON);
gpio_set_irq_enabled_with_callback(BOTON, GPIO_IRQ_EDGE_FALL, true, &interrupcion_boton);
struct repeating_timer timer;
add_repeating_timer_ms(2, interrupcion_timer, NULL, &timer);
//comprobacion
while (true) {
if (enviar_valor_voltaje) {
valor = leer_adc(0);
printf("Voltage: %.2f V\n", valor / 100.0f);
} else {
valor = leer_adc(1);
printf("Corriente: %.2f A\n", valor / 100.0f);
}
sleep_ms(500);
}
}