Compre el osciloscopio para armar junto con el esp32 ❤️
Introducción
Introducción a los microcontroladores
La importancia de la industria IoT
Tipos de computadoras
Cómo escoger un microcontrolador
Hardware
Características del ESP32
ESP-IDF
Documentación oficial del ESP-IDF
Instalación del ESP-IDF en Windows
Instalación del ESP-IDF en Mac
Instalación del ESP-IDF en Linux
Lista de materiales
Proyectos con ESP-IDF
Primer proyecto
API Core
Hola mundo con ESP-IDF
Sistemas Operativos en Tiempo Real
FreeRTOS con ESP32
Ciclo de vida de las tareas con FreeRTOS
Almacenamiento con ESP32
Peripherals API
Salida Digital con ESP32
Entrada Digital con ESP32
Entrada Analógica con ESP32
Modulación de Ancho de Pulsos
Control PWM con ESP32 y LEDC
Servidor Web
Redes y protocolos de Internet
Redes WiFi
Loop de eventos
Conexión WiFi con ESP32
Servidor HTTP básico con ESP32
Smart Light
Dimmer LED via HTTP con ESP32
Aplicación Web con ESP32
Despedida
Tu primer proyecto de IoT con ESP32
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Diana Martínez
Aportes 5
Preguntas 3
Compre el osciloscopio para armar junto con el esp32 ❤️
Para responder unas preguntas en los otros comentarios dejo una foto del mismo ejercicio pero manipulando la velocidad de giro de un motor.
El único cambio es que uso el pin 15 de salida porque es el que tengo en la tarjeta con PWM.
El osciloscopio es de bolsillo, es un DSO v3 de la empresa seed studio.
No tengo potenciometro pero lo simule con una funcion.
.
Segui el ejemplo del manual
.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "driver/ledc.h"
#define LED_PIN 25
#define LED_RED_PIN 4
#define LED_GREEN_PIN 0
#define LED_BLUE_PIN 12
#define SW_KY040_PIN 34
bool state_led = false;
bool state_red = false;
bool state_green = false;
bool state_blue = false;
const TickType_t blink_delay = 1000 / portTICK_PERIOD_MS;
const TickType_t debounce_delay = 50 / portTICK_PERIOD_MS;
const TickType_t digital_delay = 100 / portTICK_PERIOD_MS;
const TickType_t battVolt_delay = 2000 / portTICK_PERIOD_MS;
const TickType_t pwm_delay = 500 / portTICK_PERIOD_MS;
TaskHandle_t ledHandle;
TaskHandle_t swky040Handle;
TaskHandle_t battVoltHandle;
TaskHandle_t pwmHandle;
uint32_t raw_value;
uint32_t milivolts;
static esp_adc_cal_characteristics_t adc1_chars;
//en el cado del gpio35 el divisor de voltaje esta compuesto por dos resistencias de 100k
// Esto quiere decir que llega mitad del voltaje de la bateria.
// Para obtener el valor correcto hay que multiplicar el valor medido por dos
// como el valor del voltaje medido es milivoltios para obtener los voltios hay que
// dividir por 1000. De hay el factor de conversion de 0.002
double voltage_divider_factor = 0.002;
double battery_volt;
int32_t duty_cycle = 0;
int32_t dc_increment = 64;
void refresh_led(void *args)
{
while (true)
{
state_led = !state_led;
gpio_set_level(LED_PIN, state_led);
vTaskDelay(blink_delay);
}
}
void refresh_swky040(void *args)
{
while (true)
{
//El switch esta conectado en pull up
//su estado normal es alto
//cuando se oprime su estado es bajo
state_red = gpio_get_level(SW_KY040_PIN);
gpio_set_level(LED_RED_PIN, !state_red);
if (!state_red) vTaskDelay(debounce_delay);
vTaskDelay(digital_delay);
}
}
void refresh_battVolt(void *args)
{
while (true)
{
raw_value = adc1_get_raw(ADC1_CHANNEL_7);
milivolts = esp_adc_cal_raw_to_voltage(raw_value, &adc1_chars);
battery_volt = milivolts;
battery_volt = battery_volt * voltage_divider_factor;
printf("raw value: %ld milivolts: %ld battery: %f\n",raw_value, milivolts, battery_volt);
vTaskDelay(battVolt_delay);
}
}
void refresh_pwm_led(void *args)
{
while (true)
{
duty_cycle = duty_cycle + dc_increment;
if (duty_cycle > 4096)
{
duty_cycle = 4095;
dc_increment = - dc_increment;
}
if (duty_cycle < 0)
{
duty_cycle = 0;
dc_increment = - dc_increment;
}
ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, duty_cycle));
ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0));
vTaskDelay(pwm_delay);
}
}
void app_main(void)
{
//reset pines de salida
gpio_reset_pin(LED_PIN);
gpio_reset_pin(LED_RED_PIN);
//gpio_reset_pin(LED_GREEN_PIN);
gpio_reset_pin(LED_BLUE_PIN);
// coloca los pines en estado de salida o entrada
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
gpio_set_direction(LED_RED_PIN, GPIO_MODE_OUTPUT);
//gpio_set_direction(LED_GREEN_PIN, GPIO_MODE_OUTPUT);
gpio_set_direction(LED_BLUE_PIN, GPIO_MODE_OUTPUT);
gpio_set_direction(SW_KY040_PIN, GPIO_MODE_INPUT);
//coloca los leds rgb en apagado
gpio_set_level(LED_RED_PIN, state_red);
//gpio_set_level(LED_GREEN_PIN, state_green);
gpio_set_level(LED_BLUE_PIN, state_blue);
//En el chip Lora32, esp32 con radio LORA, OLED Display, cargador bateria LIPO:
//El gpio35 lee a traves de un divisor de 2 resistencias de 100k el voltaje de la
// bateria.
//El gpio35 corresponde al ADC1_CHANNEL7
//calibramos el adc1
esp_adc_cal_characterize(
ADC_UNIT_1, //apuntamos al adc 1
ADC_ATTEN_DB_11, //Rango lineal entre 150-2450 mv
ADC_WIDTH_BIT_12, //0 a 4095
0, //
&adc1_chars); //resultado de la calibracion
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
ESP_ERROR_CHECK(adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_11));
//pwm timer config
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_HIGH_SPEED_MODE,
.duty_resolution = LEDC_TIMER_12_BIT,
.timer_num = LEDC_TIMER_0,
.freq_hz = 4000, // Set output frequency at 4 kHz
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
// Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_HIGH_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.timer_sel = LEDC_TIMER_0,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = LED_GREEN_PIN,
.duty = 0, // Set duty to 0%
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
//creamos la tarea asociandola al segundo core
xTaskCreatePinnedToCore(
refresh_led, //Nombre de la funcion que implementa la tarea
"refresh_led", //Nombre descriptivo de la tarea con fines de debugging
2048, //El tamaño del task stack en bytes
NULL, //pointer a un parametro cuando la tarea esta siendo creada
5, //Prioridad de la tarea un numero
&ledHandle, //apuntador para referenciar la tarea.
1 // core 0 y core 1
);
xTaskCreatePinnedToCore(
refresh_swky040, //Nombre de la funcion que implementa la tarea
"refresh_swky040", //Nombre descriptivo de la tarea con fines de debugging
2048, //El tamaño del task stack en bytes
NULL, //pointer a un parametro cuando la tarea esta siendo creada
10, //Prioridad de la tarea un numero
&swky040Handle, //apuntador para referenciar la tarea.
1 // core 0 y core 1
);
xTaskCreatePinnedToCore(
refresh_battVolt, //Nombre de la funcion que implementa la tarea
"refresh_battVolt", //Nombre descriptivo de la tarea con fines de debugging
2048, //El tamaño del task stack en bytes
NULL, //pointer a un parametro cuando la tarea esta siendo creada
5, //Prioridad de la tarea un numero
&battVoltHandle, //apuntador para referenciar la tarea.
1 // core 0 y core 1
);
xTaskCreatePinnedToCore(
refresh_pwm_led, //Nombre de la funcion que implementa la tarea
"refresh_pwm_led", //Nombre descriptivo de la tarea con fines de debugging
2048, //El tamaño del task stack en bytes
NULL, //pointer a un parametro cuando la tarea esta siendo creada
5, //Prioridad de la tarea un numero
&pwmHandle, //apuntador para referenciar la tarea.
1 // core 0 y core 1
);
}
Definitivamente con un oscilador se puede apreciar mucho mejor lo interesante de esta práctica. Los osciladores profesionales son bastante caros pero uno como este (tipo mini para principiantes) se puede conseguir en Amazon en un rango de precios entre $50 y $150 bajo la descripción de pocket Digital Storage Oscillator (DSO).
<img src=“https://drive.google.com/file/d/1FaupW7f4dYdz9C9GvhFT9GiJClAmhlE9/view?usp=sharing” alt=“Osciloscopio”>
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?