Uso de módulo WiFi Esp8266 con Arduino UNO e IoT en Thingsboard

/* AmbiSensor - Sensor Ambiental (simulación) - IoT (Internet of Things)
   Julio César Sandria Reynoso - Mayo 2026
   Este programa genera aleatoriamente datos ambientales de
   Temperatura, Humedad, CO2 e Iluminación, y los envía a
   un servidor en la nube para poder ver los datos en tiempo
   real desde cualquier dispositivo 
  Hardware: Arduino UNO, Módulo WiFi Esp8266, Fuente de poder para protoboard,
  protoboard, 2 resistencias de 1K, cables dupont.
*/

// Incluimos la librería WiFiEspAT que es más reciente que WiFiEsp
#include <WiFiEspAT.h>

// Si usamos Arduino Mega o Leonardo USAR_MEGA = true
// Si usamos Arduino Uno o Nano USAR_MEGA = false
// const bool USAR_MEGA = true; // true = Arduino Mega | false = Arduino Uno

// Configuración dinámica de puertos Serial según la placa
// usando directivas del precompilador
#if defined(ARDUINO_AVR_MEGA2560) || defined(__AVR_ATmega2560__)
  // Si Arduino IDE detecta un Arduino Mega o Leonardo
  // Conecta pin 18 (TX1) a pin RX del Esp, con divisor de voltaje a 3.3V
  // Conecta pin 19 (RX1) a pin TX del Esp
  #define EspSerial Serial1
#else
  #include <SoftwareSerial.h>
  // En Arduino Uno o Nano:
  // Conecta pin 2 (RX) a pin TX del Esp
  // Conecta pin 3 (TX) a pin RX del Esp, con divisor de voltaje a 3.3V
  SoftwareSerial softSerial(2, 3); 
  #define EspSerial softSerial
#endif

// Credenciales Wi-Fi
const char* ssid     = "nombre-red-wifi";
const char* password = "clave-red-wifi";

// Configuración del servidor ThingsBoard
const char* server   = "thingsboard.cloud";
const int port       = 80;
const char* token    = "TOKEN";

// Variables de ambiente
float temp = 25;          // En grados Celcius
float humedad = 62;       // En porcentaje (%)
int co2 = 450;            // En ppm (partes por millón)
int luz = 780;            // En luxes o valor analógico (0-1023)

void setup() {
  Serial.begin(9600);
  Serial.println("Iniciando programa AmbiSensor - Sensor Ambiental...");

  // Inicializar la comunicación serial con el módulo WiFi Esp8266
  EspSerial.begin(9600); // Velocidades preferentes 115200 (Mega) o 9600 (Uno)

  Serial.println("Inicializando modulo Wi-Fi...");
  WiFi.init(&EspSerial);

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("No se encontró el módulo Wi-Fi AT");
    while (true); // Detener el programa si no hay módulo
  }

  // Conectar a la red Wi-Fi
  Serial.print("Conectando a Wi-Fi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n¡Conectado a la red!");
}

void loop() {
  // Asegurar que seguimos conectados antes de enviar datos
  if (WiFi.status() == WL_CONNECTED) {
    
    WiFiClient client;
    
    // Abrir conexión TCP con el servidor
    if (client.connect(server, port)) {
      Serial.println("Conectado al servidor de ThingsBoard");

      // *** AQUÍ SE DEBEN TOMAR LECTURAS DE LOS SENSORES REALES ***
      // Para este ejemplo, vamos simulando lecturas aleatorias
      temp += 2-random(5);        // En grados Celcius
      humedad += 2-random(5);     // En porcentaje (%)
      co2 += 7-random(15);        // En ppm (partes por millón)
      luz += 7-random(15);        // En luxes o valor analógico (0-1023)

      // 2. Preparar un JSON con múltiples variables
      // El formato final será: 
      // {"temperature":24.5,"humidity":62.5,"co2":450,"light":780}
      String sDatos = "{";
      sDatos += "\"temperature\":" + String(temp) + ",";
      sDatos += "\"humidity\":" + String(humedad) + ",";
      sDatos += "\"co2\":" + String(co2) + ",";
      sDatos += "\"light\":" + String(luz);
      sDatos += "}";

      // 3. Enviar la petición HTTP POST
      client.print("POST /api/v1/");
      client.print(token);
      client.println("/telemetry HTTP/1.1");
      
      // Encabezados
      client.print("Host: ");
      client.println(server);
      client.println("Content-Type: application/json");
      client.print("Content-Length: ");
      client.println(sDatos.length());
      client.println("Connection: close"); // Buena práctica para liberar memoria en el servidor
      
      // Línea en blanco obligatoria
      client.println(); 
      
      // Cuerpo de los datos (sDatos)
      client.print(sDatos);
      client.println();

      Serial.println("Datos enviados: " + sDatos);

      // 4. Leer la respuesta del servidor (para asegurarnos 
      // del 200 OK, que significa datos recibidos correctamente)
      unsigned long timeout = millis();
      while (client.available() == 0) {
        if (millis() - timeout > 5000) {
          Serial.println(">>> ¡Timeout!");
          client.stop();
          return;
        }
      }

      // Imprimir solo la primera línea (donde viene el código 200) 
      // para no saturar el monitor
      if (client.available()) {
        String status_line = client.readStringUntil('\r');
        Serial.println("Status: " + status_line);
      }

      // Cerrar la conexión
      client.stop();
    } else {
      Serial.println("Error: No se pudo conectar al servidor");
    }
  } else {
    Serial.println("Wi-Fi desconectado. Intentando reconectar...");
  }

  // Esperar 10 segundos antes del siguiente envío
  delay(10000);
}

