Categoría: Programación

  • Proyecto de Reproducción de MP3 con ESP32 y DFPlayer Mini

    Proyecto de Reproducción de MP3 con ESP32 y DFPlayer Mini

    Actualizado: 3/7/2025: Ahora es compatible con familia de uC Espressif ESP8266 y ESP32. Este proyecto detalla cómo utilizar un ESP32 y un módulo DFPlayer Mini para reproducir archivos MP3 de manera automática cada cierto tiempo. Se abordan los aspectos del módulo DFPlayer Mini, las conexiones necesarias y el código de programación, proporcionando una guía completa para la implementación de este sistema de reproducción de audio.

    El DFPlayer Mini es un módulo de reproducción de audio compacto y de bajo costo que puede reproducir archivos MP3 y WAV almacenados en una tarjeta microSD. Es ampliamente utilizado en proyectos de electrónica debido a su facilidad de uso y a su capacidad para manejar archivos de audio de manera autónoma, sin necesidad de una fuente de control compleja. El módulo cuenta con varias funciones, incluyendo el ajuste de volumen, control de reproducción, y la capacidad de seleccionar pistas mediante comandos simples.

    Conexiones del Proyecto

    Para conectar el DFPlayer Mini con el ESP32, es importante seguir las siguientes indicaciones:

    • VCC: Conectar a una fuente de alimentación de 5V. El ESP32 puede proporcionar esta salida.
    • GND: Conectar al pin de tierra (GND) del ESP32.
    • TX del DFPlayer Mini: Conectar al pin GPIO 16 del ESP32.
    • RX del DFPlayer Mini: Conectar al pin GPIO 17 del ESP32.
    • SPK1 y SPK2: Conectar a un altavoz pasivo, si se desea una salida de audio. Alternativamente, se puede usar un conector de auriculares para salida de línea.

    Es fundamental asegurarse de que las conexiones sean correctas para evitar daños en los componentes y garantizar un funcionamiento óptimo del sistema.

    3. Código de Programación

    El siguiente código muestra cómo configurar el ESP32 para comunicarse con el DFPlayer Mini y reproducir un archivo MP3 cada 10 segundos. Se utiliza el puerto Serial1 del ESP32/ESP8266 para la comunicación, aprovechando la capacidad del microcontrolador para manejar múltiples puertos UART de hardware.

    #include <Arduino.h>
    #include <DFPlayerMini_Fast.h>
    
    #if defined(ESP32)
      // En ESP32 podemos usar HardwareSerial en un segundo puerto
      HardwareSerial playerSerial(2);  // UART2: GPIO16=RX2, GPIO17=TX2 por defecto
      const int DF_RX = 16;  // al TX del DFPlayer
      const int DF_TX = 17;  // al RX del DFPlayer
    #elif defined(ESP8266)
      #include <SoftwareSerial.h>
      const int DF_RX = D5;  // ESP8266: conecta a TX del DFPlayer
      const int DF_TX = D6;  // ESP8266: conecta a RX del DFPlayer
      SoftwareSerial playerSerial(DF_RX, DF_TX);
    #else
      #error "Este código sólo es para ESP32 o ESP8266"
    #endif
    
    DFPlayerMini_Fast myDFPlayer;
    const unsigned long intervalReproduccion = 10000;  // 10 s
    unsigned long lastMillis = 0;
    
    void setup() {
      Serial.begin(115200);
      Serial.println();
      Serial.println("=== DFPlayer en ESP32/ESP8266 ===");
    
      // Inicializar puerto al módulo
      #if defined(ESP32)
        playerSerial.begin(9600, SERIAL_8N1, DF_RX, DF_TX);
      #elif defined(ESP8266)
        playerSerial.begin(9600);
      #endif
    
      if (! myDFPlayer.begin(playerSerial)) {
        Serial.println(F("ERROR: No se detectó DFPlayer Mini"));
        while (true) delay(100);
      }
    
      myDFPlayer.volume(20);   // 0–30
      myDFPlayer.play(1);      // empieza en pista 001
      lastMillis = millis();
    }
    
    void loop() {
      unsigned long now = millis();
    
      // Cada 10 s, reproducir siguiente pista
      if (now - lastMillis >= intervalReproduccion) {
        lastMillis = now;
        myDFPlayer.playNext();
      }
    
      // Procesar eventos del DFPlayer (fin de pista, errores…)
      if (myDFPlayer.available()) {
        DFPlayerEventType type = myDFPlayer.readType();
        int state = myDFPlayer.readState();
        Serial.print(F("Evento DFPlayer: "));
        Serial.print(type);
        Serial.print(F("  Estado interno: "));
        Serial.println(state);
      }
    
      // Aquí puedes gestionar botones u otras tareas no bloqueantes
    
      delay(20);
    }
    
    

    En este código, se utilizan las siguientes funciones y configuraciones:

    • mySerial.begin(9600, SERIAL_8N1, 16, 17); Esta línea configura el puerto Serial1 del ESP32 con una velocidad de comunicación de 9600 baudios y establece los pines GPIO 16 y 17 como RX y TX, respectivamente.
    • myDFPlayer.begin(mySerial); Esta función inicializa el DFPlayer Mini y lo prepara para recibir comandos.
    • myDFPlayer.volume(20); Se ajusta el volumen del reproductor a un nivel de 20 (en una escala de 0 a 30).
    • myDFPlayer.play(1); Este comando indica al DFPlayer Mini que reproduzca el archivo de audio numerado como 1 en la tarjeta microSD.
    • delay(10000); Introduce una pausa de 10 segundos antes de repetir el ciclo.

    Este código permite la reproducción continua de un archivo MP3, con una espera de 10 segundos entre reproducciones. Es posible modificar el tiempo de espera o cambiar el archivo a reproducir ajustando los parámetros del código según las necesidades del proyecto.

  • Conociendo los CHAR ARRAY

    Los “char arrays” son una forma fundamental de trabajar con texto en muchos lenguajes de programación

    Un “char array” es una estructura de datos en programación que se utiliza para guardar una secuencia de caracteres. La palabra “char” se refiere a caracteres individuales, como letras o símbolos, y “array” significa que estos caracteres se almacenan uno después del otro en la memoria.

    Por ejemplo, si se tiene la palabra “Hola”, un “char array” la representaría como una serie de caracteres: ‘H’, ‘o’, ‘l’, ‘a’. Cada uno de estos caracteres se guarda en una posición específica del array y se puede acceder a ellos por su posición. El primer carácter estará en la posición 0, el segundo en la posición 1, y así sucesivamente.

    Ahora un ejemplo para compilar con cualquier placa con Arduino IDE

    void setup() {
      Serial.begin(9600);  // Inicializar la comunicación serial
      
      char mensaje[] = "Hola, este es un ejemplo de conteo de vocales";
      
      int cantidadVocales = contarVocales(mensaje);
      
      Serial.print("El mensaje es: ");
      Serial.println(mensaje);
      
      Serial.print("La cantidad de vocales es: ");
      Serial.println(cantidadVocales);
    }
    
    void loop() {
      // Tu código aquí
    }
    
    int contarVocales(char *cadena) {
      int contador = 0;
      
      for (int i = 0; cadena[i] != '\0'; i++) {
        char caracter = toLowerCase(cadena[i]); // Convertir el caracter a minúscula para hacer la comparación
        if (caracter == 'a' || caracter == 'e' || caracter == 'i' || caracter == 'o' || caracter == 'u') {
          contador++;
        }
      }
      
      return contador;
    }
    

    En este ejemplo, se ha creado una función llamada contarVocales que toma un puntero a una cadena de caracteres (char *cadena) como argumento.

    Dentro de esta función, se recorre cada caracter en la cadena utilizando un bucle for. Convertimos cada carácter a minúscula usando la función toLowerCase() para asegurarnos de que se cuenten las vocales tanto en mayúscula como en minúscula.

    Si el carácter es una vocal (‘a’, ‘e’, ‘i’, ‘o’, ‘u’), incrementamos el contador. Al final, la función devuelve la cantidad total de vocales encontradas en la cadena.

    Este ejemplo muestra cómo puedes utilizar funciones y bucles para realizar manipulaciones más avanzadas con cadenas y caracteres en Arduino IDE. Puedes construir sobre este concepto para crear funciones más complejas que realicen diferentes tareas con texto.

    ¿Por qué un puntero?

    En C y C++, una cadena de caracteres es en realidad un array de caracteres, y se representa mediante un puntero al primer elemento del array. Cuando pasamos una cadena como argumento a una función, en realidad estamos pasando un puntero al primer carácter de la cadena. Esto se debe a cómo funcionan los arrays en C/C++.

    Ergo, cuando se declaró int contarVocales(char *cadena), se estaba indicando que la función toma un puntero a un carácter como argumento, lo que es técnicamente correcto. Sin embargo, también es válido declarar la función como int contarVocales(char cadena[]), ya que en C/C++, los arrays de caracteres se pasan como punteros al primer elemento.

  • La diferencia entre struct y typedef struct.

    En lenguaje C y C++, una estructura (struct) es un tipo de dato que te permite combinar diferentes variables de tipos distintos en una sola entidad. Por ejemplo, puedes tener una estructura llamada “Punto” que almacene las coordenadas x e y.

    Ejemplo de estructura:

    struct Punto {
        int x;
        int y;
    };
    

    Luego, para usar esta estructura y declarar variables de tipo “Punto”, normalmente deberías hacerlo así:

    struct Punto miPunto;
    miPunto.x = 10;
    miPunto.y = 5;
    

    La palabra clave struct debe ir antes del nombre de la estructura cada vez que declares una variable.

    Sin embargo, si usas “typedef struct”, puedes crear un nuevo nombre para esta estructura. Esto te permite omitir la palabra clave struct al declarar variables de esa estructura.

    Ejemplo con “typedef struct”:

    typedef struct {
        int x;
        int y;
    } Punto;
    

    Punto miPunto;
    miPunto.x = 7;
    miPunto.y = 3;
    

    La diferencia entre “struct” y “typedef struct” es cómo declaras variables de ese tipo de estructura. Con “typedef struct”, puedes crear un alias para la estructura y usar ese alias directamente sin necesidad de escribir la palabra struct.

  • Utilización de Estructuras struct{};

    Así como las matrices permiten definir el tipo de variables que pueden contener varios elementos de datos del mismo tipo, ee manera similar, las Estructuras son otro tipo de datos definido por el usuario que permite combinar elementos de datos de diferentes tipos.

    En C, las estructuras son una colección de variables agrupadas por conveniencia.

    En C++ son lo mismo que una clase excepto que los miembros de la estructura son públicos por defecto.

    struct pcb
    {
      String model ; // Nombre del modelo
      int npd ;       // Numero de pines digitales
      int npa ;       // Numero de pines analogicos
      float volt ;    // Tension de funcionamiento
    } ;
    
    void setup() {
    
      Serial.begin(115200);
      pcb PLACA_UNO_R3;
    
      // Asignación de valores
      PLACA_UNO_R3.model = "uno" ;
      PLACA_UNO_R3.npd = 13 ;
      PLACA_UNO_R3.npa = 5 ;
      PLACA_UNO_R3.volt = 5.0F ;
    
      // Lectura de valores
      int numpd = PLACA_UNO_R3.npd ;
      float voltage = PLACA_UNO_R3.volt ;
    
      Serial.print("\nVoltaje: ");
      Serial.println(voltage);
      
      Serial.print("Numero de pines digitales: ");
      Serial.println(numpd);
      
      Serial.print("Numero de pines analogicos: ");
      Serial.println(PLACA_UNO_R3.npa);  
        
      Serial.print("Modelo de PCB: ");
      Serial.println(PLACA_UNO_R3.model);
    
    }
    
    void loop() {
    
    }
    
  • ESP32 y Node-RED + MQTT (Publicar/Subscribir o Susbribir)

    Utilización de Node-RED para controlar las entradas/salidas del ESP8266/ESP32 y mostrar los datos de sensores en su interfaz.

    El software Node-RED se ejecuta en una Raspberry Pi y la comunicación entre el ESP8266 y el software Node-RED se realiza a través del protocolo de comunicación MQTT.

    Se programará el ESP32 usando Arduino IDE

    Requisitos:

    Primeros pasos con NodeRed y Raspberry Pi

    La comunicación entre Arduino IDE y Node-RED a través del protocolo MQTT permite intercambiar datos y comandos entre un dispositivo basado en ESP8266 o ESP32 (programado con Arduino IDE) y un servidor Node-RED que se ejecuta en otra máquina, como una Raspberry Pi.

    1. Preparación del entorno:
      • Asegurarse que Node-RED esté instalado y en funcionamiento en la máquina que actuará como servidor.
      • Configurar un servidor MQTT y verifica que esté en funcionamiento en la misma máquina que Node-RED.
      • Conecta tu ESP8266 o ESP32 a la red Wi-Fi para que pueda acceder al servidor MQTT.
    2. Uso de la librería PubSubClient en Arduino IDE:
      • En Arduino IDE, instalar la librería PubSubClient para facilitar la comunicación MQTT.
      • Configura tu dispositivo ESP8266 o ESP32 para conectarse a la red Wi-Fi y establecer una conexión con el servidor MQTT utilizando la dirección IP y el puerto correspondientes.
    3. Envío* de mensajes MQTT desde Arduino IDE:
      • Una vez establecida la conexión MQTT, utilizar la función client.publish() para enviar mensajes al servidor Node-RED.
      • Define un “topic” específico para cada tipo de mensaje que desees enviar. Esto permitirá que el servidor Node-RED identifique y procese la información adecuadamente.
    4. Opcional: Recepción de mensajes MQTT en Arduino IDE*:
      • Para recibir mensajes del servidor Node-RED, puedes utilizar la función client.subscribe() para suscribirte a ciertos “topics” MQTT desde tu código de Arduino. De esta manera, tu dispositivo puede recibir comandos o información desde el servidor.
    5. Configuración de Node-RED:
      • En Node-RED, configurar el nodo MQTT para que se conecte al servidor MQTT que está en funcionamiento en la Raspberry Pi u otra máquina.
      • Utiliza el nodo MQTT para escuchar los “topics” a los que tu ESP8266/ESP32 está publicando y/o suscrito.
    6. Procesamiento de mensajes en Node-RED:
      • Una vez que Node-RED reciba los mensajes de un dispositivo ESP8266/ESP32, puedes procesarlos utilizando diferentes nodos para la lógica y la visualización. Esto te permitirá realizar acciones o presentar los datos recibidos según tus necesidades.
    7. Prueba y Depuración.
  • Funciones y métodos integrados en Arduino IDE

    Cuando se trata de desarrollar proyectos electrónicos, Arduino IDE se ha convertido en una plataforma popular gracias a sus características únicas y su versatilidad. Además de su similitud con la sintaxis de C y C++, Arduino ofrece una serie de funciones y métodos específicos que permiten interactuar de manera eficiente con los componentes electrónicos. En este artículo, destacaremos algunas de las particularidades de Arduino y cómo aprovechar al máximo su potencial en tus proyectos.

    Una de las grandes ventajas de Arduino IDE es la amplia variedad de bibliotecas predefinidas disponibles. Estas bibliotecas contienen funciones listas para usar que simplifican la interacción con dispositivos y módulos comunes. Al importar una biblioteca específica, se obtiene acceso instantáneo a métodos que facilitan tareas como leer sensores, controlar motores, comunicarse con pantallas y mucho más. La biblioteca estándar de Arduino es solo el comienzo; existen innumerables bibliotecas de terceros creadas por la comunidad Arduino que ofrecen aún más funcionalidades especializadas.

    Además de las bibliotecas, Arduino también ofrece una serie de funciones y métodos integrados que son fundamentales para el desarrollo de proyectos electrónicos. Algunos ejemplos destacados son:

    1. digitalRead() y digitalWrite(): Estas funciones permiten leer y escribir valores digitales en los pines de Arduino. Son esenciales para interactuar con botones, interruptores y otros dispositivos que funcionan con señales digitales.
    2. analogRead() y analogWrite(): Arduino también cuenta con pines analógicos, y estas funciones permiten leer y escribir valores analógicos. Son especialmente útiles para trabajar con sensores de luz, temperatura y otros dispositivos que generan señales analógicas.
    3. Serial: Arduino tiene soporte para la comunicación serial, lo que permite establecer una conexión con otros dispositivos, como una computadora. La clase Serial ofrece métodos para enviar y recibir datos a través del puerto serie, lo que es esencial para la depuración y la interacción con otros sistemas.
    4. Wire: Esta biblioteca permite la comunicación I2C, un protocolo ampliamente utilizado para conectar múltiples dispositivos en un bus de dos hilos. Con los métodos proporcionados por la biblioteca Wire, es posible enviar y recibir datos entre Arduino y otros dispositivos compatibles con I2C.

    Estas son solo algunas de las particularidades de Arduino que te permitirán aprovechar al máximo su potencial en tus proyectos. Explorar las bibliotecas, funciones y métodos específicos de Arduino te brindará un mayor control sobre tus componentes electrónicos y te permitirá crear proyectos más sofisticados. Además, no olvides que la comunidad Arduino es muy activa, por lo que siempre puedes buscar ejemplos, tutoriales y proyectos similares para inspirarte y aprender nuevas formas de utilizar Arduino en tus creaciones.

    En conclusión, al destacar las particularidades de Arduino, como sus funciones y métodos específicos, los lectores podrán comprender mejor cómo aprovechar al máximo el potencial de Arduino en sus proyectos electrónicos. Explorar las bibliotecas predefinidas, aprender sobre las funciones integradas y estar al tanto de la comunidad Arduino te abrir

  • Sintaxis de código Arduino IDE

    Arduino IDE utiliza un lenguaje de programación basado en el estándar de C++, aunque proporciona una serie de funciones y bibliotecas específicas para facilitar la interacción con los componentes electrónicos. Aunque existen algunas diferencias y limitaciones en comparación con el C++ estándar, los principios básicos de la sintaxis son los mismos.

    La sintaxis general para escribir el programa Arduino es casi similar a la del C y C++ ordinario. Aquellos que estén familiarizados con el C y C++ básico podrán comenzar a utilizarlo fácilmente.

    Un programa Arduino se estructura principalmente en dos funciones: setup() y loop(). La función setup() se ejecuta una sola vez al inicio del programa y se utiliza para realizar la configuración inicial, como la inicialización de pines y la configuración de la comunicación serial. La función loop() es la parte principal del programa y se ejecuta continuamente en un ciclo infinito después de que setup() ha finalizado. Aquí es donde se colocan las instrucciones que se deben repetir una y otra vez, como leer sensores, tomar decisiones y controlar los actuadores.

    La mayoría de las instrucciones en Arduino IDE siguen la estructura de la programación en C y C++. Por ejemplo, para asignar un valor a una variable, se utiliza el operador de asignación (=). Los operadores aritméticos como suma (+), resta (-), multiplicación (*), división (/) y módulo (%) también se utilizan de la misma manera.

    Las estructuras de control como las condicionales (if, else if, else) y los bucles (for, while, do-while) se utilizan para tomar decisiones y repetir bloques de código, al igual que en C y C++. Estas estructuras permiten controlar el flujo del programa en función de ciertas condiciones o realizar iteraciones hasta que se cumpla una condición específica.

    Además de la sintaxis básica, Arduino proporciona una amplia gama de bibliotecas predefinidas que contienen funciones listas para usar. Estas bibliotecas simplifican la interacción con dispositivos y módulos comunes, como sensores, pantallas LCD, motores, comunicación inalámbrica, entre otros. Al incluir una biblioteca específica, puedes aprovechar las funciones y métodos que ofrece para facilitar el desarrollo de tu proyecto.

    En resumen, la sintaxis de código Arduino se basa en el lenguaje de programación C++ estándar, pero con algunas diferencias y bibliotecas adicionales. Aquellos familiarizados con C y C++ básico encontrarán que Arduino es fácil de aprender y utilizar. Con su sintaxis intuitiva y bibliotecas convenientes, Arduino se ha convertido en una plataforma popular para el desarrollo de proyectos electrónicos, desde simples experimentos hasta complejas aplicaciones embebidas.

  • Utilizar ambos núcleos de un ESP32

    FreeRTOS (Free Real-Time Operating System) es un sistema operativo de tiempo real de código abierto diseñado para sistemas embebidos y aplicaciones en tiempo real. Un sistema operativo es un software que administra los recursos del hardware y proporciona una interfaz para que las aplicaciones se ejecuten en un dispositivo, como un microcontrolador o microprocesador.

    En el contexto de los microcontroladores, como el ESP32, los sistemas operativos en tiempo real (RTOS) como FreeRTOS son útiles para administrar tareas concurrentes que deben ejecutarse de manera independiente y en un orden específico. Esto permite que las tareas se ejecuten en paralelo y que el sistema pueda responder rápidamente a eventos en tiempo real.

    Las tareas son como pequeños programas que se ejecutan de forma independiente y tienen su propia parte de la memoria (pila) para almacenar datos locales y trabajar en una tarea específica. Un RTOS permite que las tareas compartan el tiempo de ejecución del procesador, lo que permite una mejor utilización de los recursos del sistema.

    En FreeRTOS, xTaskCreatePinnedToCore es una función utilizada para crear tareas que se ejecutarán en un núcleo de procesador específico en sistemas multi-núcleo, como el ESP32.

    Se utiliza FreeRTOS para crear dos tareas: parpadearLedNucleo0 y parpadearLedNucleo1. Cada tarea controla un LED y los hace parpadear con diferentes intervalos de tiempo. Al usar FreeRTOS, estas tareas se pueden ejecutar en núcleos diferentes del ESP32, lo que permite que las tareas de parpadeo se realicen en paralelo sin bloquear la ejecución del programa principal.

    FreeRTOS también proporciona mecanismos para sincronización y comunicación entre tareas, lo que permite que las tareas se comuniquen y cooperen en la resolución de problemas complejos.

    const int ledPinNucleo0 = 2;
    const int ledPinNucleo1 = 4;
    
    void parpadearLedNucleo0(void *parameter) {
      (void)parameter; // Ignorar el parámetro, ya que no lo usamos en este ejemplo
    
      while (true) {
        digitalWrite(ledPinNucleo0, HIGH);
        Serial.println("LED Núcleo 0 encendido");
        delay(500);
        digitalWrite(ledPinNucleo0, LOW);
        Serial.println("LED Núcleo 0 apagado");
        delay(500);
      }
    }
    
    void parpadearLedNucleo1(void *parameter) {
      (void)parameter; // Ignorar el parámetro, ya que no lo usamos en este ejemplo
    
      while (true) {
        digitalWrite(ledPinNucleo1, HIGH);
        Serial.println("LED Núcleo 1 encendido");
        delay(300);
        digitalWrite(ledPinNucleo1, LOW);
        Serial.println("LED Núcleo 1 apagado");
        delay(300);
      }
    }
    
    void setup() {
      Serial.begin(115200);
      pinMode(ledPinNucleo0, OUTPUT);
      pinMode(ledPinNucleo1, OUTPUT);
    
      xTaskCreatePinnedToCore(parpadearLedNucleo0, "Nucleo 0 LED", 10000, NULL, 1, NULL, 0);
      xTaskCreatePinnedToCore(parpadearLedNucleo1, "Nucleo 1 LED", 10000, NULL, 1, NULL, 1);
    }
    
    void loop() {
      // Nada que hacer en loop, ya que las tareas se encargan del parpadeo de los LEDs
    }
    
    

    Con estos cambios, se mostrarán mensajes en el monitor serie cada vez que los LEDs cambien de estado, lo que te permitirá verificar el funcionamiento correcto del código y seguir el comportamiento de los LEDs. Recuerda que necesitarás abrir el Monitor Serie en el IDE de Arduino para ver los mensajes que se imprimen.

  • Prototipo Mecatrónica: Máquina Encapsuladora de Café

    Prototipo Mecatrónica: Máquina Encapsuladora de Café

    Electrónica y programación para prototipo con ESP32, LCD, Controladoras de Motor paso a paso y transistor para motor DC y resistencia de sellado.

  • Arduino IDE: Compilar código para ESP32/ESP8266

    Arduino IDE es un compilador que hace que insertar lógica en lenguaje C sea muy fácil, sobre todo si la placa que compras es marca Arduino pues viene con el “CORE” pre-instalado.

    Cuando utilizamos placas de otros fabricante o incluso microcontroladores que no se encuentran en estas placas marca Arduino, tenemos muchas veces a disposición Frameworks de diversos fabricantes, como es el caso de los microcontroladores ESPRESSIF: ESP8266 y ESP32

    Luego de tener instalado el driver del FTDI en nuestro ordenador, se procede a decirle al “Arduino IDE” desde qué dirección cargar placas adicionales.

    Archivo > Preferencias

    Puedes compilar este código con Arduino IDE

    ESP8266 Core

    https://arduino.esp8266.com/stable/package_esp8266com_index.json

    ESP32 Core

    https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

    Si quieres tener instalados los firmwares de ambos microcontroladores, puedes separar los link con una “,”

    https://arduino.esp8266.com/stable/package_esp8266com_index.json, https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

    Ver https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md para más detalles.

    ¿Cómo verificar si el microcontrolador se instaló correctamente?


    Ahora que ha instalado ESP32 en su “Arduino IDE”, si desea saber si desea instalar ESP32/8266 en Arduino IDE correctamente o no. Puede verificarlo usando un ejemplo simple ya disponible en Arduino IDE para la placa de desarrollo ESP32 para Internet de las cosas. Cuando instala la biblioteca ESP32 en Arduino IDE, estos ejemplos también se instalan.

    Se pueden seguir estos pasos:

    1. conectar tu placa con una computadora a través de un cable USB.

    2. Conectar la placa con una computadora, seleccione la placa que está utilizando.

    Hay muchos tipos de placas ESP32/8266 disponibles en el mercado. Suelo preferir la versión de ALIExpress Wemos D32 que incluye AUTOFLASH. Pero puedes usar cualquier tablero que quieras. Para seleccionar la placa, ir a herramientas>Placas, clic en el módulo de Desarrollo. Imagen a continuación:

    Ahora selección del puerto:

    Ahora subir el Sketch (Control+U)