No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Dimmer LED via HTTP con ESP32

28/30
Recursos

Aportes 5

Preguntas 5

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

Buenos d铆as comunidad!!
Quer铆a contarles mi experiencia con este programa鈥

  1. Para que funcione con valores de RGB mayores de 99, tuve que cambiar en dimmer.c, param[3] por param[4].
  2. Con un osciloscopio puede observar que para alcanzar un duty-cicle de 100%, tengo que poner r, g o b en 256 y no en 255 como podr铆a creerse, lo cual es curioso porque tenemos
    #define LEDC_DUTY_RES LEDC_TIMER_8_BIT
    y 256 son 9 bits.

Esta clase estuvo demasiado buena, me va a dar migra帽a de ver el led x.x pero muy buena jajajajaja

En caso de que a alguien le sirva: Tengan en cuenta que existen dos tipos de LEDs RGB: de 谩nodo com煤n y de c谩todo com煤n. Seg煤n entiendo, en el curso se utiliza uno de c谩todo com煤n. En mi caso, poseo uno de 谩nodo com煤n. Esto quiere decir que el pin m谩s largo debe ir a positivo en vez de a negativo, el resto queda todo igual. Adem谩s de eso, luego me di cuenta que los colores no funcionaban como esperaba. Esto es porque funciona "al rev茅s", al llevarlo a 255 pasa a apagado, y en 0 est谩 a su m谩xima potencia. Tambi茅n, como dijo otra persona en los comentarios, en vez de 255 hay que usar 256 como m谩ximo valor, en mi caso para alcanzar realmente ese estado de 100% apagado. Dejo un snippet de mi m茅todo para actualizar los colores, donde abstraigo todo esto en un 煤nico lugar para no afectar al resto del c贸digo. ```java void update_leds() { // workaround for common anode RGB LED uint32_t inverted_duty_r = 256 - led_r; uint32_t inverted_duty_g = 256 - led_g; uint32_t inverted_duty_b = 256 - led_b; ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_R, inverted_duty_r); ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_R); ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_G, inverted_duty_g); ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_G); ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_B, inverted_duty_b); ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_B); } ```

El codigo en c:
.
.

#include <stdio.h>
#include "string.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/ledc.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "esp_http_server.h"
#include "paginaGet.h"


//******************** task refresh_led *****************************

#define          LED_PIN        25
bool             state_led    = false;
const TickType_t blink_delay  = 1000 / portTICK_PERIOD_MS;
TaskHandle_t     ledHandle;

void refresh_led(void *args)
{
    while (true)
    {
        state_led = !state_led;
        gpio_set_level(LED_PIN, state_led);
        vTaskDelay(blink_delay);
    }     
}

//***************** manejo del led RGB *************************************

#define LED_RED_PIN   4
#define LED_GREEN_PIN 0
#define LED_BLUE_PIN  12

#define LEDC_CHANNEL_RED   LEDC_CHANNEL_0
#define LEDC_CHANNEL_GREEN LEDC_CHANNEL_1
#define LEDC_CHANNEL_BLUE  LEDC_CHANNEL_2

void set_rgb_led(int32_t dutyRed, int32_t dutyGreen, int32_t dutyBlue)
{
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_RED, dutyRed));
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_RED));  
    
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_GREEN, dutyGreen));
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_GREEN));  

    ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_BLUE, dutyBlue));
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_BLUE));  
}

//**************************manejo de wifi *************************************
esp_netif_ip_info_t ip_info;
esp_netif_t* netif = NULL;


//**************************manejo de web server ******************************

static esp_err_t home_get_handler(httpd_req_t *req)
{
    httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
};

static const httpd_uri_t home = {
    .uri = "/",
    .method = HTTP_GET,
    .handler = home_get_handler
};

static esp_err_t setRGB_get_handler(httpd_req_t *req)
{
    int32_t dutyRed   = 0; 
    int32_t dutyGreen = 0; 
    int32_t dutyBlue  = 0;

    size_t buf_len;
    char* buf;
    buf_len = httpd_req_get_url_query_len(req) + 1;

    if (buf_len > 1)
    {
        buf = malloc(buf_len);
        if ( httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK )
        {
            printf("longitud : %d\n", buf_len);
            printf("contenido: %s\n", buf);

            char param[4];
            if (httpd_query_key_value(buf, "r", param, sizeof(param)) == ESP_OK)
            {
                printf("r param: %s\n", param);
                dutyRed = atoi(param);
            }
            if (httpd_query_key_value(buf, "g", param, sizeof(param)) == ESP_OK)
            {
                printf("g param: %s\n", param);
                dutyGreen = atoi(param);
            }
            if (httpd_query_key_value(buf, "b", param, sizeof(param)) == ESP_OK)
            {
                printf("b param: %s\n", param);
                dutyBlue = atoi(param);
            }
            free(buf);
            printf("r: %ld,  g: %ld,  b: %ld\n", dutyRed, dutyGreen, dutyBlue);
            set_rgb_led(dutyRed, dutyGreen, dutyBlue);

            httpd_resp_set_hdr(req, "Content-Type", "application/json");

            char resp1[30];
            sprintf(resp1,"{\"r\": %ld, \"g\": %ld, \"b\": %ld}", dutyRed, dutyGreen, dutyBlue);
            httpd_resp_send(req, resp1, HTTPD_RESP_USE_STRLEN);

        }    
    }    

    
    return ESP_OK;
};

static const httpd_uri_t setRGB = {
    .uri = "/RGB",
    .method = HTTP_GET,
    .handler = setRGB_get_handler
};


void web_server_init()
{
    httpd_handle_t server = NULL;
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    
    if (httpd_start(&server, &config) == ESP_OK)
    {
        httpd_register_uri_handler(server, &home);
        httpd_register_uri_handler(server, &setRGB);
        return;
    } 
    else 
    {
        printf("Error al iniciar el servidor\n");
    };

};