Instalación de ROS 2 y Webots en Ubuntu 22.04 LTS

Por Julio César Sandria Reynoso
30 de abril de 2026

En este artículo se describe la instalación de ROS 2 y Webots en Ubuntu 22.04 LTS en una computadora con arranque dual (dual boot) que ya tiene Windows 11 instalado. El Dual Boot es la opción más robusta para simulaciones pesadas porque permite que Ubuntu acceda al 100% del hardware (CPU, RAM y, sobre todo, la GPU) sin las capas de abstracción de una máquina virtual.

A continuación se muestra la hoja de ruta para instalar Ubuntu 22.04 LTS junto a Windows 11 de forma segura:

1. Preparación en Windows 11 (Crítico)

Antes de tocar cualquier partición, se debe preparar el terreno para evitar bloqueos del sistema.

  • Desactivar «Inicio Rápido» (Fast Boot): Windows bloquea el disco duro al apagarse si esto está activo, impidiendo que Ubuntu escriba en él.
    • Panel de Control > Hardware y sonido > Opciones de energía > Elegir el comportamiento de los botones de inicio.
  • Desactivar BitLocker: Si Windows 11 tiene el cifrado de disco BitLocker activado, se debe desactivar o tener a mano la clave de recuperación de 48 dígitos. De lo contrario, no se podrá redimensionar la partición.
  • Hacer espacio: Hacer clic derecho en el botón de Inicio > Administración de discos. Reducir el volumen de la unidad C: para dejar al menos 60-100 GB de «Espacio no asignado» para Ubuntu, ROS 2 y simulaciones de Webots.

2. Crear el medio de instalación

  1. Descargar el archivo ISO oficial de Ubuntu 22.04.x LTS.
  2. Usar una herramienta como Rufus o BalenaEtcher para «quemar» el ISO en una memoria USB de al menos 8 GB.

3. Configuración de la BIOS/UEFI

Reiniciar la computadora y entrar al BIOS (usualmente presionando F2F12Del o Esc al arrancar).

  • Secure Boot: En la mayoría de las computadoras desktop o laptops modernas, se puede dejarlo activado, pero si se tienen problemas para arrancar el USB, probar desactivarlo.
  • SATA Mode: Asegurarse de que esté en AHCI (si está en RAID, Ubuntu podría no ver el disco duro o SSD). Cuidado: cambiar esto puede requerir configurar Windows para arrancar en AHCI primero.

4. El proceso de instalación de Ubuntu

Arrancar la computadora desde la USB (Boot Menu) y selecciona «Install Ubuntu». Siguiendo estos pasos clave:

  1. Red y Actualizaciones: Conectar a Wi-Fi y marca la casilla «Instalar programas de terceros para hardware de gráficos y Wi-Fi». Esto es vital para que los drivers de NVIDIA (si los hay) funcionen con Webots.
  2. Tipo de instalación: Aquí viene lo más importante. Seleccionar «Instalar Ubuntu junto a Windows Boot Manager».
    • Si no aparece esta opción, elegir «Más opciones» para asignar manualmente el espacio no asignado creado en el paso 1.
  3. Particionado (si se elige Manual): Crear una partición root (punto de montaje /) con el resto del espacio (mínimo 50 GB). Formato: ext4.
  4. Finalizar: Seguir las instrucciones de ubicación y usuario.

5. Post-Instalación: El menú GRUB

Al reiniciar la computadora, se deberá ver una pantalla negra con letras blancas (el GRUB) que permite elegir entre Ubuntu y Windows Boot Manager.

6. Configuración para ROS 2 + Webots

Una vez en Ubuntu, lo primero que se debe hacer es optimizar el sistema para la simulación:

  1. Drivers de Video: Ir a «Software y actualizaciones» > «Más controladores» y asegurarse de usar el driver NVIDIA (Proprietary, tested). Sin esto, Webots irá muy lento.

7. Instalación de ROS 2 Humble

A continuación se detalla los comandos para que, una vez que se inicie sesión en Ubuntu 22.04, se deje listo para realizar simulaciones con ROS 2.

Abrir una terminal (Ctrl + Alt + T) y ejecutar estos bloques de comandos:

7.1. Configurar los Repositorios y las Claves

