¿Qué pasa con tus mensajes cuando se cae la red celular después de un temblor o durante un corte de luz largo? En Chile esa pregunta no es teórica. Este proyecto arma un tablero de mensajes que no depende de internet ni de la red celular: escucha una red mesh LoRa en 915 MHz y muestra lo que llega en una pantalla e-ink tricolor de 4,2". Funciona con cualquier nodo Meshtastic que esté al alcance, que no necesita suscripción ni chip SIM.

Al final de esta guía vas a entender cómo un ESP32-S3 con un radio RFM95W decodifica paquetes Meshtastic sin transmitir nada, por qué una pantalla e-ink puede durar más de un día con una batería de 2000 mAh y qué tienes que ajustar para que el tablero escuche la red mesh de tu ciudad.

Tablero MeshFruit sobre un escritorio mostrando mensajes recibidos por la red mesh

El concepto: un receptor pasivo de la red mesh

Meshtastic es un firmware abierto que convierte radios LoRa baratos en una red de mensajería: cada nodo retransmite los paquetes que escucha y así el mensaje "salta" de nodo en nodo hasta cubrir varios kilómetros. MeshFruit se conecta a esa red de una forma particular: solo recibe. Nunca transmite, así que no aparece en la lista de nodos de nadie ni gasta energía en el radio emitiendo.

Tiene dos ventajas prácticas:

  • Consumo mínimo: en LoRa, transmitir es lo que más corriente gasta. Un receptor puro puede quedarse escuchando todo el día con una LiPo chica.
  • Cero configuración de red: no tienes que registrar el nodo ni coordinar con los operadores de la mesh local. Si el canal público usa la clave por defecto, el tablero descifra los mensajes directamente.

La decodificación la hace Adafruit CircuitPython MeshFruit, una librería escrita para este proyecto que entiende el formato de paquetes compatible con Meshtastic.

Tres vistas en una pantalla que no gasta energía

Un botón en la parte superior cambia entre tres pantallas:

  1. Clima: pronóstico de tres días, hora de salida y puesta de sol y la fase lunar actual. Esta vista sí usa WiFi para bajar el pronóstico cuando hay conexión.
  2. Mensajes: lo que ha llegado por la mesh. El mensaje más nuevo aparece en rojo y en negrita para que se lea desde el otro lado de la pieza. Los anteriores bajan en negro.
  3. Nodos: todas las radios que el tablero ha escuchado, ordenadas por intensidad de señal (RSSI).

Tablero MeshFruit terminado con su pantalla e-ink

En la franja superior también se ven el CO2, la temperatura y la humedad que lee un sensor STCC4 + SHT41 conectado por STEMMA QT, además del nivel de batería y una estimación de autonomía.

¿Por qué e-ink y no un OLED o TFT? Una pantalla de tinta electrónica mantiene la imagen sin consumir nada. Solo gasta corriente mientras redibuja. Un OLED encendido todo el día se comería la batería en horas. El costo es que el panel tricolor de 4,2" no puede refrescarse más de una vez cada 180 segundos, y cada refresco toma unos 20 segundos. Por eso el código usa el NeoPixel de la Feather para dar la respuesta rápida (un parpadeo al llegar un mensaje o al apretar el botón) que la pantalla no puede dar.

Hardware: conexiones

La pantalla se maneja a través del eInk Feather Friend, que va montado sobre la Feather ESP32-S3. El radio LoRa comparte el mismo bus SPI. Estas son las conexiones del RFM95W:

RFM95W Feather ESP32-S3
VIN 3V
GND GND
SCK SCK
MOSI MOSI
MISO MISO
CS 11
RST 12
G0 A5

Diagrama de conexiones del proyecto hecho en Fritzing