void app_main(void)

{
    
    // ********************Creacion de la tarea para refrescar el led *****************************************
    //reset pines de salida
    gpio_reset_pin(LED_PIN);

    // coloca los pines en estado de salida o entrada
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);

    //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
    );

    // **************** manejo de LED RGB con LedC ***********************
    //pwm timer config 
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_HIGH_SPEED_MODE,
        .duty_resolution  = LEDC_TIMER_8_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_red = {
        .speed_mode     = LEDC_HIGH_SPEED_MODE,
        .channel        = LEDC_CHANNEL_RED,
        .timer_sel      = LEDC_TIMER_0,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LED_RED_PIN,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_red));

    ledc_channel_config_t ledc_channel_green = {
        .speed_mode     = LEDC_HIGH_SPEED_MODE,
        .channel        = LEDC_CHANNEL_GREEN,
        .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_green));

    ledc_channel_config_t ledc_channel_blue = {
        .speed_mode     = LEDC_HIGH_SPEED_MODE,
        .channel        = LEDC_CHANNEL_BLUE,
        .timer_sel      = LEDC_TIMER_0,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LED_BLUE_PIN,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_blue));


    //************************ manejo del wifi y arranque web server******************************

    nvs_flash_init();

    esp_netif_init();

    esp_event_loop_create_default();
 
    example_connect();

    netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");

    if (netif == NULL)
    {
        printf("No hay interfaz\n");
    }
    else 
    {
        esp_netif_get_ip_info(netif, &ip_info);
        printf("************************************************************\n");
        printf("IP       : %d.%d.%d.%d\n", IP2STR(&ip_info.ip));
        printf("Net mask : %d.%d.%d.%d\n", IP2STR(&ip_info.netmask));
        printf("Gateway  : %d.%d.%d.%d\n", IP2STR(&ip_info.gw));

         web_server_init();
    };
     
}

.
.
El codigo en html. sin la parte del svg, para evitar su publicacion contiene enlace a sitios no seguros
.
.

char resp[] = R"=====(
<!DOCTYPE html>
<html lang="sp">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background-color: #98CA3F;
        }
        h1 {
            text-align: center;
        }
        .container {
            display: flex;
            justify-content: center;
            padding-bottom: 50px;
        }
        .vertContainer {
            display:flex;
            flex-direction: column;
            justify-content: center;
        }
        .slider_container {
            display:flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: space-around;
        }
        .redSlider {
            accent-color: red;
        }
        .greenSlider {
            accent-color: green;
        }
        .bluelider {
            accent-color: blue;
        }
        table {
            background-color: whitesmoke;
        }
                    
    </style>
</head>
<body onload="colorChange()">
    <h1>Sliders - curso de microcontroladores ESP32</h1>
    <div class="container">
        <svg></svg>
    </div>
    <div class="slider_container">
        <table>
            <tr>
                <th>Led</td>
                <th>Control</td>
                <th>Valor</td>
                <th>Color</td>
                <th>Resultado</td>
            </tr> 
            <tbody>   
            <tr>
                <td>Red </td> 
                <td><input type="range" min="0" max="255" value="127" class="redSlider"   id="redRange" oninput="colorChange()"></td>
                <td id="redValue">127</td>
                <td id="redColor"></td>
                <td id="resColor" rowspan="3"></td>
            </tr>
            <tr>
                <td>Green</td>
                <td><input type="range" min="0" max="255" value="127" class="greenSlider" id="greenRange" oninput="colorChange()"></td>
                <td id="greenValue">127</td>
                <td id="greenColor"></td>
            </tr>
                <tr>
                    <td>Blue</td>
                    <td><input type="range" min="0" max="255" value="127" class="blueSlider"  id="blueRange" oninput="colorChange()"></td>
                    <td id="blueValue">127</td>
                    <td id="blueColor"></td>
                </tr>
            </tbody>
        </table>
        <div class="vertContainer"><input type="button" value="Enviar al ESP32" class="boton" onclick="setRGB()"></div>
        <textarea name="respuesta" id="respuesta" cols="30" rows="10"></textarea>
    </div>
    <script>
        function colorChange() {
            let rC, gC, bC;
            rC = document.getElementById("redRange").value; 
            gC = document.getElementById("greenRange").value; 
            bC = document.getElementById("blueRange").value;
            document.getElementById("redValue").innerHTML   = rC;
            document.getElementById("greenValue").innerHTML = gC;
            document.getElementById("blueValue").innerHTML  = bC
            document.getElementById("redColor").style.backgroundColor = 'rgb(' + rC + ',' + 0 + ',' + 0 + ')';
            document.getElementById("greenColor").style.backgroundColor = 'rgb(' + 0 + ',' + gC + ',' + 0 + ')';
            document.getElementById("blueColor").style.backgroundColor = 'rgb(' + 0 + ',' + 0 + ',' + bC + ')';
            document.getElementById("resColor").style.backgroundColor = 'rgb(' + rC + ',' + gC + ',' + bC + ')';
        }
        function setRGB() {
            let rC, gC, bC;
         
            rC = document.getElementById("redRange").value; 
            gC = document.getElementById("greenRange").value; 
            bC = document.getElementById("blueRange").value;
            
            let url;
            url = "/RGB?r=" + rC + "&g=" + gC + "&b=" + bC;
               
            let xhr = new XMLHttpRequest();
            xhr.open("GET", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    document.getElementById("respuesta").innerHTML = xhr.responseText;
                }  
            };
            xhr.send();   
        }
    </script>
</body>
</html>    
)=====";    

El programa en el estudio, y el esp32 con bateria en la sala.