#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/irq.h"
#include "hardware/timer.h"
#define ADC_VOLT_PIN 26
#define ADC_CURR_PIN 27
#define BUTTON_PIN 8
#define DIGIT1 10
#define DIGIT2 11
#define DIGIT3 12
#define SEGMENT_A 0
#define SEGMENT_B 1
#define SEGMENT_C 2
#define SEGMENT_D 3
#define SEGMENT_E 4
#define SEGMENT_F 5
#define SEGMENT_G 6
volatile uint8_t mode = 0;
volatile uint16_t voltage = 0;
volatile uint16_t current = 0;
const uint8_t digit_segments[] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};
struct repeating_timer timer;
void setup();
void button_callback(uint gpio, uint32_t events);
bool refresh_display(struct repeating_timer *t);
uint16_t read_adc(uint8_t channel);
void display_digit(uint8_t digit, uint8_t position);
void display_clear();
void display_update(uint16_t value);
void setup() {
stdio_init_all();
adc_init();
adc_gpio_init(ADC_VOLT_PIN);
adc_gpio_init(ADC_CURR_PIN);
gpio_init(BUTTON_PIN);
gpio_set_dir(BUTTON_PIN, GPIO_IN);
gpio_pull_up(BUTTON_PIN);
for (int i = SEGMENT_A; i <= SEGMENT_G; i++) {
gpio_init(i);
gpio_set_dir(i, GPIO_OUT);
}
for (int i = DIGIT1; i <= DIGIT3; i++) {
gpio_init(i);
gpio_set_dir(i, GPIO_OUT);
}
add_repeating_timer_ms(5, refresh_display, NULL, &timer);
gpio_set_irq_enabled_with_callback(BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true, &button_callback);
}
void button_callback(uint gpio, uint32_t events) {
mode = !mode;
}
bool refresh_display(struct repeating_timer *t) {
static uint8_t digit_index = 0;
uint16_t value = mode == 0 ? voltage : current;
uint16_t display_value = (value * 3300) / 4096; // Convert ADC value to millivolts
uint8_t digits[3] = {display_value / 1000,
(display_value / 100) % 10,
(display_value / 10) % 10};
display_clear();
display_digit(digits[digit_index], digit_index);
digit_index = (digit_index + 1) % 3;
return true;
}
uint16_t read_adc(uint8_t channel) {
adc_select_input(channel);
uint16_t raw = adc_read();
return (raw * 3300) / 4096; // Convert to millivolts
}
void display_digit(uint8_t digit, uint8_t position) {
uint8_t segments = digit_segments[digit];
for (int i = 0; i < 7; i++) {
gpio_put(SEGMENT_A + i, (segments >> i) & 1);
}
gpio_put(DIGIT1 + position, 1);
}
void display_clear() {
for (int i = SEGMENT_A; i <= SEGMENT_G; i++) {
gpio_put(i, 0);
}
for (int i = DIGIT1; i <= DIGIT3; i++) {
gpio_put(i, 0);
}
}
int main() {
setup();
while (1) {
voltage = read_adc(0);
current = read_adc(1);
sleep_ms(0.1);
}
return 0;
}