Detalles que conviene tener en cuenta:

  • El botón va entre el pin A0 y GND. El código activa el pull up interno, así que no necesitas resistencia externa.
  • El sensor se conecta al puerto STEMMA QT con un cable JST SH de 4 pines, sin soldar.
  • Pines ocupados: SCK, MOSI y MISO se comparten con el eInk Feather Friend, que además usa D5, D6, D9 y D10. No los uses para otra cosa.

Por qué el orden de inicialización importa

Un detalle del código explica un error que desconcierta a mucha gente: el bus I2C del STEMMA se inicializa antes que todo lo demás. board.STEMMA_I2C() controla el pin I2C_POWER. Si otro periférico lo toma primero, el bus queda sin resistencias pull up y el error aparece como un problema de cableado aunque en realidad sea de alimentación. Si el sensor no responde, revisa ese orden antes de desarmar las conexiones.

Además, el código fija en alto los chip select de la SRAM y de la microSD del Feather Friend (D6 y D5) para que no ensucien el bus SPI que comparten con la pantalla y el radio.

Software: CircuitPython y el bundle del proyecto

  1. Instala CircuitPython en la Feather ESP32-S3.
  2. Descarga el Project Bundle desde la guía original (enlace en Recursos). Trae el código, las librerías y la carpeta de fuentes.
  3. Conecta la Feather por USB. Aparece la unidad CIRCUITPY.
  4. Copia todos los archivos del bundle a CIRCUITPY.

Contenido de la unidad CIRCUITPY con la carpeta de fuentes bitmap del proyecto

Para la vista de clima, define tu red WiFi y tu ubicación en settings.toml con las variables CIRCUITPY_WIFI_SSID, CIRCUITPY_WIFI_PASSWORD, LATITUDE y LONGITUDE. El código trae USE_FAHRENHEIT = True. En Chile cámbialo a False para ver grados Celsius.

La parte crítica para Chile: la frecuencia del radio

Esta es la sección de configuración del radio en el código original:

Python
# --- radio ------------------------------------------------------------

# US 915MHz band, 250kHz slots. Slot N sits at 902.125 + (N - 1) * 0.25
# MHz, and slot 20 is the default for the public channel. Outside the
# US this has to match whatever the nodes around you are using: run
# "meshtastic --info" on a node to read its operating frequency.
FREQUENCY = 906.875
CHANNEL_HASH = 0x08
SYNC_WORD_REG = 0x39
MESH_SYNC_WORD = 0x2B
RADIO_IRQ_PIN = board.A5

Y así se configura el RFM95W para que hable el mismo "idioma" de modulación que Meshtastic:

Python
rfm9x = adafruit_rfm9x.RFM9x(
    spi,
    digitalio.DigitalInOut(board.D11),
    digitalio.DigitalInOut(board.D12),
    FREQUENCY,
)
rfm9x.signal_bandwidth = 250000
rfm9x.spreading_factor = 11
rfm9x.coding_rate = 5
rfm9x.preamble_length = 16
rfm9x.enable_crc = True
rfm9x._write_u8(SYNC_WORD_REG, MESH_SYNC_WORD)  # pylint: disable=protected-access

Qué significa cada parámetro:

  • Ancho de banda de 250 kHz + factor de dispersión 11: corresponde al preset LongFast de Meshtastic. Un SF alto hace que cada símbolo dure más en el aire, lo que da más alcance y más inmunidad al ruido, pero menos velocidad. Por eso los mensajes son cortos.
  • Sync word 0x2B: es la "contraseña de capa física" de Meshtastic. Un radio LoRa con otra sync word ignora los paquetes aunque esté en la misma frecuencia. Por eso el código escribe ese registro directamente.
  • Frecuencia: el código usa 906.875 MHz, el slot 20 de la banda de EE.UU. Chile también opera LoRa en la banda de 915 MHz (plan AU915), pero lo que manda es la frecuencia que usan los nodos de tu zona. Como dice el propio comentario del código, corre meshtastic --info en un nodo cercano y copia su frecuencia de operación en FREQUENCY. Si tu tablero no recibe nada, lo más probable es que esté en otro slot.

