#include <stdio.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/dac_oneshot.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include <math.h>
#include <inttypes.h>
static const char *TAG = "dac_oneshot_example";
#define CONFIG_LOG_DEFAULT_LEVEL_VERBOSE 1 //necessário para rodar o log no wokwi
#define CONFIG_LOG_MAXIMUM_LEVEL 5 //necessário para rodar o log no wokwi
// Definição dos pinos para os botões
#define BUTTON_1 GPIO_NUM_32 // Alternar entre ondas
#define BUTTON_2 GPIO_NUM_33 // Aumentar/Diminuir a amplitude
#define BUTTON_3 GPIO_NUM_13 // Aumentar/Diminuir a frequência
// Parâmetros da onda
#define MAX_AMPLITUDE 255
#define MIN_AMPLITUDE 0
#define MAX_FREQUENCY 1000
#define MIN_FREQUENCY 1
// Estado da onda
int wave_type = 0; // 0: Triangular, 1: Dente de serra, 2: Quadrada, 3: Senoidal
int amplitude = 105; // Amplitude inicial
int frequency = 200; // Frequência inicial
void app_main(void) {
uint32_t val = 0;
// Configuração do DAC
dac_oneshot_handle_t chan0_handle;
dac_oneshot_config_t chan0_cfg = {
.chan_id = DAC_CHAN_0,
};
ESP_ERROR_CHECK(dac_oneshot_new_channel(&chan0_cfg, &chan0_handle));
// Configuração dos botões
gpio_reset_pin(BUTTON_1);
gpio_set_direction(BUTTON_1, GPIO_MODE_INPUT);
gpio_set_pull_mode(BUTTON_1, GPIO_PULLUP_ONLY);
gpio_reset_pin(BUTTON_2);
gpio_set_direction(BUTTON_2, GPIO_MODE_INPUT);
gpio_set_pull_mode(BUTTON_2, GPIO_PULLUP_ONLY);
gpio_reset_pin(BUTTON_3);
gpio_set_direction(BUTTON_3, GPIO_MODE_INPUT);
gpio_set_pull_mode(BUTTON_3, GPIO_PULLUP_ONLY);
esp_log_level_set(TAG, ESP_LOG_VERBOSE); //necessário para rodar o log no wokwi
ESP_LOGI(TAG, "DAC oneshot example start.");
while (1) {
// Lógica para alternar entre ondas
if (gpio_get_level(BUTTON_1) == 0) {
wave_type = (wave_type + 1) % 4; // Alterna entre 0 e 3
esp_log_level_set(TAG, ESP_LOG_VERBOSE); //necessário para rodar o log no wokwi
ESP_LOGI(TAG, "Tipo de onda alterado: %d", wave_type);
vTaskDelay(pdMS_TO_TICKS(300)); // Debounce
}
// Lógica para alterar a amplitude
if (gpio_get_level(BUTTON_2) == 0) {
if (amplitude < MAX_AMPLITUDE) {
amplitude += 5; // Aumenta a amplitude
}
esp_log_level_set(TAG, ESP_LOG_VERBOSE); //necessário para rodar o log no wokwi
ESP_LOGI(TAG, "Amplitude: %d", amplitude);
vTaskDelay(pdMS_TO_TICKS(300)); // Debounce
}
// Lógica para alterar a frequência
if (gpio_get_level(BUTTON_3) == 0) {
if (frequency < MAX_FREQUENCY) {
frequency += 10; // Aumenta a frequência
}
esp_log_level_set(TAG, ESP_LOG_VERBOSE); //necessário para rodar o log no wokwi
ESP_LOGI(TAG, "Frequência: %d", frequency);
vTaskDelay(pdMS_TO_TICKS(300)); // Debounce
}
// Geração da onda
if (wave_type == 0) { // Onda triangular
for (val = 0; val < amplitude; val++) { //subida
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, val));
vTaskDelay(pdMS_TO_TICKS(1000 / frequency / 255));
}
for (val = amplitude; val > 0; val--) {//descida
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, val));
vTaskDelay(pdMS_TO_TICKS(1000 / frequency / 255));
}
} else if (wave_type == 1) { // Onda dente de serra
for (val = 0; val < amplitude; val++) {
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, val));
vTaskDelay(pdMS_TO_TICKS(1000 / frequency / 255));
}
} else if (wave_type == 2) { // Onda quadrada
for (val = 0; val < amplitude; val++) {
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, (val % 2) ? amplitude : 0));
vTaskDelay(pdMS_TO_TICKS(1000 / frequency));
}
} else if (wave_type == 3) { // Onda senoidal
for (val = 0; val < 360; val++) {
int sine_value = (int)((amplitude / 2) * (1 + sin(val * M_PI / 180)));
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, sine_value));
vTaskDelay(pdMS_TO_TICKS(1000 / frequency / 360));
}
}
}
}