// IFMA - SISTEMAS EMBARCADOS
// HUGO FELIPE DOS SANTOS ROCHA
// UNIT04 - Cap. 05 a 08 - ATIVIDADE: TAREFA DE ENVIO - Clock e temporizador
/*TAREFA 2:
7. Como o ADC converte sinais analógicos do joystick em valores digitais no exemplo 02?
RESPOSTA:
Com a inicialização do ADC por meio da função: adc_init(),
configura o hardware do Conversor Analógico-Digital (ADC) do Raspberry Pi Pico,
preparando-o para realizar as conversões.
Após a configuração dos Pinos:adc_gpio_init(VRX_PIN); e adc_gpio_init(VRY_PIN);
Esses comandos associam os pinos físicos do Raspberry Pi Pico (GP26 e GP27) aos canais de entrada do ADC.
Ou seja, eles "dizem" ao ADC para ler os valores analógicos presentes nesses pinos.
Configurando o botão, o pino do botão é configurado como entrada digital,
permitindo detectar se o botão está pressionado ou não.
Fazendo a leitura dos valores:adc_select_input(0); e adc_select_input(1);
Antes de cada leitura, o código seleciona o canal específico do ADC (0 para o eixo X e 1 para o eixo Y) que será amostrado.
adc_read(); Essa função realiza a conversão analógico-digital.
O valor analógico (tensão) presente no pino selecionado é amostrado e convertido em um valor digital de 16 bits,
que pode variar de 0 a 4095.
o ADC é como uma régua dividida em 4096 partes iguais.
Quando você mede algo com uma régua, você encontra a medida mais próxima de uma das marcas da régua.
O ADC faz algo similar, ele compara a tensão analógica de entrada com um conjunto de referências internas e determina em qual "marca" da régua essa tensão se encaixa melhor.
Essa marca, representada por um número de 16 bits, é o valor digital que você obtém.
Interpretando os valores de 0 a 4095, Esses valores representam a amplitude do sinal analógico.
Por exemplo, se o joystick estiver totalmente para a esquerda, o valor lido no eixo X será próximo de 0.
Se estiver totalmente para a direita, o valor será próximo de 4095.
Para o estado do botão, O valor lido do botão será 0 se ele estiver pressionado e 1 se não estiver.
Assim, O ADC transforma um sinal analógico (que varia continuamente) em um sinal digital (que assume valores discretos).
Esse processo é fundamental para que um microcontrolador como o Raspberry Pi Pico possa entender e processar informações provenientes do mundo real,
como a posição de um joystick.
*/
#include <stdio.h> // Biblioteca padrão para entrada e saída, utilizada para printf.
#include "pico/stdlib.h" // Biblioteca padrão para funções básicas do Pico, como GPIO e temporização.
#include "hardware/adc.h" // Biblioteca para controle do ADC (Conversor Analógico-Digital).
// Definições dos pinos para o joystick e botão
#define VRX_PIN 26 // Define o pino GP26 para o eixo X do joystick (Canal ADC0).
#define VRY_PIN 27 // Define o pino GP27 para o eixo Y do joystick (Canal ADC1).
#define SW_PIN 22 // Define o pino GP22 para o botão do joystick (entrada digital).
int main() {
// Inicializa a comunicação serial para permitir o uso de printf.
// Isso permite enviar mensagens para o console via USB, facilitando a depuração.
stdio_init_all();
// Inicializa o módulo ADC do Raspberry Pi Pico.
// Isso prepara o ADC para ler valores dos pinos analógicos.
adc_init();
// Configura o pino GP26 para leitura analógica do ADC.
// O pino GP26 está mapeado para o canal 0 do ADC, que será usado para ler o eixo X do joystick.
adc_gpio_init(VRX_PIN);
// Configura o pino GP27 para leitura analógica do ADC.
// O pino GP27 está mapeado para o canal 1 do ADC, que será usado para ler o eixo Y do joystick.
adc_gpio_init(VRY_PIN);
// Configura o pino do botão como entrada digital com pull-up interno.
// O pull-up garante que o pino leia "alto" quando o botão não está pressionado, evitando leituras instáveis.
gpio_init(SW_PIN);
gpio_set_dir(SW_PIN, GPIO_IN);
gpio_pull_up(SW_PIN);
// Loop infinito para ler continuamente os valores do joystick e do botão.
while (true) {
// Seleciona o canal 0 do ADC (pino GP26) para leitura.
// Esse canal corresponde ao eixo X do joystick (VRX).
adc_select_input(0);
uint16_t vrx_value = adc_read(); // Lê o valor do eixo X, de 0 a 4095.
// Seleciona o canal 1 do ADC (pino GP27) para leitura.
// Esse canal corresponde ao eixo Y do joystick (VRY).
adc_select_input(1);
uint16_t vry_value = adc_read(); // Lê o valor do eixo Y, de 0 a 4095.
// Lê o estado do botão do joystick (SW).
// O valor lido será 0 se o botão estiver pressionado e 1 se não estiver.
bool sw_value = gpio_get(SW_PIN) == 0; // 0 indica que o botão está pressionado.
// Imprime os valores lidos na comunicação serial.
// VRX e VRY mostram a posição do joystick, enquanto SW mostra o estado do botão.
printf("VRX: %u, VRY: %u, SW: %d\n", vrx_value, vry_value, sw_value);
// Introduz um atraso de 500 milissegundos antes de repetir a leitura.
// Isso evita que as leituras e impressões sejam feitas muito rapidamente.
sleep_ms(500);
}
// Retorna 0 indicando que o programa terminou com sucesso.
// Esse ponto nunca será alcançado, pois o loop é infinito.
return 0;
}