{"id":3342,"date":"2026-05-23T22:48:31","date_gmt":"2026-05-24T03:48:31","guid":{"rendered":"https:\/\/www.electroallweb.com\/?p=3342"},"modified":"2026-05-24T22:45:25","modified_gmt":"2026-05-25T03:45:25","slug":"ejercicios-practicos-de-la-comunicacion-rs485-con-arduino","status":"publish","type":"post","link":"https:\/\/www.electroallweb.com\/index.php\/2026\/05\/23\/ejercicios-practicos-de-la-comunicacion-rs485-con-arduino\/","title":{"rendered":"EJERCICIOS PR\u00c1CTICOS de la COMUNICACI\u00d3N RS485 con ARDUINO"},"content":{"rendered":"<section class=\"l-section wpb_row height_medium\"><div class=\"l-section-h i-cf\"><div class=\"g-cols vc_row type_default valign_top\"><div class=\"vc_col-sm-2 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><\/div><\/div><\/div><div class=\"vc_col-sm-10 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\r\n\t<div class=\"wpb_text_column  vc_custom_1779594278243\">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h5><span id=\"ESPECIFICACIONES_TECNICAS\">INTRODUCCI\u00d3N<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-265 alignnone\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png\" alt=\"\" width=\"1080\" height=\"36\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-1024x33.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-768x25.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores.png 1624w\" sizes=\"(max-width: 1080px) 100vw, 1080px\" \/><\/span><\/h5>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p style=\"text-align: justify;\" data-start=\"38\" data-end=\"217\">La comunicaci\u00f3n RS485 es un est\u00e1ndar de transmisi\u00f3n serial ampliamente utilizado en sistemas industriales y electr\u00f3nicos debido a su alta estabilidad y resistencia al ruido el\u00e9ctrico. Funciona mediante comunicaci\u00f3n diferencial usando dos l\u00edneas llamadas A y B, donde la informaci\u00f3n se transmite a trav\u00e9s de la diferencia de voltaje entre ambas se\u00f1ales. Esto permite realizar comunicaciones confiables a largas distancias y conectar varios dispositivos en un mismo bus. Generalmente se utiliza junto a m\u00f3dulos como el MAX485, que convierten las se\u00f1ales UART del microcontrolador en se\u00f1ales RS485. Gracias a sus ventajas, RS485 es muy empleado en automatizaci\u00f3n, redes de sensores, m\u00e1quinas vending y sistemas de control industrial.<\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<\/div><\/div><\/div><\/div><\/div><\/section><section class=\"l-section wpb_row height_medium\"><div class=\"l-section-h i-cf\"><div class=\"g-cols vc_row type_default valign_top\"><div class=\"vc_col-sm-2 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><\/div><\/div><\/div><div class=\"vc_col-sm-10 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\r\n\t<div class=\"wpb_text_column  vc_custom_1779594362620\">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h5><span id=\"ESPECIFICACIONES_TECNICAS\">ESPECIFICACIONES T\u00c9CNICAS<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-265 alignnone\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png\" alt=\"\" width=\"1080\" height=\"36\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-1024x33.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-768x25.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores.png 1624w\" sizes=\"(max-width: 1080px) 100vw, 1080px\" \/><\/span><\/h5>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<ol>\n<li data-section-id=\"17cgweb\" data-start=\"29\" data-end=\"75\">Microcontrolador: ATmega328P-AU @ 16 MHz<\/li>\n<li data-section-id=\"13rv9kz\" data-start=\"77\" data-end=\"149\">Alimentaci\u00f3n: Entrada 12- 24 VDC<\/li>\n<li data-section-id=\"1fabxv9\" data-start=\"151\" data-end=\"197\">Comunicaci\u00f3n: RS485 mediante MAX485ESA+T<\/li>\n<li data-section-id=\"wophse\" data-start=\"199\" data-end=\"243\">Entradas: 6 digitales, 2 anal\u00f3gicas<\/li>\n<li data-section-id=\"1e8zy3x\" data-start=\"245\" data-end=\"324\">Visualizaci\u00f3n: LCD 16&#215;2 con PCF8574T y Display 7 segmentos con 74HC595D<\/li>\n<li data-section-id=\"11g4l19\" data-start=\"326\" data-end=\"437\" data-is-last-node=\"\">Funciones:\n<ul>\n<li style=\"list-style-type: none;\">\n<ul data-start=\"341\" data-end=\"437\" data-is-last-node=\"\">\n<li data-section-id=\"19slzpy\" data-start=\"341\" data-end=\"361\">Comunicaci\u00f3n RS485<\/li>\n<li data-section-id=\"v4n365\" data-start=\"364\" data-end=\"384\">Lectura de se\u00f1ales<\/li>\n<li data-section-id=\"hktrqs\" data-start=\"387\" data-end=\"416\">Visualizaci\u00f3n y diagn\u00f3stico<\/li>\n<li data-section-id=\"1selz7k\" data-start=\"419\" data-end=\"437\" data-is-last-node=\"\">Programaci\u00f3n ISP<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<\/div><\/div><\/div><\/div><\/div><\/section><section class=\"l-section wpb_row height_medium\"><div class=\"l-section-h i-cf\"><div class=\"g-cols vc_row type_default valign_top\"><div class=\"vc_col-sm-2 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><\/div><\/div><\/div><div class=\"vc_col-sm-10 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\r\n\t<div class=\"wpb_text_column  vc_custom_1779594665635\">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h5><span id=\"ESPECIFICACIONES_TECNICAS\">ESQUEM\u00c1TICO ELECTRONICO<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-265 alignnone\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png\" alt=\"\" width=\"1080\" height=\"36\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-1024x33.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-768x25.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores.png 1624w\" sizes=\"(max-width: 1080px) 100vw, 1080px\" \/><\/span><\/h5>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<div class=\"w-image\"><div class=\"w-image-h\"><a href=\"https:\/\/github.com\/ELECTROALL\/Entrenador-RS485-Con-arduino\/blob\/main\/SCH_Schematic1_2026-05-23.pdf\" title=\"\" target=\"\" rel=\"\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"725\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485-1024x725.png\" class=\"attachment-large size-large\" alt=\"\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485-1024x725.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485-300x213.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485-768x544.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485-1536x1088.png 1536w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485-600x425.png 600w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/Esquematico-electronico-entrenador-rs485.png 1680w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/div><\/div><div class=\"w-btn-wrapper align_left\"><a class=\"w-btn style_outlined color_primary icon_none\" href=\"https:\/\/github.com\/ELECTROALL\/Entrenador-RS485-Con-arduino\/blob\/main\/SCH_Schematic1_2026-05-23.pdf\"><span class=\"w-btn-label\">Descargar esquematico PDF<\/span><\/a><\/div><\/div><\/div><\/div><\/div><\/div><\/section><section class=\"l-section wpb_row height_medium\"><div class=\"l-section-h i-cf\"><div class=\"g-cols vc_row type_default valign_top\"><div class=\"vc_col-sm-2 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><\/div><\/div><\/div><div class=\"vc_col-sm-10 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\r\n\t<div class=\"wpb_text_column  vc_custom_1779595067040\">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h5><span id=\"ESPECIFICACIONES_TECNICAS\">DISE\u00d1O PCB<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-265 alignnone\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png\" alt=\"\" width=\"1080\" height=\"36\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-1024x33.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-768x25.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores.png 1624w\" sizes=\"(max-width: 1080px) 100vw, 1080px\" \/><\/span><\/h5>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<div class=\"w-image\"><div class=\"w-image-h\"><a href=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23.png\" ref=\"magnificPopup\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"889\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-1024x889.png\" class=\"attachment-large size-large\" alt=\"\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-1024x889.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-300x261.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-768x667.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-1536x1334.png 1536w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-2048x1779.png 2048w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2026\/05\/3D_PCB1_2026-05-23-600x521.png 600w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/div><\/div><div class=\"w-btn-wrapper align_left\"><a class=\"w-btn style_solid color_primary icon_none\" href=\"https:\/\/github.com\/ELECTROALL\/Entrenador-RS485-Con-arduino\/blob\/main\/PCBA.rar\"><span class=\"w-btn-label\">DESCARGAR DISE\u00d1O PCB, GERBER, BOM, PICK&amp;PLACE<\/span><\/a><\/div><\/div><\/div><\/div><\/div><\/div><\/section><section class=\"l-section wpb_row height_medium\"><div class=\"l-section-h i-cf\"><div class=\"g-cols vc_row type_default valign_top\"><div class=\"vc_col-sm-2 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><\/div><\/div><\/div><div class=\"vc_col-sm-10 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\r\n\t<div class=\"wpb_text_column  vc_custom_1779595267857\">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h5><span id=\"ESPECIFICACIONES_TECNICAS\">CODIGOS PARA PRUEBAS<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-265 alignnone\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png\" alt=\"\" width=\"1080\" height=\"36\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-1024x33.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-768x25.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores.png 1624w\" sizes=\"(max-width: 1080px) 100vw, 1080px\" \/><\/span><\/h5>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<div class=\"w-btn-wrapper align_left\"><a class=\"w-btn style_solid color_primary icon_none\" href=\"https:\/\/drive.google.com\/file\/d\/1XDje0qqm3wgoJxahN20umNjQqCwcKD77\/view?usp=sharing\"><span class=\"w-btn-label\">DESCARGAR LIBRER\u00cdAS<\/span><\/a><\/div>\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h6>EJECICIO 1: ENVIO DE DATOS ANALOGICOS AMBOS(cada tarjeta env\u00eda y recibe a la vez)<\/h6>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO MAESTRO<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ ============================================\r\n\/\/ COMUNICACI\u00d3N BIDIRECCIONAL SIM\u00c9TRICA\r\n\/\/ Ambos dispositivos env\u00edan y reciben\r\n\/\/ Muestran: L\u00ednea 1 = lo que ENV\u00cdAN\r\n\/\/ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 L\u00ednea 2 = lo que RECIBEN\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n\/\/ Configuraci\u00f3n\r\n#define TIEMPO_TURNO 250 \u00a0\/\/ 250ms cada turno (2 turnos = 500ms ciclo)\r\n#define PIN_ANALOGO A6\r\n\r\n\/\/ Variables\r\nunsigned long lastTurnTime = 0;\r\nbool miTurno = true; \u00a0\/\/ true = yo env\u00edo, false = yo recibo\r\nint miValor = 0;\r\nint ultimoValorRecibido = -1;\r\nint ultimoValorEnviado = -1;\r\n\r\n\/\/ Buffer para recibir datos\r\nString incomingData = \"\";\r\n\r\nvoid setup() {\r\n\u00a0 \/\/ Inicializar RS485\r\n\u00a0 Serial.begin(19200);\r\n\r\n\u00a0 \/\/ Inicializar LCD\r\n\u00a0 lcd.init();\r\n\u00a0 lcd.backlight();\r\n\u00a0 lcd.clear();\r\n\r\n\u00a0 \/\/ Determinar qui\u00e9n empieza (aleatorio o por direcci\u00f3n)\r\n\u00a0 \/\/ Usamos el tiempo de inicio para evitar que ambos empiecen igual\r\n\u00a0 delay(random(100, 300));\r\n\r\n\u00a0 lcd.setCursor(0, 0);\r\n\u00a0 lcd.print(\"Envio: \u00a0 \u00a0 \u00a0\");\r\n\u00a0 lcd.setCursor(0, 1);\r\n\u00a0 lcd.print(\"Recibo: \u00a0 \u00a0 \");\r\n\r\n\u00a0 \/\/ Mostrar ID \u00fanico (\u00faltimo d\u00edgito de la direcci\u00f3n MAC o random)\r\n\u00a0 int miID = random(1, 100);\r\n\u00a0 lcd.setCursor(8, 0);\r\n\u00a0 lcd.print(\"ID:\");\r\n\u00a0 lcd.print(miID);\r\n\u00a0 delay(1000);\r\n\u00a0 lcd.clear();\r\n\r\n\u00a0 lcd.setCursor(0, 0);\r\n\u00a0 lcd.print(\"Yo envio:\");\r\n\u00a0 lcd.setCursor(0, 1);\r\n\u00a0 lcd.print(\"Recibo:\");\r\n}\r\n\r\nvoid loop() {\r\n\u00a0 unsigned long currentTime = millis();\r\n\r\n\u00a0 \/\/ ============================================\r\n\u00a0 \/\/ CAMBIO DE TURNO CADA TIEMPO_TURNO\r\n\u00a0 \/\/ ============================================\r\n\u00a0 if ((currentTime - lastTurnTime) &gt;= TIEMPO_TURNO) {\r\n\u00a0 \u00a0 lastTurnTime = currentTime;\r\n\u00a0 \u00a0 miTurno = !miTurno; \u00a0\/\/ Alternar turno\r\n\r\n\u00a0 \u00a0 if (miTurno) {\r\n\u00a0 \u00a0 \u00a0 \/\/ \u00a1Mi turno de ENVIAR!\r\n\u00a0 \u00a0 \u00a0 enviarDatos();\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n\r\n\u00a0 \/\/ ============================================\r\n\u00a0 \/\/ SI NO ES MI TURNO, ESCUCHO Y RECIBO\r\n\u00a0 \/\/ ============================================\r\n\u00a0 if (!miTurno) {\r\n\u00a0 \u00a0 recibirDatos();\r\n\u00a0 }\r\n}\r\n\r\n\/\/ ============================================\r\n\/\/ ENVIAR MIS DATOS POR RS485\r\n\/\/ ============================================\r\nvoid enviarDatos() {\r\n\u00a0 \/\/ Leer mi valor anal\u00f3gico\r\n\u00a0 miValor = analogRead(PIN_ANALOGO);\r\n\r\n\u00a0 \/\/ Mostrar en LCD lo que estoy enviando\r\n\u00a0 if (miValor != ultimoValorEnviado) {\r\n\u00a0 \u00a0 ultimoValorEnviado = miValor;\r\n\u00a0 \u00a0 lcd.setCursor(9, 0);\r\n\u00a0 \u00a0 lcd.print(\" \u00a0 \u00a0\");\r\n\u00a0 \u00a0 lcd.setCursor(9, 0);\r\n\u00a0 \u00a0 lcd.print(miValor);\r\n\u00a0 }\r\n\r\n\u00a0 \/\/ Enviar por RS485 con formato: \"VALOR:512\\n\"\r\n\u00a0 Serial.print(\"VALOR:\");\r\n\u00a0 Serial.print(miValor);\r\n\u00a0 Serial.println();\r\n\r\n\u00a0 \/\/ Peque\u00f1a pausa para asegurar env\u00edo\r\n\u00a0 delay(10);\r\n}\r\n\r\n\/\/ ============================================\r\n\/\/ RECIBIR DATOS DEL OTRO DISPOSITIVO\r\n\/\/ ============================================\r\nvoid recibirDatos() {\r\n\u00a0 while (Serial.available()) {\r\n\u00a0 \u00a0 char c = Serial.read();\r\n\r\n\u00a0 \u00a0 if (c == '\\n') {\r\n\u00a0 \u00a0 \u00a0 incomingData.trim();\r\n\r\n\u00a0 \u00a0 \u00a0 if (incomingData.startsWith(\"VALOR:\")) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 int valorRecibido = incomingData.substring(6).toInt();\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Mostrar en LCD lo que recib\u00ed\r\n\u00a0 \u00a0 \u00a0 \u00a0 if (valorRecibido != ultimoValorRecibido) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ultimoValorRecibido = valorRecibido;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 lcd.setCursor(8, 1);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 lcd.print(\" \u00a0 \u00a0\");\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 lcd.setCursor(8, 1);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 lcd.print(valorRecibido);\r\n\u00a0 \u00a0 \u00a0 \u00a0 }\r\n\u00a0 \u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 \u00a0 incomingData = \"\";\r\n\u00a0 \u00a0 }\r\n\u00a0 \u00a0 else if (c != '\\r') {\r\n\u00a0 \u00a0 \u00a0 incomingData += c;\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO ESCLAVO<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/\/ ============================================\r\n\/\/ COMUNICACI\u00d3N BIDIRECCIONAL SIM\u00c9TRICA\r\n\/\/ Ambos dispositivos env\u00edan y reciben\r\n\/\/ Muestran: L\u00ednea 1 = lo que ENV\u00cdAN\r\n\/\/           L\u00ednea 2 = lo que RECIBEN\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n\/\/ Configuraci\u00f3n\r\n#define TIEMPO_TURNO 250  \/\/ 250ms cada turno (2 turnos = 500ms ciclo)\r\n#define PIN_ANALOGO A6\r\n\r\n\/\/ Variables\r\nunsigned long lastTurnTime = 0;\r\nbool miTurno = true;  \/\/ true = yo env\u00edo, false = yo recibo\r\nint miValor = 0;\r\nint ultimoValorRecibido = -1;\r\nint ultimoValorEnviado = -1;\r\n\r\n\/\/ Buffer para recibir datos\r\nString incomingData = \"\";\r\n\r\nvoid setup() {\r\n  \/\/ Inicializar RS485\r\n  Serial.begin(19200);\r\n\r\n  \/\/ Inicializar LCD\r\n  lcd.init();\r\n  lcd.backlight();\r\n  lcd.clear();\r\n\r\n  \/\/ Determinar qui\u00e9n empieza (aleatorio o por direcci\u00f3n)\r\n  \/\/ Usamos el tiempo de inicio para evitar que ambos empiecen igual\r\n  delay(random(100, 300));\r\n\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Envio:      \");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Recibo:     \");\r\n\r\n  \/\/ Mostrar ID \u00fanico (\u00faltimo d\u00edgito de la direcci\u00f3n MAC o random)\r\n  int miID = random(1, 100);\r\n  lcd.setCursor(8, 0);\r\n  lcd.print(\"ID:\");\r\n  lcd.print(miID);\r\n  delay(1000);\r\n  lcd.clear();\r\n\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Yo envio:\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Recibo:\");\r\n}\r\n\r\nvoid loop() {\r\n  unsigned long currentTime = millis();\r\n\r\n  \/\/ ============================================\r\n  \/\/ CAMBIO DE TURNO CADA TIEMPO_TURNO\r\n  \/\/ ============================================\r\n  if ((currentTime - lastTurnTime) &gt;= TIEMPO_TURNO) {\r\n    lastTurnTime = currentTime;\r\n    miTurno = !miTurno;  \/\/ Alternar turno\r\n\r\n    if (miTurno) {\r\n      \/\/ \u00a1Mi turno de ENVIAR!\r\n      enviarDatos();\r\n    }\r\n  }\r\n\r\n  \/\/ ============================================\r\n  \/\/ SI NO ES MI TURNO, ESCUCHO Y RECIBO\r\n  \/\/ ============================================\r\n  if (!miTurno) {\r\n    recibirDatos();\r\n  }\r\n}\r\n\r\n\/\/ ============================================\r\n\/\/ ENVIAR MIS DATOS POR RS485\r\n\/\/ ============================================\r\nvoid enviarDatos() {\r\n  \/\/ Leer mi valor anal\u00f3gico\r\n  miValor = analogRead(PIN_ANALOGO);\r\n\r\n  \/\/ Mostrar en LCD lo que estoy enviando\r\n  if (miValor != ultimoValorEnviado) {\r\n    ultimoValorEnviado = miValor;\r\n    lcd.setCursor(9, 0);\r\n    lcd.print(\"    \");\r\n    lcd.setCursor(9, 0);\r\n    lcd.print(miValor);\r\n  }\r\n\r\n  \/\/ Enviar por RS485 con formato: \"VALOR:512\\n\"\r\n  Serial.print(\"VALOR:\");\r\n  Serial.print(miValor);\r\n  Serial.println();\r\n\r\n  \/\/ Peque\u00f1a pausa para asegurar env\u00edo\r\n  delay(10);\r\n}\r\n\r\n\/\/ ============================================\r\n\/\/ RECIBIR DATOS DEL OTRO DISPOSITIVO\r\n\/\/ ============================================\r\nvoid recibirDatos() {\r\n  while (Serial.available()) {\r\n    char c = Serial.read();\r\n\r\n    if (c == '\\n') {\r\n      incomingData.trim();\r\n\r\n      if (incomingData.startsWith(\"VALOR:\")) {\r\n        int valorRecibido = incomingData.substring(6).toInt();\r\n\r\n        \/\/ Mostrar en LCD lo que recib\u00ed\r\n        if (valorRecibido != ultimoValorRecibido) {\r\n          ultimoValorRecibido = valorRecibido;\r\n          lcd.setCursor(8, 1);\r\n          lcd.print(\"    \");\r\n          lcd.setCursor(8, 1);\r\n          lcd.print(valorRecibido);\r\n        }\r\n      }\r\n\r\n      incomingData = \"\";\r\n    } \r\n    else if (c != '\\r') {\r\n      incomingData += c;\r\n    }\r\n  }\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h6>EJERCICIO 2: COMUNICACI\u00d3N MAESTRO-ESCLAVO CON RETROALIMENTACI\u00d3N<\/h6>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO MAESTRO<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ ============================================\r\n\/\/ MAESTRO - RECIBE BOTONES DEL ESCLAVO\r\n\/\/ MUESTRA EN DISPLAY 7 SEGMENTOS (74HC595)\r\n\/\/ CONFIRMA RECEPCI\u00d3N AL ESCLAVO\r\n\/\/ MUESTRA ESTADO EN LCD I2C\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\n\/\/ LCD I2C (probar 0x27 o 0x3F)\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n\/\/ Pines del 74HC595\r\n#define DS_PIN   11\r\n#define SHCP_PIN 13\r\n#define STCP_PIN 12\r\n\r\n\/\/ Variables\r\nint ultimoValorMostrado = -1;\r\nunsigned long lastReceiveTime = 0;\r\nunsigned long lastHeartbeatTime = 0;\r\nunsigned long lastLcdUpdate = 0;\r\n\r\n\/\/ Variables para LCD\r\nint ultimoRecibido = -1;\r\nString ultimoRemitente = \"\";\r\nString estadoComunicacion = \"Esperando...\";\r\nint paquetesRecibidos = 0;\r\n\r\n\/\/ Buffer para comunicaci\u00f3n\r\nString incomingData = \"\";\r\n\r\n\/\/ Tabla de segmentos para n\u00fameros 0-9 (c\u00e1todo com\u00fan)\r\nbyte digitPatterns[] = {\r\n  0b11111100, \/\/ 0\r\n  0b01100000, \/\/ 1\r\n  0b11011010, \/\/ 2\r\n  0b11110010, \/\/ 3\r\n  0b01100110, \/\/ 4\r\n  0b10110110, \/\/ 5\r\n  0b10111110, \/\/ 6\r\n  0b11100000, \/\/ 7\r\n  0b11111110, \/\/ 8\r\n  0b11110110  \/\/ 9\r\n};\r\n\r\nvoid setup() {\r\n  \/\/ Inicializar RS485\r\n  Serial.begin(19200);\r\n\r\n  \/\/ Inicializar LCD\r\n  lcd.init();\r\n  lcd.backlight();\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar pines del 74HC595\r\n  pinMode(DS_PIN, OUTPUT);\r\n  pinMode(SHCP_PIN, OUTPUT);\r\n  pinMode(STCP_PIN, OUTPUT);\r\n\r\n  \/\/ Mostrar pantalla de inicio\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"=== MAESTRO ===\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Iniciando...\");\r\n  delay(2000);\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar LCD con encabezados fijos\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Recibido:      \");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Estado:        \");\r\n\r\n  \/\/ Mostrar 0 en display 7 segmentos\r\n  mostrarNumero(0);\r\n  delay(500);\r\n  mostrarNumero(8);\r\n  delay(500);\r\n  mostrarNumero(0);\r\n\r\n  \/\/ Enviar mensaje de inicio\r\n  Serial.println(\"SISTEMA_MAESTRO_LISTO\");\r\n}\r\n\r\nvoid loop() {\r\n  \/\/ ========================================\r\n  \/\/ 1. RECIBIR DATOS DEL ESCLAVO\r\n  \/\/ ========================================\r\n  while (Serial.available()) {\r\n    char c = Serial.read();\r\n\r\n    if (c == '\\n') {\r\n      incomingData.trim();\r\n\r\n      if (incomingData.startsWith(\"BOTON:\")) {\r\n        \/\/ Formato: BOTON:2:D2\r\n        int botonNumero = incomingData.substring(6, 7).toInt();\r\n        String botonPin = incomingData.substring(8);\r\n\r\n        if (botonNumero &gt;= 1 &amp;&amp; botonNumero &lt;= 6) {\r\n          lastReceiveTime = millis();\r\n          ultimoRecibido = botonNumero;\r\n          ultimoRemitente = botonPin;\r\n          paquetesRecibidos++;\r\n\r\n          \/\/ Actualizar LCD\r\n          actualizarLCD();\r\n\r\n          \/\/ Mostrar el n\u00famero en el display 7 segmentos\r\n          mostrarNumero(botonNumero);\r\n          ultimoValorMostrado = botonNumero;\r\n\r\n          \/\/ Enviar confirmaci\u00f3n al esclavo\r\n          Serial.print(\"OK:\");\r\n          Serial.print(botonNumero);\r\n          Serial.print(\":\");\r\n          Serial.print(botonPin);\r\n          Serial.println();\r\n\r\n          delay(10);\r\n        }\r\n      }\r\n      else if (incomingData == \"SISTEMA_ESCLAVO_LISTO\") {\r\n        estadoComunicacion = \"Esclavo OK\";\r\n        actualizarLCD();\r\n      }\r\n      else if (incomingData == \"ESCLAVO_HEARTBEAT\") {\r\n        lastReceiveTime = millis();\r\n        estadoComunicacion = \"Heartbeat OK\";\r\n        actualizarLCD();\r\n        \/\/ Parpadear display de 7 segmentos\r\n        mostrarNumero(0);\r\n        delay(50);\r\n        mostrarNumero(ultimoValorMostrado &gt; 0 ? ultimoValorMostrado : 0);\r\n      }\r\n\r\n      incomingData = \"\";\r\n    }\r\n    else if (c != '\\r') {\r\n      incomingData += c;\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 2. VERIFICAR TIMEOUT DE COMUNICACI\u00d3N\r\n  \/\/ ========================================\r\n  if (lastReceiveTime != 0 &amp;&amp; (millis() - lastReceiveTime) &gt; 10000) {\r\n    estadoComunicacion = \"TIMEOUT!\";\r\n    actualizarLCD();\r\n    mostrarError();\r\n    lastReceiveTime = millis() - 5000; \/\/ Para no mostrar error constantemente\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 3. HEARTBEAT DEL MAESTRO\r\n  \/\/ ========================================\r\n  if (millis() - lastHeartbeatTime &gt; 30000) {\r\n    lastHeartbeatTime = millis();\r\n    Serial.print(\"MAESTRO:Heartbeat|Paq:\");\r\n    Serial.print(paquetesRecibidos);\r\n    Serial.println();\r\n  }\r\n\r\n  \/\/ Actualizar LCD peri\u00f3dicamente\r\n  if (millis() - lastLcdUpdate &gt; 500) {\r\n    lastLcdUpdate = millis();\r\n    actualizarLCD();\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ ACTUALIZAR LCD CON ESTADO\r\n\/\/ ========================================\r\nvoid actualizarLCD() {\r\n  \/\/ Primera l\u00ednea: \u00daltimo valor recibido\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Recibido: \");\r\n  if (ultimoRecibido &gt; 0) {\r\n    lcd.print(ultimoRecibido);\r\n    lcd.print(\" (\");\r\n    lcd.print(ultimoRemitente);\r\n    lcd.print(\")   \");\r\n  } else {\r\n    lcd.print(\"-          \");\r\n  }\r\n\r\n  \/\/ Segunda l\u00ednea: Estado de comunicaci\u00f3n\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Estado: \");\r\n  lcd.print(estadoComunicacion);\r\n  lcd.print(\"     \");\r\n\r\n  \/\/ Mostrar contador de paquetes al final\r\n  lcd.setCursor(12, 1);\r\n  lcd.print(\"P:\");\r\n  lcd.print(paquetesRecibidos % 100);\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ MOSTRAR N\u00daMERO EN 7 SEGMENTOS\r\n\/\/ ========================================\r\nvoid mostrarNumero(int numero) {\r\n  if (numero &lt; 0 || numero &gt; 9) numero = 0;\r\n\r\n  byte patron = digitPatterns[numero];\r\n\r\n  digitalWrite(STCP_PIN, LOW);\r\n  shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, patron);\r\n  digitalWrite(STCP_PIN, HIGH);\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ MOSTRAR ERROR EN DISPLAY 7 SEGMENTOS\r\n\/\/ ========================================\r\nvoid mostrarError() {\r\n  byte errorPattern = 0b01111001;  \/\/ 'E'\r\n\r\n  digitalWrite(STCP_PIN, LOW);\r\n  shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, errorPattern);\r\n  digitalWrite(STCP_PIN, HIGH);\r\n\r\n  delay(100);\r\n  if (ultimoValorMostrado &gt; 0) {\r\n    mostrarNumero(ultimoValorMostrado);\r\n  } else {\r\n    mostrarNumero(0);\r\n  }\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO ESCLAVO<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ ============================================\r\n\/\/ ESCLAVO - LEE BOTONES (D2-D7) Y ENV\u00cdA POR RS485\r\n\/\/ MUESTRA EN DISPLAY 7 SEGMENTOS (74HC595)\r\n\/\/ MUESTRA ESTADO EN LCD I2C\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\n\/\/ LCD I2C (probar 0x27 o 0x3F)\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n\/\/ Pines del 74HC595\r\n#define DS_PIN   11\r\n#define SHCP_PIN 13\r\n#define STCP_PIN 12\r\n\r\n\/\/ Pines de botones (D2 a D7)\r\nconst int botones[] = {2, 3, 4, 5, 6, 7};\r\nconst int numBotones = 6;\r\nconst char* botonNombres[] = {\"D2\", \"D3\", \"D4\", \"D5\", \"D6\", \"D7\"};\r\n\r\n\/\/ Variables\r\nint ultimoEstado[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};\r\nint ultimoValorMostrado = -1;\r\nunsigned long lastDebounceTime[6] = {0, 0, 0, 0, 0, 0};\r\nunsigned long lastSendTime = 0;\r\nunsigned long lastLcdUpdate = 0;\r\n\r\n\/\/ Buffer para comunicaci\u00f3n\r\nString incomingData = \"\";\r\n\r\n\/\/ Variables para LCD\r\nint ultimoEnvio = -1;\r\nint ultimaRecepcion = -1;\r\nString ultimoComandoRecibido = \"\";\r\n\r\n\/\/ Tabla de segmentos para n\u00fameros 0-9 (c\u00e1todo com\u00fan)\r\nbyte digitPatterns[] = {\r\n  0b11111100, \/\/ 0\r\n  0b01100000, \/\/ 1\r\n  0b11011010, \/\/ 2\r\n  0b11110010, \/\/ 3\r\n  0b01100110, \/\/ 4\r\n  0b10110110, \/\/ 5\r\n  0b10111110, \/\/ 6\r\n  0b11100000, \/\/ 7\r\n  0b11111110, \/\/ 8\r\n  0b11110110  \/\/ 9\r\n};\r\n\r\nvoid setup() {\r\n  \/\/ Inicializar RS485\r\n  Serial.begin(19200);\r\n\r\n  \/\/ Inicializar LCD\r\n  lcd.init();\r\n  lcd.backlight();\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar pines del 74HC595\r\n  pinMode(DS_PIN, OUTPUT);\r\n  pinMode(SHCP_PIN, OUTPUT);\r\n  pinMode(STCP_PIN, OUTPUT);\r\n\r\n  \/\/ Configurar pines de botones como entradas con pull-up\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    pinMode(botones[i], INPUT_PULLUP);\r\n  }\r\n\r\n  \/\/ Mostrar pantalla de inicio\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"=== ESCLAVO ===\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Iniciando...\");\r\n  delay(2000);\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar LCD con encabezados fijos\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Envio:   Rec:\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Boton:       \");\r\n\r\n  \/\/ Mostrar 0 en display 7 segmentos\r\n  mostrarNumero(0);\r\n  delay(500);\r\n  mostrarNumero(8);\r\n  delay(500);\r\n  mostrarNumero(0);\r\n\r\n  \/\/ Enviar mensaje de inicio por RS485\r\n  Serial.println(\"SISTEMA_ESCLAVO_LISTO\");\r\n}\r\n\r\nvoid loop() {\r\n  \/\/ ========================================\r\n  \/\/ 1. LEER BOTONES Y ENVIAR AL MAESTRO\r\n  \/\/ ========================================\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    int lectura = digitalRead(botones[i]);\r\n\r\n    if (lectura == LOW &amp;&amp; ultimoEstado[i] == HIGH) {\r\n      if (millis() - lastDebounceTime[i] &gt; 50) {\r\n        lastDebounceTime[i] = millis();\r\n\r\n        int numeroBoton = i + 1;\r\n        String botonNombre = botonNombres[i];\r\n\r\n        \/\/ Enviar al maestro\r\n        Serial.print(\"BOTON:\");\r\n        Serial.print(numeroBoton);\r\n        Serial.print(\":\");\r\n        Serial.print(botonNombre);\r\n        Serial.println();\r\n\r\n        \/\/ Actualizar LCD con lo que se envi\u00f3\r\n        ultimoEnvio = numeroBoton;\r\n        actualizarLCD();\r\n\r\n        \/\/ Mostrar en display 7 segmentos local\r\n        mostrarNumero(numeroBoton);\r\n        ultimoValorMostrado = numeroBoton;\r\n\r\n        delay(50);\r\n      }\r\n    }\r\n    ultimoEstado[i] = lectura;\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 2. RECIBIR CONFIRMACIONES DEL MAESTRO\r\n  \/\/ ========================================\r\n  while (Serial.available()) {\r\n    char c = Serial.read();\r\n    if (c == '\\n') {\r\n      incomingData.trim();\r\n\r\n      if (incomingData.startsWith(\"OK:\")) {\r\n        \/\/ Formato: OK:2:D2\r\n        int numeroConfirmado = incomingData.substring(3, 4).toInt();\r\n        ultimoComandoRecibido = incomingData;\r\n\r\n        \/\/ Actualizar LCD con lo que se recibi\u00f3\r\n        ultimaRecepcion = numeroConfirmado;\r\n        actualizarLCD();\r\n\r\n        \/\/ Parpadear display para confirmar\r\n        mostrarNumero(0);\r\n        delay(100);\r\n        mostrarNumero(numeroConfirmado);\r\n      }\r\n      else if (incomingData.startsWith(\"MAESTRO:\")) {\r\n        \/\/ Heartbeat del maestro\r\n        ultimoComandoRecibido = incomingData;\r\n        actualizarLCD();\r\n      }\r\n\r\n      incomingData = \"\";\r\n    } else if (c != '\\r') {\r\n      incomingData += c;\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 3. REENV\u00cdO PERI\u00d3DICO (Heartbeat)\r\n  \/\/ ========================================\r\n  if (millis() - lastSendTime &gt; 30000) {\r\n    lastSendTime = millis();\r\n    Serial.println(\"ESCLAVO_HEARTBEAT\");\r\n  }\r\n\r\n  \/\/ Actualizar LCD cada 500ms (para parpadeo de indicadores)\r\n  if (millis() - lastLcdUpdate &gt; 500) {\r\n    lastLcdUpdate = millis();\r\n    actualizarLCD();\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ ACTUALIZAR LCD CON ESTADO\r\n\/\/ ========================================\r\nvoid actualizarLCD() {\r\n  \/\/ Primera l\u00ednea: Env\u00edo y Recepci\u00f3n\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Envio: \");\r\n  if (ultimoEnvio &gt; 0) {\r\n    lcd.print(ultimoEnvio);\r\n    lcd.print(\"   \");\r\n  } else {\r\n    lcd.print(\"-   \");\r\n  }\r\n\r\n  lcd.setCursor(10, 0);\r\n  lcd.print(\"Rec: \");\r\n  if (ultimaRecepcion &gt; 0) {\r\n    lcd.print(ultimaRecepcion);\r\n    lcd.print(\"   \");\r\n  } else {\r\n    lcd.print(\"-   \");\r\n  }\r\n\r\n  \/\/ Segunda l\u00ednea: Estado de botones\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Botones: \");\r\n\r\n  \/\/ Mostrar qu\u00e9 botones est\u00e1n presionados\r\n  String botonesActivos = \"\";\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    if (digitalRead(botones[i]) == LOW) {\r\n      botonesActivos += String(i + 1);\r\n    } else {\r\n      botonesActivos += \"-\";\r\n    }\r\n  }\r\n  lcd.print(botonesActivos);\r\n  lcd.print(\"     \");\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ MOSTRAR N\u00daMERO EN 7 SEGMENTOS\r\n\/\/ ========================================\r\nvoid mostrarNumero(int numero) {\r\n  if (numero &lt; 0 || numero &gt; 9) numero = 0;\r\n\r\n  byte patron = digitPatterns[numero];\r\n\r\n  digitalWrite(STCP_PIN, LOW);\r\n  shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, patron);\r\n  digitalWrite(STCP_PIN, HIGH);\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h6>EJERCICIO 3: COMUNICACI\u00d3N MAESTRO-ESCLAVO CON RETROALIMENTACI\u00d3N, pero para 5 tarjetas<\/h6>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO MAESTRO<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ ============================================\r\n\/\/ MAESTRO RS485 - CON BOTONES PROPIOS\r\n\/\/ RECIBE DE 4 ESCLAVOS (IDs 1-4)\r\n\/\/ LEE SUS PROPIOS BOTONES (D2-D7)\r\n\/\/ MUESTRA EN LCD Y 7 SEGMENTOS\r\n\/\/ RETRANSMITE A TODOS LOS ESCLAVOS\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\n\/\/ LCD I2C\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n\/\/ Pines del 74HC595\r\n#define DS_PIN   11\r\n#define SHCP_PIN 13\r\n#define STCP_PIN 12\r\n\r\n\/\/ ID del maestro (0 para distinguirlo)\r\n#define MASTER_ID 0\r\n\r\n\/\/ Pines de botones del maestro (D2 a D7)\r\nconst int botones[] = {2, 3, 4, 5, 6, 7};\r\nconst int numBotones = 6;\r\n\r\n\/\/ Configuraci\u00f3n de esclavos\r\nconst int numEsclavos = 4;\r\nint ultimoRecibidoPorEsclavo[5] = {0, -1, -1, -1, -1};  \/\/ \u00cdndice 1-4\r\nunsigned long lastReceiveTime[5] = {0, 0, 0, 0, 0};\r\nbool esclavoConectado[5] = {false, false, false, false, false};\r\n\r\n\/\/ Variables para botones del maestro\r\nint ultimoEstadoBotones[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};\r\nunsigned long lastDebounceTime[6] = {0, 0, 0, 0, 0, 0};\r\nint ultimoEnvioMaestro = -1;\r\n\r\n\/\/ Variables generales\r\nint ultimoValorMostrado = -1;\r\nunsigned long lastHeartbeatTime = 0;\r\nunsigned long lastLcdUpdate = 0;\r\nint ultimoBotonGlobal = -1;\r\nint ultimoEsclavoGlobal = -1;\r\n\r\n\/\/ Buffer para comunicaci\u00f3n\r\nString incomingData = \"\";\r\n\r\n\/\/ Patrones de segmentos corregidos (c\u00e1todo com\u00fan)\r\nbyte digitPatterns[] = {\r\n  0b11111100, \/\/ 0\r\n  0b01100000, \/\/ 1\r\n  0b11011010, \/\/ 2\r\n  0b11110010, \/\/ 3\r\n  0b01100110, \/\/ 4\r\n  0b10110110, \/\/ 5\r\n  0b10111110, \/\/ 6\r\n  0b11100000, \/\/ 7\r\n  0b11111110, \/\/ 8\r\n  0b11110110  \/\/ 9\r\n};\r\n\r\nvoid setup() {\r\n  \/\/ Inicializar RS485\r\n  Serial.begin(19200);\r\n\r\n  \/\/ Inicializar LCD\r\n  lcd.init();\r\n  lcd.backlight();\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar 74HC595\r\n  pinMode(DS_PIN, OUTPUT);\r\n  pinMode(SHCP_PIN, OUTPUT);\r\n  pinMode(STCP_PIN, OUTPUT);\r\n\r\n  \/\/ Configurar botones del maestro\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    pinMode(botones[i], INPUT_PULLUP);\r\n  }\r\n\r\n  \/\/ Pantalla de inicio\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"=== MAESTRO ===\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Con Botones\");\r\n  delay(2000);\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar LCD\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Ultimo: E   B\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"E0:? E1:? E2:? E3:?\");\r\n\r\n  \/\/ Mostrar 0 en display\r\n  mostrarNumero(0);\r\n  delay(500);\r\n  mostrarNumero(8);\r\n  delay(500);\r\n  mostrarNumero(0);\r\n\r\n  \/\/ Anunciar inicio\r\n  Serial.println(\"MASTER_READY\");\r\n}\r\n\r\nvoid loop() {\r\n  \/\/ ========================================\r\n  \/\/ 1. LEER BOTONES DEL PROPIO MAESTRO\r\n  \/\/ ========================================\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    int lectura = digitalRead(botones[i]);\r\n\r\n    if (lectura == LOW &amp;&amp; ultimoEstadoBotones[i] == HIGH) {\r\n      if (millis() - lastDebounceTime[i] &gt; 50) {\r\n        lastDebounceTime[i] = millis();\r\n\r\n        int numeroBoton = i + 1;\r\n\r\n        \/\/ Actualizar variable local\r\n        ultimoEnvioMaestro = numeroBoton;\r\n        ultimoBotonGlobal = numeroBoton;\r\n        ultimoEsclavoGlobal = MASTER_ID;\r\n\r\n        \/\/ Mostrar en display 7 segmentos del maestro\r\n        mostrarNumero(numeroBoton);\r\n        ultimoValorMostrado = numeroBoton;\r\n\r\n        \/\/ Actualizar LCD del maestro\r\n        actualizarLCD();\r\n\r\n        \/\/ ========================================\r\n        \/\/ RETRANSMITIR A TODOS LOS ESCLAVOS\r\n        \/\/ El maestro tambi\u00e9n usa el mismo formato\r\n        \/\/ ========================================\r\n        Serial.print(\"FROM_MASTER:\");\r\n        Serial.print(MASTER_ID);\r\n        Serial.print(\":BOTON:\");\r\n        Serial.println(numeroBoton);\r\n\r\n        delay(50);\r\n      }\r\n    }\r\n    ultimoEstadoBotones[i] = lectura;\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 2. RECIBIR DATOS DE LOS ESCLAVOS\r\n  \/\/ ========================================\r\n  while (Serial.available()) {\r\n    char c = Serial.read();\r\n\r\n    if (c == '\\n') {\r\n      incomingData.trim();\r\n\r\n      \/\/ Formato esperado: \"ID:BOTON:NUMERO\"  (ej: \"2:BOTON:3\")\r\n      if (incomingData.indexOf(\":BOTON:\") &gt; 0 &amp;&amp; !incomingData.startsWith(\"FROM_MASTER\")) {\r\n        int primerPunto = incomingData.indexOf(':');\r\n        int esclavoID = incomingData.substring(0, primerPunto).toInt();\r\n\r\n        int inicioBoton = primerPunto + 7;  \/\/ despu\u00e9s de \":BOTON:\"\r\n        int botonNumero = incomingData.substring(inicioBoton).toInt();\r\n\r\n        if (esclavoID &gt;= 1 &amp;&amp; esclavoID &lt;= 4 &amp;&amp; botonNumero &gt;= 1 &amp;&amp; botonNumero &lt;= 6) {\r\n          \/\/ Actualizar estado\r\n          lastReceiveTime[esclavoID] = millis();\r\n          esclavoConectado[esclavoID] = true;\r\n          ultimoRecibidoPorEsclavo[esclavoID] = botonNumero;\r\n          ultimoBotonGlobal = botonNumero;\r\n          ultimoEsclavoGlobal = esclavoID;\r\n\r\n          \/\/ Actualizar LCD del maestro\r\n          actualizarLCD();\r\n\r\n          \/\/ Mostrar en display 7 segmentos del maestro\r\n          mostrarNumero(botonNumero);\r\n          ultimoValorMostrado = botonNumero;\r\n\r\n          \/\/ ========================================\r\n          \/\/ RETRANSMITIR A TODOS LOS ESCLAVOS\r\n          \/\/ ========================================\r\n          Serial.print(\"FROM_MASTER:\");\r\n          Serial.print(esclavoID);\r\n          Serial.print(\":BOTON:\");\r\n          Serial.println(botonNumero);\r\n\r\n          delay(10);\r\n        }\r\n      }\r\n      else if (incomingData.startsWith(\"FROM_MASTER:\")) {\r\n        \/\/ Esto es un eco de lo que el propio maestro envi\u00f3\r\n        \/\/ No hacer nada para evitar bucles\r\n      }\r\n      else if (incomingData.startsWith(\"SLAVE_READY:\")) {\r\n        int esclavoID = incomingData.substring(12).toInt();\r\n        esclavoConectado[esclavoID] = true;\r\n        lastReceiveTime[esclavoID] = millis();\r\n        actualizarLCD();\r\n      }\r\n      else if (incomingData.startsWith(\"HEARTBEAT_SLAVE:\")) {\r\n        int esclavoID = incomingData.substring(17).toInt();\r\n        lastReceiveTime[esclavoID] = millis();\r\n        esclavoConectado[esclavoID] = true;\r\n        actualizarLCD();\r\n      }\r\n\r\n      incomingData = \"\";\r\n    }\r\n    else if (c != '\\r') {\r\n      incomingData += c;\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 3. VERIFICAR TIMEOUT DE ESCLAVOS\r\n  \/\/ ========================================\r\n  for (int i = 1; i &lt;= numEsclavos; i++) {\r\n    if (esclavoConectado[i] &amp;&amp; (millis() - lastReceiveTime[i]) &gt; 15000) {\r\n      esclavoConectado[i] = false;\r\n      ultimoRecibidoPorEsclavo[i] = -1;\r\n      actualizarLCD();\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 4. HEARTBEAT DEL MAESTRO (cada 30 seg)\r\n  \/\/ ========================================\r\n  if (millis() - lastHeartbeatTime &gt; 30000) {\r\n    lastHeartbeatTime = millis();\r\n    Serial.println(\"HEARTBEAT_MASTER\");\r\n  }\r\n\r\n  \/\/ Actualizar LCD peri\u00f3dicamente\r\n  if (millis() - lastLcdUpdate &gt; 500) {\r\n    lastLcdUpdate = millis();\r\n    actualizarLCD();\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ ACTUALIZAR LCD DEL MAESTRO\r\n\/\/ ========================================\r\nvoid actualizarLCD() {\r\n  \/\/ Primera l\u00ednea: \u00daltimo bot\u00f3n recibido (de cualquier origen)\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"Ultimo: E\");\r\n  if (ultimoEsclavoGlobal &gt;= 0) {\r\n    lcd.print(ultimoEsclavoGlobal);\r\n  } else {\r\n    lcd.print(\"-\");\r\n  }\r\n  lcd.print(\" B\");\r\n  if (ultimoBotonGlobal &gt; 0) {\r\n    lcd.print(ultimoBotonGlobal);\r\n    lcd.print(\"   \");\r\n  } else {\r\n    lcd.print(\"-   \");\r\n  }\r\n\r\n  \/\/ Segunda l\u00ednea: Estado de maestro (E0) y esclavos (E1-E3)\r\n  lcd.setCursor(0, 1);\r\n\r\n  \/\/ Maestro (E0) - mostrar \u00faltimo bot\u00f3n que envi\u00f3\r\n  lcd.print(\"E0:\");\r\n  if (ultimoEnvioMaestro &gt; 0) {\r\n    lcd.print(ultimoEnvioMaestro);\r\n  } else {\r\n    lcd.print(\"?\");\r\n  }\r\n\r\n  \/\/ Esclavo 1\r\n  lcd.print(\" E1:\");\r\n  if (esclavoConectado[1] &amp;&amp; ultimoRecibidoPorEsclavo[1] &gt; 0) {\r\n    lcd.print(ultimoRecibidoPorEsclavo[1]);\r\n  } else if (esclavoConectado[1]) {\r\n    lcd.print(\"?\");\r\n  } else {\r\n    lcd.print(\"X\");\r\n  }\r\n\r\n  \/\/ Esclavo 2\r\n  lcd.print(\" E2:\");\r\n  if (esclavoConectado[2] &amp;&amp; ultimoRecibidoPorEsclavo[2] &gt; 0) {\r\n    lcd.print(ultimoRecibidoPorEsclavo[2]);\r\n  } else if (esclavoConectado[2]) {\r\n    lcd.print(\"?\");\r\n  } else {\r\n    lcd.print(\"X\");\r\n  }\r\n\r\n  \/\/ Esclavo 3\r\n  lcd.print(\" E3:\");\r\n  if (esclavoConectado[3] &amp;&amp; ultimoRecibidoPorEsclavo[3] &gt; 0) {\r\n    lcd.print(ultimoRecibidoPorEsclavo[3]);\r\n  } else if (esclavoConectado[3]) {\r\n    lcd.print(\"?\");\r\n  } else {\r\n    lcd.print(\"X\");\r\n  }\r\n  lcd.print(\" \");\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ MOSTRAR N\u00daMERO EN 7 SEGMENTOS\r\n\/\/ ========================================\r\nvoid mostrarNumero(int numero) {\r\n  if (numero &lt; 0 || numero &gt; 9) numero = 0;\r\n\r\n  byte patron = digitPatterns[numero];\r\n\r\n  digitalWrite(STCP_PIN, LOW);\r\n  shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, patron);\r\n  digitalWrite(STCP_PIN, HIGH);\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO ESCLAVO<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ ============================================\r\n\/\/ ESCLAVO RS485 CON DIRECCI\u00d3N\r\n\/\/ ID: 1, 2, 3 o 4 (CAMBIAR SEG\u00daN CORRESPONDA)\r\n\/\/ LEE BOTONES D2-D7, ENV\u00cdA AL MAESTRO\r\n\/\/ RECIBE Y MUESTRA RETRANSMISIONES DEL MAESTRO\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\n\/\/ ========== CONFIGURACI\u00d3N \u00daNICA POR ESCLAVO ==========\r\n\/\/ CAMBIAR ESTE VALOR PARA CADA ESCLAVO: 1, 2, 3 o 4\r\n#define MI_ID 1  \/\/ &lt;--- CAMBIAR A 1, 2, 3 o 4\r\n\r\n\/\/ =====================================================\r\n\r\n\/\/ LCD I2C (probar 0x27 o 0x3F)\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n\/\/ Pines del 74HC595\r\n#define DS_PIN   11\r\n#define SHCP_PIN 13\r\n#define STCP_PIN 12\r\n\r\n\/\/ Pines de botones (D2 a D7)\r\nconst int botones[] = {2, 3, 4, 5, 6, 7};\r\nconst int numBotones = 6;\r\n\r\n\/\/ Variables\r\nint ultimoEstado[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};\r\nint ultimoValorMostrado = -1;\r\nunsigned long lastDebounceTime[6] = {0, 0, 0, 0, 0, 0};\r\nunsigned long lastHeartbeatTime = 0;\r\n\r\n\/\/ Buffer para comunicaci\u00f3n\r\nString incomingData = \"\";\r\n\r\n\/\/ Variables para LCD\r\nint ultimoEnvio = -1;\r\nint ultimaRecepcion = -1;\r\nint ultimoEsclavoOrigen = -1;\r\n\r\n\/\/ Patrones de segmentos corregidos (c\u00e1todo com\u00fan)\r\nbyte digitPatterns[] = {\r\n  0b11111100, \/\/ 0\r\n  0b01100000, \/\/ 1\r\n  0b11011010, \/\/ 2\r\n  0b11110010, \/\/ 3\r\n  0b01100110, \/\/ 4\r\n  0b10110110, \/\/ 5\r\n  0b10111110, \/\/ 6\r\n  0b11100000, \/\/ 7\r\n  0b11111110, \/\/ 8\r\n  0b11110110  \/\/ 9\r\n};\r\n\r\nvoid setup() {\r\n  \/\/ Inicializar RS485\r\n  Serial.begin(19200);\r\n\r\n  \/\/ Inicializar LCD\r\n  lcd.init();\r\n  lcd.backlight();\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar pines del 74HC595\r\n  pinMode(DS_PIN, OUTPUT);\r\n  pinMode(SHCP_PIN, OUTPUT);\r\n  pinMode(STCP_PIN, OUTPUT);\r\n\r\n  \/\/ Configurar botones\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    pinMode(botones[i], INPUT_PULLUP);\r\n  }\r\n\r\n  \/\/ Pantalla de inicio\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"=== ESCLAVO \");\r\n  lcd.print(MI_ID);\r\n  lcd.print(\" ===\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Iniciando...\");\r\n  delay(2000);\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar LCD\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"ID:\");\r\n  lcd.print(MI_ID);\r\n  lcd.print(\" Envio:   Rec:\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Ultimo: E  B\");\r\n\r\n  \/\/ Mostrar ID en display 7 segmentos\r\n  mostrarNumero(MI_ID);\r\n  delay(1000);\r\n  mostrarNumero(0);\r\n\r\n  \/\/ Anunciar presencia en el bus\r\n  Serial.print(\"SLAVE_READY:\");\r\n  Serial.println(MI_ID);\r\n}\r\n\r\nvoid loop() {\r\n  \/\/ ========================================\r\n  \/\/ 1. LEER BOTONES Y ENVIAR AL MAESTRO\r\n  \/\/ ========================================\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    int lectura = digitalRead(botones[i]);\r\n\r\n    if (lectura == LOW &amp;&amp; ultimoEstado[i] == HIGH) {\r\n      if (millis() - lastDebounceTime[i] &gt; 50) {\r\n        lastDebounceTime[i] = millis();\r\n\r\n        int numeroBoton = i + 1;\r\n\r\n        \/\/ Enviar al maestro con formato: ID:BOTON:NUMERO\r\n        Serial.print(MI_ID);\r\n        Serial.print(\":BOTON:\");\r\n        Serial.println(numeroBoton);\r\n\r\n        \/\/ Actualizar LCD con lo que se envi\u00f3\r\n        ultimoEnvio = numeroBoton;\r\n        actualizarLCD();\r\n\r\n        \/\/ Mostrar en display 7 segmentos local (lo que presion\u00f3)\r\n        mostrarNumero(numeroBoton);\r\n        ultimoValorMostrado = numeroBoton;\r\n\r\n        delay(50);\r\n      }\r\n    }\r\n    ultimoEstado[i] = lectura;\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 2. RECIBIR DATOS DEL MAESTRO\r\n  \/\/ ========================================\r\n  while (Serial.available()) {\r\n    char c = Serial.read();\r\n    if (c == '\\n') {\r\n      incomingData.trim();\r\n\r\n      \/\/ ========================================\r\n      \/\/ PROCESAR MENSAJES DEL MAESTRO\r\n      \/\/ ========================================\r\n\r\n      \/\/ Formato esperado: \"FROM_MASTER:ID:BOTON:NUMERO\"\r\n      \/\/ Ejemplo: \"FROM_MASTER:2:BOTON:5\"\r\n      if (incomingData.startsWith(\"FROM_MASTER:\")) {\r\n        \/\/ Extraer todo despu\u00e9s de \"FROM_MASTER:\"\r\n        String resto = incomingData.substring(12);\r\n\r\n        \/\/ Buscar el primer \":\" despu\u00e9s del ID del esclavo\r\n        int primerPunto = resto.indexOf(':');\r\n        int esclavoOrigen = resto.substring(0, primerPunto).toInt();\r\n\r\n        \/\/ Buscar \"BOTON:\" y extraer el n\u00famero\r\n        int posBoton = resto.indexOf(\"BOTON:\");\r\n        int numeroRecibido = resto.substring(posBoton + 6).toInt();\r\n\r\n        \/\/ ========================================\r\n        \/\/ MOSTRAR EN LCD DEL ESCLAVO\r\n        \/\/ ========================================\r\n        ultimaRecepcion = numeroRecibido;\r\n        ultimoEsclavoOrigen = esclavoOrigen;\r\n        actualizarLCD();\r\n\r\n        \/\/ ========================================\r\n        \/\/ MOSTRAR EN DISPLAY 7 SEGMENTOS\r\n        \/\/ ========================================\r\n        \/\/ \u00a1El n\u00famero que se muestra en todos los esclavos!\r\n        mostrarNumero(numeroRecibido);\r\n        ultimoValorMostrado = numeroRecibido;\r\n\r\n        \/\/ Peque\u00f1o parpadeo para indicar recepci\u00f3n\r\n        delay(50);\r\n      }\r\n      else if (incomingData.startsWith(\"HEARTBEAT_MASTER\")) {\r\n        \/\/ Heartbeat del maestro - solo actualizar LCD\r\n        actualizarLCD();\r\n      }\r\n      else if (incomingData.startsWith(\"MASTER_READY\")) {\r\n        \/\/ Maestro listo\r\n        lcd.setCursor(0, 1);\r\n        lcd.print(\"Maestro OK    \");\r\n        delay(500);\r\n        actualizarLCD();\r\n      }\r\n\r\n      incomingData = \"\";\r\n    } else if (c != '\\r') {\r\n      incomingData += c;\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 3. HEARTBEAT DEL ESCLAVO (cada 30 seg)\r\n  \/\/ ========================================\r\n  if (millis() - lastHeartbeatTime &gt; 30000) {\r\n    lastHeartbeatTime = millis();\r\n    Serial.print(\"HEARTBEAT_SLAVE:\");\r\n    Serial.println(MI_ID);\r\n  }\r\n\r\n  \/\/ Actualizar LCD peri\u00f3dicamente\r\n  static unsigned long lastLcdUpdate = 0;\r\n  if (millis() - lastLcdUpdate &gt; 500) {\r\n    lastLcdUpdate = millis();\r\n    actualizarLCD();\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ ACTUALIZAR LCD DEL ESCLAVO\r\n\/\/ ========================================\r\nvoid actualizarLCD() {\r\n  \/\/ Primera l\u00ednea: ID, Env\u00edo local, Recepci\u00f3n global\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"ID:\");\r\n  lcd.print(MI_ID);\r\n  lcd.print(\" Env:\");\r\n\r\n  if (ultimoEnvio &gt; 0) {\r\n    lcd.print(ultimoEnvio);\r\n    lcd.print(\" \");\r\n  } else {\r\n    lcd.print(\"- \");\r\n  }\r\n\r\n  lcd.print(\" Rec:\");\r\n  if (ultimaRecepcion &gt; 0) {\r\n    lcd.print(ultimaRecepcion);\r\n    lcd.print(\" \");\r\n  } else {\r\n    lcd.print(\"- \");\r\n  }\r\n\r\n  \/\/ Segunda l\u00ednea: \u00daltimo bot\u00f3n recibido de qu\u00e9 esclavo\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Ultimo: E\");\r\n\r\n  if (ultimoEsclavoOrigen &gt; 0) {\r\n    lcd.print(ultimoEsclavoOrigen);\r\n  } else {\r\n    lcd.print(\"-\");\r\n  }\r\n\r\n  lcd.print(\" B\");\r\n  if (ultimaRecepcion &gt; 0) {\r\n    lcd.print(ultimaRecepcion);\r\n    lcd.print(\"   \");\r\n  } else {\r\n    lcd.print(\"-   \");\r\n  }\r\n\r\n  \/\/ Mostrar estado de botones locales (al final)\r\n  lcd.setCursor(10, 1);\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    if (digitalRead(botones[i]) == LOW) {\r\n      lcd.print(i + 1);\r\n    } else {\r\n      lcd.print(\"-\");\r\n    }\r\n  }\r\n  lcd.print(\"  \");\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ MOSTRAR N\u00daMERO EN 7 SEGMENTOS\r\n\/\/ ========================================\r\nvoid mostrarNumero(int numero) {\r\n  if (numero &lt; 0 || numero &gt; 9) numero = 0;\r\n\r\n  byte patron = digitPatterns[numero];\r\n\r\n  digitalWrite(STCP_PIN, LOW);\r\n  shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, patron);\r\n  digitalWrite(STCP_PIN, HIGH);\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h6>EJERCICIO 4: Comunicaci\u00f3n bidireccional completa (P2P) (TODO MAESTRO)<\/h6>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<p><span style=\"color: #ff6600;\"><strong>CODIGO MAESTRO &#8211; ESCLAVO (mismo esclavo)<\/strong><\/span><\/p>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n\r\n\t<div class=\"wpb_text_column \">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ ============================================\r\n\/\/ SISTEMA P2P - COMUNICACI\u00d3N BIDIRECCIONAL COMPLETA\r\n\/\/ TODOS los dispositivos usan el MISMO c\u00f3digo\r\n\/\/ Solo cambiar MI_ID (0 para maestro, 1-4 para esclavos)\r\n\/\/ ============================================\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;LiquidCrystal_I2C.h&gt;\r\n\r\n\/\/ ========== CONFIGURACI\u00d3N \u00daNICA ==========\r\n\/\/ CAMBIAR ESTE VALOR EN CADA DISPOSITIVO:\r\n\/\/ 0 = Maestro (o nodo central)\r\n\/\/ 1, 2, 3, 4 = Esclavos\r\n#define MI_ID 4  \/\/ &lt;--- CAMBIAR SEG\u00daN DISPOSITIVO\r\n\r\n\/\/ IDs especiales\r\n#define ID_BROADCAST 255  \/\/ Enviar a todos\r\n#define ID_MAESTRO 0       \/\/ ID del nodo maestro\r\n\r\n\/\/ ==========================================\r\n\r\nLiquidCrystal_I2C lcd(0x27, 16, 2);\r\n\r\n#define DS_PIN   11\r\n#define SHCP_PIN 13\r\n#define STCP_PIN 12\r\n\r\n\/\/ Botones (D2-D7)\r\nconst int botones[] = {2, 3, 4, 5, 6, 7};\r\nconst int numBotones = 6;\r\n\r\n\/\/ Variables de botones\r\nint ultimoEstado[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};\r\nint ultimoValorMostrado = -1;\r\nunsigned long lastDebounceTime[6] = {0, 0, 0, 0, 0, 0};\r\nunsigned long lastHeartbeatTime = 0;\r\n\r\n\/\/ Buffer para comunicaci\u00f3n\r\nString incomingData = \"\";\r\n\r\n\/\/ Variables para LCD\r\nint ultimoEnvio = -1;\r\nint ultimoDestino = -1;\r\nint ultimaRecepcion = -1;\r\nint ultimoOrigen = -1;\r\n\r\n\/\/ Variables para control de colisiones (CSMA\/CD simple)\r\nunsigned long lastTransmissionTime = 0;\r\nconst unsigned long MIN_GAP_BETWEEN_MSG = 50;  \/\/ 50ms entre mensajes\r\nbool waitingForClearBus = false;\r\nunsigned long waitStartTime = 0;\r\n\r\n\/\/ Patrones de segmentos\r\nbyte digitPatterns[] = {\r\n  0b11111100, \/\/ 0\r\n  0b01100000, \/\/ 1\r\n  0b11011010, \/\/ 2\r\n  0b11110010, \/\/ 3\r\n  0b01100110, \/\/ 4\r\n  0b10110110, \/\/ 5\r\n  0b10111110, \/\/ 6\r\n  0b11100000, \/\/ 7\r\n  0b11111110, \/\/ 8\r\n  0b11110110  \/\/ 9\r\n};\r\n\r\n\/\/ ========================================\r\n\/\/ ENVIAR MENSAJE A OTRO DISPOSITIVO\r\n\/\/ ========================================\r\nbool enviarMensaje(int destino, String tipo, String dato) {\r\n  \/\/ Verificar tiempo m\u00ednimo entre mensajes\r\n  if (millis() - lastTransmissionTime &lt; MIN_GAP_BETWEEN_MSG) {\r\n    waitingForClearBus = true;\r\n    waitStartTime = millis();\r\n    return false;\r\n  }\r\n\r\n  String mensaje = \"DE:\" + String(destino) + \":\" + String(MI_ID) + \":\" + tipo + \":\" + dato;\r\n  Serial.println(mensaje);\r\n  lastTransmissionTime = millis();\r\n  waitingForClearBus = false;\r\n\r\n  \/\/ Actualizar LCD con lo que se envi\u00f3\r\n  ultimoEnvio = dato.toInt();\r\n  ultimoDestino = destino;\r\n  actualizarLCD();\r\n\r\n  return true;\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ PROCESAR MENSAJE RECIBIDO\r\n\/\/ ========================================\r\nvoid procesarMensaje(String mensaje) {\r\n  \/\/ Formato: \"DE:DESTINO:ORIGEN:TIPO:DATO\"\r\n  if (!mensaje.startsWith(\"DE:\")) return;\r\n\r\n  String resto = mensaje.substring(3);  \/\/ Quitar \"DE:\"\r\n\r\n  int primerPunto = resto.indexOf(':');\r\n  int destino = resto.substring(0, primerPunto).toInt();\r\n\r\n  String resto2 = resto.substring(primerPunto + 1);\r\n  int segundoPunto = resto2.indexOf(':');\r\n  int origen = resto2.substring(0, segundoPunto).toInt();\r\n\r\n  String resto3 = resto2.substring(segundoPunto + 1);\r\n  int tercerPunto = resto3.indexOf(':');\r\n  String tipo = resto3.substring(0, tercerPunto);\r\n\r\n  String dato = resto3.substring(tercerPunto + 1);\r\n\r\n  \/\/ Verificar si el mensaje es para m\u00ed o es broadcast\r\n  if (destino == MI_ID || destino == ID_BROADCAST) {\r\n    \/\/ Actualizar LCD con lo que se recibi\u00f3\r\n    ultimaRecepcion = dato.toInt();\r\n    ultimoOrigen = origen;\r\n    actualizarLCD();\r\n\r\n    \/\/ Mostrar en display 7 segmentos\r\n    int numero = dato.toInt();\r\n    if (numero &gt;= 0 &amp;&amp; numero &lt;= 9) {\r\n      mostrarNumero(numero);\r\n      ultimoValorMostrado = numero;\r\n    }\r\n\r\n    \/\/ Mostrar en LCD el mensaje recibido (parpadeo r\u00e1pido)\r\n    lcd.setCursor(12, 1);\r\n    lcd.print(\"RX\");\r\n    delay(100);\r\n    lcd.setCursor(12, 1);\r\n    lcd.print(\"  \");\r\n\r\n    \/\/ Si es un comando especial, procesarlo\r\n    if (tipo == \"CMD\") {\r\n      procesarComando(origen, dato);\r\n    }\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ PROCESAR COMANDOS ESPECIALES\r\n\/\/ ========================================\r\nvoid procesarComando(int origen, String comando) {\r\n  if (comando == \"HEARTBEAT\") {\r\n    \/\/ Responder al heartbeat\r\n    if (MI_ID != ID_MAESTRO) {\r\n      enviarMensaje(origen, \"RSP\", \"ALIVE\");\r\n    }\r\n  }\r\n  else if (comando == \"BLINK\") {\r\n    \/\/ Parpadear display 7 segmentos\r\n    for (int i = 0; i &lt; 3; i++) {\r\n      mostrarNumero(8);\r\n      delay(200);\r\n      mostrarNumero(ultimoValorMostrado &gt; 0 ? ultimoValorMostrado : 0);\r\n      delay(200);\r\n    }\r\n  }\r\n  else if (comando.startsWith(\"SHOW:\")) {\r\n    int numero = comando.substring(5).toInt();\r\n    mostrarNumero(numero);\r\n    ultimoValorMostrado = numero;\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ ESCANEAR BUS Y RETRANSMITIR (OPCIONAL)\r\n\/\/ ========================================\r\nvoid escanearBus() {\r\n  \/\/ El maestro puede hacer ping a todos los dispositivos\r\n  static unsigned long lastScan = 0;\r\n  if (MI_ID == ID_MAESTRO &amp;&amp; (millis() - lastScan) &gt; 60000) {\r\n    lastScan = millis();\r\n    enviarMensaje(ID_BROADCAST, \"CMD\", \"HEARTBEAT\");\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ SETUP\r\n\/\/ ========================================\r\nvoid setup() {\r\n  Serial.begin(19200);\r\n\r\n  lcd.init();\r\n  lcd.backlight();\r\n  lcd.clear();\r\n\r\n  pinMode(DS_PIN, OUTPUT);\r\n  pinMode(SHCP_PIN, OUTPUT);\r\n  pinMode(STCP_PIN, OUTPUT);\r\n\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    pinMode(botones[i], INPUT_PULLUP);\r\n  }\r\n\r\n  \/\/ Pantalla de inicio\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"=== P2P SYS ===\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"ID:\");\r\n  lcd.print(MI_ID);\r\n  lcd.print(\" Listo\");\r\n  delay(2000);\r\n  lcd.clear();\r\n\r\n  \/\/ Configurar LCD\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"ID:\");\r\n  lcd.print(MI_ID);\r\n  lcd.print(\" Envio:&gt;   Rec:&lt;\");\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Ultimo: E B\");\r\n\r\n  mostrarNumero(MI_ID);\r\n  delay(1000);\r\n  mostrarNumero(0);\r\n\r\n  \/\/ Anunciar presencia en el bus (broadcast)\r\n  delay(100);  \/\/ Peque\u00f1a pausa para evitar colisiones iniciales\r\n  enviarMensaje(ID_BROADCAST, \"STATUS\", \"ONLINE\");\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ LOOP PRINCIPAL\r\n\/\/ ========================================\r\nvoid loop() {\r\n  \/\/ ========================================\r\n  \/\/ 1. LEER BOTONES Y ENVIAR\r\n  \/\/ ========================================\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    int lectura = digitalRead(botones[i]);\r\n\r\n    if (lectura == LOW &amp;&amp; ultimoEstado[i] == HIGH) {\r\n      if (millis() - lastDebounceTime[i] &gt; 50) {\r\n        lastDebounceTime[i] = millis();\r\n\r\n        int numeroBoton = i + 1;\r\n\r\n        \/\/ En P2P, el usuario elige el destino (por ahora, broadcast)\r\n        \/\/ Podr\u00edas agregar un selector de destino con botones extra\r\n        enviarMensaje(ID_BROADCAST, \"BOTON\", String(numeroBoton));\r\n\r\n        \/\/ Tambi\u00e9n mostrar localmente\r\n        mostrarNumero(numeroBoton);\r\n        ultimoValorMostrado = numeroBoton;\r\n\r\n        delay(50);\r\n      }\r\n    }\r\n    ultimoEstado[i] = lectura;\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 2. RECIBIR MENSAJES\r\n  \/\/ ========================================\r\n  while (Serial.available()) {\r\n    char c = Serial.read();\r\n    if (c == '\\n') {\r\n      incomingData.trim();\r\n      if (incomingData.length() &gt; 0) {\r\n        procesarMensaje(incomingData);\r\n      }\r\n      incomingData = \"\";\r\n    } else if (c != '\\r') {\r\n      incomingData += c;\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 3. ESCANEAR BUS (solo maestro)\r\n  \/\/ ========================================\r\n  escanearBus();\r\n\r\n  \/\/ ========================================\r\n  \/\/ 4. HEARTBEAT\r\n  \/\/ ========================================\r\n  if (millis() - lastHeartbeatTime &gt; 30000) {\r\n    lastHeartbeatTime = millis();\r\n    \/\/ Anunciar que sigo vivo\r\n    enviarMensaje(ID_BROADCAST, \"STATUS\", \"ALIVE\");\r\n  }\r\n\r\n  \/\/ ========================================\r\n  \/\/ 5. ACTUALIZAR LCD\r\n  \/\/ ========================================\r\n  static unsigned long lastLcdUpdate = 0;\r\n  if (millis() - lastLcdUpdate &gt; 500) {\r\n    lastLcdUpdate = millis();\r\n    actualizarLCD();\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ ACTUALIZAR LCD\r\n\/\/ ========================================\r\nvoid actualizarLCD() {\r\n  \/\/ Primera l\u00ednea: ID y env\u00edo\r\n  lcd.setCursor(0, 0);\r\n  lcd.print(\"ID:\");\r\n  lcd.print(MI_ID);\r\n  lcd.print(\" Env:\");\r\n\r\n  if (ultimoEnvio &gt; 0) {\r\n    lcd.print(ultimoEnvio);\r\n    lcd.print(\"&gt;\");\r\n  } else {\r\n    lcd.print(\"-&gt;\");\r\n  }\r\n\r\n  if (ultimoDestino &gt;= 0) {\r\n    if (ultimoDestino == ID_BROADCAST) {\r\n      lcd.print(\"T\");\r\n    } else {\r\n      lcd.print(ultimoDestino);\r\n    }\r\n  } else {\r\n    lcd.print(\"-\");\r\n  }\r\n\r\n  lcd.print(\"  Rec:&lt;\");\r\n  if (ultimaRecepcion &gt; 0) {\r\n    lcd.print(ultimaRecepcion);\r\n  } else {\r\n    lcd.print(\"-\");\r\n  }\r\n\r\n  \/\/ Segunda l\u00ednea: origen del \u00faltimo mensaje\r\n  lcd.setCursor(0, 1);\r\n  lcd.print(\"Ultimo: E\");\r\n  if (ultimoOrigen &gt;= 0) {\r\n    lcd.print(ultimoOrigen);\r\n  } else {\r\n    lcd.print(\"-\");\r\n  }\r\n  lcd.print(\" B\");\r\n  if (ultimaRecepcion &gt; 0) {\r\n    lcd.print(ultimaRecepcion);\r\n    lcd.print(\"   \");\r\n  } else {\r\n    lcd.print(\"-   \");\r\n  }\r\n\r\n  \/\/ Estado de botones locales\r\n  lcd.setCursor(10, 1);\r\n  for (int i = 0; i &lt; numBotones; i++) {\r\n    if (digitalRead(botones[i]) == LOW) {\r\n      lcd.print(i + 1);\r\n    } else {\r\n      lcd.print(\"-\");\r\n    }\r\n  }\r\n  lcd.print(\"  \");\r\n\r\n  \/\/ Indicador de bus ocupado\r\n  if (waitingForClearBus) {\r\n    lcd.setCursor(15, 0);\r\n    lcd.print(\"B\");\r\n  } else {\r\n    lcd.setCursor(15, 0);\r\n    lcd.print(\" \");\r\n  }\r\n}\r\n\r\n\/\/ ========================================\r\n\/\/ MOSTRAR N\u00daMERO EN 7 SEGMENTOS\r\n\/\/ ========================================\r\nvoid mostrarNumero(int numero) {\r\n  if (numero &lt; 0 || numero &gt; 9) numero = 0;\r\n  byte patron = digitPatterns[numero];\r\n  digitalWrite(STCP_PIN, LOW);\r\n  shiftOut(DS_PIN, SHCP_PIN, LSBFIRST, patron);\r\n  digitalWrite(STCP_PIN, HIGH);\r\n}<\/pre>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<\/div><\/div><\/div><\/div><\/div><\/section><section class=\"l-section wpb_row height_medium\"><div class=\"l-section-h i-cf\"><div class=\"g-cols vc_row type_default valign_top\"><div class=\"vc_col-sm-2 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\"><\/div><\/div><\/div><div class=\"vc_col-sm-10 wpb_column vc_column_container\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\r\n\t<div class=\"wpb_text_column  vc_custom_1779598685586\">\r\n\t\t<div class=\"wpb_wrapper\">\r\n\t\t\t<h5><span id=\"ESPECIFICACIONES_TECNICAS\">VIDEO<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-265 alignnone\" src=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png\" alt=\"\" width=\"1080\" height=\"36\" srcset=\"https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-300x10.png 300w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-1024x33.png 1024w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores-768x25.png 768w, https:\/\/www.electroallweb.com\/wp-content\/uploads\/2019\/11\/linea-electroall-de-colores.png 1624w\" sizes=\"(max-width: 1080px) 100vw, 1080px\" \/><\/span><\/h5>\n\r\n\t\t<\/div>\r\n\t<\/div>\r\n<div class=\"w-video ratio_16x9\"><div class=\"w-video-h\"><iframe loading=\"lazy\" width=\"420\" height=\"315\" src=\"\/\/www.youtube.com\/embed\/J2WHK_ZVrQo\" allowfullscreen><\/iframe><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/section>\n","protected":false},"excerpt":{"rendered":"INTRODUCCI\u00d3N La comunicaci\u00f3n RS485 es un est\u00e1ndar de transmisi\u00f3n serial ampliamente utilizado en sistemas industriales y electr\u00f3nicos debido a su alta estabilidad y resistencia al ruido el\u00e9ctrico. Funciona mediante comunicaci\u00f3n diferencial usando dos l\u00edneas llamadas A y B, donde la informaci\u00f3n se transmite a trav\u00e9s de la diferencia de voltaje entre ambas se\u00f1ales. Esto permite...","protected":false},"author":2,"featured_media":3356,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[1],"tags":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/posts\/3342"}],"collection":[{"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/comments?post=3342"}],"version-history":[{"count":12,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/posts\/3342\/revisions"}],"predecessor-version":[{"id":3357,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/posts\/3342\/revisions\/3357"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/media\/3356"}],"wp:attachment":[{"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/media?parent=3342"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/categories?post=3342"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.electroallweb.com\/index.php\/wp-json\/wp\/v2\/tags?post=3342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}