Primero, autorizar a Ubuntu para que confíe en los servidores de ROS 2.

$ sudo apt update
$ sudo apt install curl gnupg2 lsb-release -y
$ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

7.2. Instalar ROS 2 Humble (Desktop)

Instalar la versión completa que incluye Rviz2.

$ sudo apt update
$ sudo apt install ros-humble-desktop ros-dev-tools -y

7.3. Instalar Webots y el Driver de ROS 2

Cyberbotics mantiene un repositorio propio, pero la forma más estable de integrarlo con ROS 2 es instalando el paquete oficial del puente:

$ sudo apt install ros-humble-webots-ros2 -y

Nota: Este comando instalará automáticamente una versión compatible de Webots si no se tiene.

7.4. Configurar el Entorno (Automático)

Para no tener que escribir source /opt/ros/humble/setup.bash cada vez que se abre una terminal, se añade a la configuración personal:

$ echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
$ source ~/.bashrc

7.5. Verificación de Seguridad

Para confirmar que todo está en orden, intentar correr el ejemplo oficial de un robot móvil en un entorno simulado:

$ ros2 launch webots_ros2_universal_robot multirobot_launch.py

Separar caracteres en Arduino

Fecha de publicado: 26-Jul-2018. Fecha de actualización: 19-Oct-2024.

Programa en Arduino para separar caracteres…

String split = "133,215,365";

void setup() {
  Serial.begin(9600);
}

void loop() {
int parte1 = getValue(split,',',0).toInt();
Serial.print(parte1);
delay(1000);
}

String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Actualización (19-oct-2024).

Inicialmente publiqué este código rápidamente porque lo usé en un proyecto en Arduino y quería guardarlo para poder reusarlo en otra ocasión. Ahora le hice algunos cambios para hacerlo más comprensible y agrego una explicación del mismo.

La idea es que en algún momento podemos recibir en Arduino una cadena (String) con valores separados con un caracter, una coma por ejemplo, y necesitamos obtener cada uno de los valores de la cadena.

La función String getValue(String data, char separator, int index), recibe el String data, el cual es recorrido caracter por caracter hasta encontrar el separador indicado por el caracter separator, y regresa la subcadena indicada por el número entero index. Considerando la numeración como en los arreglos, la primera subcadena tiene el índice cero, la segunda 1, y así sucesivamente.

Si se trata de acceder un índice que sobrepasa el número de subcadenas que hay, la función getValue() regresa una cadena vacía. El usuario debe tomar en cuenta esto al usar esta función en sus propios proyectos.

// Programa en C++ para Arduino
// Por: Julio César Sandria Reynoso
// Obtiene las partes de una cadena separada por el caracter indicado
String split = "123,45,67890";
char separador = ',';

void setup() { 
  Serial.begin(9600);
  Serial.print("Cadena a separar: ");
  Serial.println(split);
  
  String parte0 = getValue(split,separador,0);
  Serial.print("parte0 = ");
  Serial.println(parte0);
  
  String parte1 = getValue(split,separador,1);
  Serial.print("parte1 = ");
  Serial.println(parte1);
  
  String parte2 = getValue(split,separador,2);
  Serial.print("parte2 = ");
  Serial.println(parte2);
  
  String parte3 = getValue(split,separador,3);
  Serial.print("parte3 = ");
  Serial.println(parte3);
} 

void loop() { 

} 

String getValue(String data, char separator, int index) { 
  int found = 0;
  int strIndex[] = {0, -1}; 
  int maxIndex = data.length()-1; 
  for(int i=0; i<=maxIndex && found<=index; i++){ 
    if(data.charAt(i)==separator || i==maxIndex) {
      found++; 
      strIndex[0] = strIndex[1]+1; 
      strIndex[1] = (i == maxIndex) ? i+1 : i; 
    } 
  } 
  return found>index ? 
         data.substring(strIndex[0], strIndex[1]) : ""; 
}

La ejecución de este programa muestra en el monitor serial la siguiente salida:

Cadena a separar: 123,45,67890
parte0 = 123
parte1 = 45
parte2 = 67890
parte3 = 

Si quieres aprender sobre robótica con Arduino, programación o algo más relacionado con computación o tecnologías de información, pide informes en el Instituto de Robótica de Xalapa (www.irox.mx).

Mtro. Julio C. Sandria R.

Cursos

En el Instituto de Robótica de Xalapa se imparten cursos y talleres de robótica en verano y permanentes para niños, jóvenes y adultos, tales como:

  • Cursos de Robótica para Niños y Jóvenes
  • Cursos de Arduino
  • Cursos de robótica con Arduino
  • Cursos de robótica con Lego Mindstorms NXT y EV3
  • Cursos de Raspberry Pi

El iRoX cuenta con amplia experiencia en la formación de niños y jóvenes, así como en la participación en eventos y concursos de robótica.

Cursos y talleres 2017

Más información en el sitio web del iRoX: www.iRoX.mx.