Pruebas y uso

  1. Enciende el tablero. La pantalla hace un primer dibujo, que tarda unos 20 segundos.
  2. Desde un celular con la app Meshtastic conectada a un nodo propio, envía un mensaje al canal público.
  3. El NeoPixel parpadea en verde cuando llega el paquete. Si la pantalla está en su ventana de espera de 180 s, el LED queda en naranja indicando que hay un redibujo en cola.
  4. Presiona el botón para pasar a la vista de nodos y ver el RSSI de cada radio. Te sirve para saber qué tan lejos llega la mesh desde tu casa.

Si no llegan mensajes:

  • Frecuencia distinta: revisa el slot con meshtastic --info.
  • Canal privado: la librería usa por defecto la clave del canal público. Para uno privado, pasa psk= al crear Meshtastic_Compatible().
  • Antena: un RFM95W sin antena apenas escucha. La guía original suelda una antena de resorte. Para más alcance, una antena de cuarto de onda para 915 MHz mide unos 7,8 cm de alambre.

Carcasa impresa en 3D y armado

La guía original trae archivos 3MF listos para imprimir en PLA y el ensamble completo en Fusion 360, que se puede exportar a STEP o STL si quieres modificarlo.

Piezas de la carcasa preparadas en el slicer para impresión 3D

Ensamble del tablero modelado en Fusion 360

Para el armado, corta cables de silicona de unos 50 mm para unir el radio LoRa y el botón con la Feather, y suelda la antena de resorte al módulo LoRa. La carcasa usa tornillos M2.5x6 mm e imanes para montarla en una superficie metálica.

Etapa de armado del tablero: cableado del radio LoRa y el botón hacia la Feather

Variantes y mejoras

  • Nodo solar autónomo: agrega un panel solar de 6 V con un cargador de LiPo (tipo TP4056 o un cargador solar dedicado) y el tablero queda funcionando indefinidamente en una ventana. Con e-ink y radio en modo solo recepción, un panel chico alcanza de sobra.
  • Convertirlo en nodo que transmite: si quieres además enviar mensajes, lo más práctico es sumar un nodo Meshtastic completo (por ejemplo un ESP32 con LoRa SX1262 y firmware Meshtastic) y dejar MeshFruit como pantalla de lectura para la casa.
  • Alertas de CO2: el STCC4 ya mide CO2. Puedes agregar un buzzer activo que suene cuando pase de 1.000 ppm, algo útil en piezas cerradas en invierno con estufa.

Personalización para Chile

Esta corrida no pudo consultar el catálogo en línea de MechatronicStore, así que no vinculamos productos específicos con SKU ni precio. Revisa el buscador de la tienda para estos componentes:

  • Placa ESP32-S3 en formato de desarrollo. La Feather ESP32-S3 de Adafruit es la del tutorial. Otra placa ESP32-S3 con PSRAM también sirve, pero tendrías que reasignar pines y no tendrás el Feather Friend enchufable.
  • Módulo LoRa RFM95W / SX1276 de 915 MHz. Revisa que sea la versión de 915 MHz, no la de 433 ni la de 868.
  • Pantalla e-ink tricolor de 4,2" (400x300). Tiene que ser e-ink, porque un OLED o TFT no reemplaza el bajo consumo del proyecto.
  • Sensor SHT41 (temperatura y humedad) y, si lo encuentras, un sensor de CO2 I2C.
  • Batería LiPo 3,7 V 2000 mAh con conector JST PH.
  • Pulsador táctil y cables JST SH (STEMMA QT / Qwiic).

Sobre la banda: Chile opera LoRa en 915 MHz, igual que el tutorial, así que el hardware para EE.UU. te sirve sin cambios. Solo tienes que ajustar el slot de frecuencia al de la mesh local.

Recursos

Versión chilena basada en la guía original, con componentes en stock local.