En este tutorial veremos cómo implementar comunicación serial bidireccional entre Arduino y una aplicación en App Inventor, usando Bluetooth y JSON para transmitir información de forma organizada.
Este ejemplo incluye:
- Control de dos LEDs desde el celular.
- Lectura de pulsadores para enviar el estado de vuelta a la app.
- Control de brillo mediante un slider (PWM).
Materiales necesarios:
- Arduino UNO (o compatible).
- Módulo Bluetooth HC-05 o HC-06.
- 2 LEDs con resistencias.
- 2 Pulsadores con resistencias pull-up (o internas).
Explicación del código
Librerías usadas
- SoftwareSerial.h: permite crear un puerto serial adicional en los pines 10 (RX) y 11 (TX).
- ArduinoJson.h: facilita la conversión de cadenas en formato JSON a variables y viceversa.
Estructura del JSON
La app en App Inventor envía datos como:
{"Switch1":true,"Switch2":false,"slider1":128}
Y Arduino responde con el estado actualizado de los pulsadores en el mismo formato JSON.
Flujo de comunicacion:
- De la app a Arduino: se envía un JSON con el estado de los switches y el slider.
- De Arduino a la app: cuando se presiona un pulsador, Arduino responde con un JSON actualizando los valores.
Control de LEDs y pulsadores
- Los LEDs se controlan con digitalWrite() en base al array dato[].
- El brillo se controla con analogWrite() usando el valor recibido en valorSlider.
- Los pulsadores se leen con digitalRead() y se implementa un antirrebote por software.
Código completo:
Repositorio de github: Ver repositorio de github
/*Comunicación serial bidireccional.- Los datos recibidos bienen de una aplicacion creada en appInventor a travez de bluetooth* Código escrito por: Esteban Carrillo para EDEPTEC.* Página web: https://www.edeptec.com* Facebook: @edeptec* Youtube: https://youtube.com/c/EDEPTEC*/#include <ArduinoJson.h> // Libreria para convertir string a JSON#include <SoftwareSerial.h>#define rxPin 10#define txPin 11SoftwareSerial mySerial(rxPin, txPin); // crear un nuevo onjeto SoftwareSerialint leds[2] = { 13, 3 }; // Pines en donde van conectados los ledsint ledControlBrillo = 6;int pulsadores[2] = { 2, 4 }; // Pines en donde van conectados los pulsadoresString str = ""; // Almacena el string recivido por el puerto serialconst int numeroDeDatos = 2; // Numero de datos a recibirint dato[numeroDeDatos]; // Array para almacenar los valores de los datos recibidosint valorSlider = 0; //Almacena valor pwm 0-255bool estadoPrevio[2] = { 0, 0 }; //Estados previos de los pulsadores "Antirrebote"/*** Configura los pines de los LEDs como salidas, de los pulsadores como entradas* y establece la velocidad de comunicación serial.*/void setup() {mySerial.begin(9600);Serial.begin(9600);for (int i = 0; i < numeroDeDatos; i++) {pinMode(leds[i], OUTPUT);digitalWrite(leds[i], LOW);pinMode(pulsadores[i], INPUT_PULLUP);}pinMode(ledControlBrillo, OUTPUT);}/*** Bucle principal del programa.** En este bucle se verifica si hay datos disponibles en el puerto serie,* si es así se almacenan en un string y se convierten a un objeto JSON.* Luego se extraen los valores de los datos recibidos y se almacenan en un* array. Finalmente se actualiza el brillo de los LEDs con los valores* del array.*/void loop() {JsonDocument doc; // Asigna el documento JSON a docif (mySerial.available() > 0) { // Verificar si hay datos disponibles// Leer hasta el final del stringstr = mySerial.readStringUntil('}'); //String en este punto {"value1":255,"value2":255,"value3":255// Agregar "}" al final del stringstr.concat("}"); //String en este punto: {"value1":255,"value2":255,"value3":255}Serial.println(str); // Imprime el string en el monitor serialDeserializationError error = deserializeJson(doc, str); // Convertir el string a JSONif (error) { // Verificar si hubo un error en la conversionSerial.print(F("deserializeJson() failed: "));Serial.println(error.f_str());return;}// Extrae los valores de los datos recibidos y los almacena en el array datodato[0] = doc["Switch1"].as<boolean>(); //Valor del LED N°1dato[1] = doc["Switch2"].as<boolean>(); //Valor del LED N°2valorSlider = doc["slider1"].as<int>(); //Valor de pwm para: ledControlBrillo}bool estadoPulsador[2] = { 0, 0 }; // Almacena estados de los pulsadoresfor (int i = 0; i < numeroDeDatos; i++) {estadoPulsador[i] = digitalRead(pulsadores[i]); // Estados lógicos del los pulsadorif (estadoPulsador[i] != estadoPrevio[i] && estadoPulsador[i] == HIGH) { // Implementación antirrebote && si se presiona el pulsador:dato[i] = !dato[i]; // Hace un intercabio de valores ejemplo si antes era true ahora es falsedoc["Switch1"] = dato[0] ? "true" : "false"; //Establece le valor de "true" o "false" a la propiedad "Switch1" ejemplo {"Switch1":"true"}doc["Switch2"] = dato[1] ? "true" : "false";serializeJson(doc, mySerial); // Convierte el json a string y lo envia a traves del puerto serial.}delay(10); // Pausa de 10msestadoPrevio[i] = estadoPulsador[i]; //Implementacion AntirrebotedigitalWrite(leds[i], dato[i]); //Enciende o apaga los leds}analogWrite(ledControlBrillo, valorSlider); // Controla el brillo del led "Pwm"}

Publicar un comentario
¡Hola! Nos alegra mucho que hayas llegado hasta aquí y que estés leyendo este artículo en Edeptec.
Este formulario es un espacio abierto para ti: puedes dejar un comentario con tus dudas, sugerencias, experiencias o simplemente tu opinión sobre el tema tratado.
» ¿Te resultó útil la información?
» ¿Tienes alguna experiencia personal que quieras compartir?
» ¿Se te ocurre algún tema que te gustaría ver en próximos artículos?
Recuerda que este espacio es para aprender y compartir, por eso te animamos a participar de manera respetuosa y constructiva. Tus comentarios pueden ayudar a otros lectores que están en el mismo camino, ya sea en electrónica, programación, deportes o tecnología.
¡Gracias por ser parte de esta comunidad de aprendizaje! Tu participación es lo que hace crecer este proyecto.