Hablando por Meshtastic en Emacs

Me gustaría enseñarte cómo conectar un dispositivo Meshtastic por USB directamente a Emacs a partir de un paquete que he desarrollado para mi llamado meshtastic.el.

Cómo funciona

meshtastic.el lanza un subproceso Python que habla con el dispositivo por serial. Los mensajes llegan como líneas JSON al filtro de proceso de Emacs.

flowchart LR
    D["📻 Dispositivo\nMeshtastic"]:::device
    B["🐍 meshtastic-bridge.py\n(subproceso Python)"]:::bridge
    E["meshtastic.el\n(Emacs)"]:::emacs

    D <-->|"USB serial"| B
    B <-->|"JSON\nstdin / stdout"| E

    classDef device fill:#37474F,stroke:#263238,stroke-width:2px,color:#fff
    classDef bridge fill:#00897B,stroke:#00695C,stroke-width:2px,color:#fff
    classDef emacs fill:#7B1FA2,stroke:#4A148C,stroke-width:2px,color:#fff

Se muestran en buffers de chat al estilo ERC.

Instalación

Lo primero que debes hacer es instalar la biblioteca Python de Meshtastic.

pip install meshtastic

A continuación, instalar mi paquete. Está disponible en MELPA.

M-x package-install RET meshtastic RET

En caso contrario puedes usar use-package y :vc que son nativos de Emacs.

(use-package meshtastic
  :vc (:url "https://git.andros.dev/andros/meshtastic.el"
       :rev :newest))

Configuración

Linux

Encuentra el puerto con:

ls /dev/ttyUSB* /dev/ttyACM*
(setq meshtastic-serial-port "/dev/ttyUSB0")

Si hay error de permisos, añade tu usuario al grupo dialout:

sudo usermod -aG dialout $USER

macOS

Los puertos en macOS usan el esquema cu.usbserial-*:

ls /dev/cu.usbserial-*
(setq meshtastic-serial-port "/dev/cu.usbserial-0001")

Windows

(setq meshtastic-serial-port "COM3")
(setq meshtastic-python-executable "python")

El número de puerto aparece en el Administrador de dispositivos, bajo "Puertos (COM y LPT)".

Uso

Ya con todo listo, puedes ejecutar M-x meshtastic. El puente arranca automáticamente y la pantalla de bienvenida muestra el estado de la conexión:

  Meshtastic
  ======================================

  Connection
  Port:      /dev/ttyUSB0
  Status:    Connected
  Node:      Hilltop Relay (!a1b2c3d4)

  Statistics
  Nodes:     12
  Channels:  2

  --------------------------------------

  [c] Channels          [n] Nodes
  [g] Refresh           [q] Quit

  --------------------------------------

Mientras conecta, el estado muestra Connecting.... Al establecer la conexión cambia a Connected y las estadísticas de nodos y canales aparecen sin necesidad de refrescar manualmente.

Lista de canales

Pulsa c para ver los canales disponibles:

  ID  Name          Role
  0   LongFast      Primary
  1   HikingGroup   Secondary

Pulsa RET en cualquier canal para abrir su chat, o usa las teclas 0-7 directamente.

Lista de nodos

Pulsa n para ver todos los nodos de la malla:

  Hops  Name                           Node ID         Last heard  Battery
  0     🟢 Hilltop Relay               !a1b2c3d4       now         85%
  1     🟢 Solar Node 7                !d4e5f6a7       12m         -
  2     🟢 BaseStation K9              !b8c9d0e1       5m          62%
  3     ⚫ Mountain Peak               !f2a3b4c5       1h          -

La lista se ordena por saltos. El indicador 🟢 significa que el nodo ha sido escuchado en los últimos 15 minutos. La columna Battery muestra el nivel de batería cuando el nodo ha enviado telemetría; - si todavía no hay datos.

La lista se actualiza automáticamente cuando los nodos intercambian información en la malla, sin necesidad de pulsar g.

Chat

Pulsa RET en un canal o nodo para abrir el buffer de chat:

[08:15] <Hilltop Relay> Good morning mesh!
[08:20] <BaseStation K9> Morning! Signal is great today
[08:21] <Solar Node 7> Copy that, 3 hops from here
[09:05] <BaseStation K9> Confirmed ✓
#LongFast> _

Escribe el mensaje tras el prompt y pulsa RET para enviar. Los mensajes propios muestran · mientras esperan confirmación del puente y cambian a cuando el puente confirma el envío.

Navega el historial de entradas con M-p y M-n.

Traceroute

Pulsa t en cualquier nodo de la lista para enviar un traceroute. Se abre un buffer de log dedicado:

[08:30:01] → Solar Node 7 (!d4e5f6a7)
  ✓ → Hilltop Relay → BaseStation K9 (8.0dB) → Solar Node 7
  ← Solar Node 7 → BaseStation K9 (7.0dB) → Hilltop Relay

[08:31:15] → Mountain Peak (!f2a3b4c5)
  ⧖ Pending...

Cada entrada muestra la ruta de ida con los valores SNR de cada salto, y la ruta de vuelta. Mientras espera la respuesta aparece ⧖ Pending... y se actualiza en cuanto llega.

También puedes usar M-x meshtastic-traceroute desde un buffer de DM (usa el nodo del chat) o desde cualquier otro buffer (pide el Node ID).

Enviar posición

M-x meshtastic-send-position envía tus coordenadas GPS al nodo seleccionado. Usa calendar-latitude y calendar-longitude si están configurados en Emacs; si no, cae al GPS del propio dispositivo; y si tampoco hay, muestra un error.

Funciona desde la lista de nodos, desde un DM o desde cualquier buffer (en ese caso pide el Node ID).

Limitaciones

No debemos equiparar una app moderna de mensajería a una conversación de LoRa. Sus limitaciones son estructurales y debes aprender a convivir con ellas. Emacs no las puede sortear.

  • Sin historial al arrancar: el puente no tiene base de datos. Solo están disponibles los mensajes recibidos desde que se inició.
  • Ancho de banda limitado: LoRa es una radio de largo alcance pero baja velocidad. Los mensajes deben ser cortos.
  • Un dispositivo por instancia: cada instancia de Emacs conecta con un único puerto serial.
  • Los mensajes se pueden perder: nadie te garantiza que los mensajes lleguen al destinatario.

Pero lo que no tiene límite es la diversión y toda la gente que puedes llegar a conocer por tu zona.

Este trabajo está bajo una licencia Attribution-NonCommercial-NoDerivatives 4.0 International.

¿Me invitas a un café?

Comentarios

Todavía no hay ningún comentario.

Escrito por Andros Fenollosa

junio 5, 2026

4 min de lectura

Sigue leyendo

Visitantes en tiempo real

Estás solo: 🐱