{"id":48789111,"url":"https://github.com/leshniak/mesh-pager","last_synced_at":"2026-04-13T19:00:44.477Z","repository":{"id":350389978,"uuid":"1206209728","full_name":"leshniak/mesh-pager","owner":"leshniak","description":"Meshtastic-compatible LoRa mesh pager on Arduino Nesso N1 (ESP32-C6) — canned messages, touch UI, AES-256 encryption, deep sleep","archived":false,"fork":false,"pushed_at":"2026-04-10T05:01:04.000Z","size":157,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-10T07:11:02.384Z","etag":null,"topics":["arduino","esp32","esp32-c6","lora","mesh-network","meshtastic","platformio"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leshniak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-09T17:28:02.000Z","updated_at":"2026-04-10T05:01:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/leshniak/mesh-pager","commit_stats":null,"previous_names":["leshniak/mesh-pager"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/leshniak/mesh-pager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leshniak%2Fmesh-pager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leshniak%2Fmesh-pager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leshniak%2Fmesh-pager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leshniak%2Fmesh-pager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leshniak","download_url":"https://codeload.github.com/leshniak/mesh-pager/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leshniak%2Fmesh-pager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31766482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T15:25:13.801Z","status":"ssl_error","status_checked_at":"2026-04-13T15:25:09.162Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","esp32","esp32-c6","lora","mesh-network","meshtastic","platformio"],"created_at":"2026-04-13T19:00:19.032Z","updated_at":"2026-04-13T19:00:44.467Z","avatar_url":"https://github.com/leshniak.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mesh-pager\n\nA Meshtastic-compatible LoRa mesh pager built on the **Arduino Nesso N1** (ESP32-C6). Sends and receives pre-configured canned messages over an encrypted mesh network with a touch UI and physical button.\n\n## UI\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/images/ui-idle.svg\" alt=\"Idle — message selection\" width=\"135\"/\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"docs/images/ui-sending.svg\" alt=\"Hold to send — progress bar\" width=\"135\"/\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"docs/images/ui-toast.svg\" alt=\"Incoming message toast\" width=\"135\"/\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"docs/images/ui-history.svg\" alt=\"Message history overlay\" width=\"135\"/\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eIdle \u0026nbsp;·\u0026nbsp; Hold to send \u0026nbsp;·\u0026nbsp; Incoming toast \u0026nbsp;·\u0026nbsp; Message history\u003c/em\u003e\n\u003c/p\u003e\n\n## Features\n\n- **Canned messages** — swipe left/right to pick, hold or click to send\n- **Meshtastic-compatible** — AES-256-CTR encrypted packets, works with existing Meshtastic nodes\n- **Touch UI** — 135x240 TFT with gesture controls (swipe, hold-to-send, swipe down for history)\n- **Physical button** — single click to send, double click to cycle messages, long press to power off\n- **Deep sleep** — auto-sleeps after 15s of inactivity, wakes on button press (~40-60 uA draw)\n- **Stay-awake lock** — double-click for standby mode: screen off, radio listening, wakes only on valid channel messages or button press (emergency deep sleep after 10 min)\n- **Smart wake** — incoming messages reset the sleep timer automatically\n- **Send-on-wake** — optional instant transmit on wake for gate/garage remote use\n- **Message history** — last 5 sent/received messages in a swipe-down overlay with SNR and hop count\n- **Toast notifications** — incoming messages pop up with sender ID, SNR, hop count (+N), and countdown timer\n- **Packet deduplication** — 64-entry cache prevents duplicate display via multiple relay paths\n- **Audio feedback** — distinct tones for TX, RX, sleep, and power off\n- **Power management** — display dimming, CPU frequency scaling (80 MHz), battery monitoring\n\n## Hardware\n\n| Component | Details |\n|-----------|---------|\n| Board | Arduino Nesso N1 (ESP32-C6, 160 MHz, 320 KB RAM, 16 MB flash) |\n| Display | 135x240 ST7789 TFT (M5GFX) |\n| Touch | FT5x06 capacitive touchscreen |\n| Radio | SX1262 LoRa (869.525 MHz, SF9, BW 250 kHz, 22 dBm) |\n| Battery | LiPo with USB charging via PMIC |\n\n## Getting Started\n\n### Prerequisites\n\n- [PlatformIO](https://platformio.org/) (CLI or IDE plugin)\n- Arduino Nesso N1 board\n\n### Configuration\n\nCopy the secrets template and fill in your Meshtastic channel details:\n\n```bash\ncp include/secrets.example.h include/secrets.h\n```\n\nEdit `include/secrets.h`:\n\n```cpp\n#pragma once\ninline constexpr const char* channelName = \"MyChannel\";\ninline constexpr const char* channelKey = \"base64-encoded-32-byte-key\";\ninline constexpr const char* messages[] = {\n    \"Hello\",\n    \"On my way\",\n    \"Open gate\",\n    \"SOS\",\n};\n```\n\nThe channel name and key must match your Meshtastic network configuration.\n\n### Build \u0026 Upload\n\n```bash\npio run                    # build\npio run -t upload          # flash to device\n```\n\n### Optional: Send-on-Wake\n\nFor gate remote use, enable instant transmit on wake from deep sleep in `include/config/AppConfig.h`:\n\n```cpp\ninline constexpr bool kSendOnWake = true;\n```\n\nWhen enabled, pressing the button to wake the device immediately sends the currently selected canned message.\n\n## UI Controls\n\n| Gesture | Action |\n|---------|--------|\n| Swipe left/right | Navigate canned messages |\n| Touch \u0026 hold (1s) | Send current message |\n| Swipe down | Open message history |\n| Swipe up | Close message history |\n| Button single click | Send current message |\n| Button double click | Toggle stay-awake lock |\n| Button long press | Power off |\n\n## Project Structure\n\n```\nmesh-remote/\n├── include/\n│   ├── app/             # State machine, canned message storage\n│   ├── config/          # Pins, radio, UI, and app constants\n│   ├── hal/             # Hardware abstraction (radio, touch, display, buzzer, power)\n│   ├── protocol/        # Meshtastic packet encoding, encryption, protobuf codec\n│   ├── ui/              # Renderer, toast/history manager\n│   └── secrets.h        # Channel config (not committed)\n├── src/                 # Implementation files mirror include/ structure\n└── platformio.ini\n```\n\n## Radio Configuration\n\nDefault settings match the **Meshtastic MediumFast EU** preset (SF9). A LongFast EU config (SF11, longer range, slower) is also available in `RadioConfig.h`.\n\n| Parameter | MediumFast (active) | LongFast |\n|-----------|---------------------|----------|\n| Frequency | 869.525 MHz | 869.525 MHz |\n| Bandwidth | 250 kHz | 250 kHz |\n| Spreading Factor | 9 | 11 |\n| Coding Rate | 4/5 | 4/5 |\n| TX Power | 22 dBm | 22 dBm |\n| Sync Word | 0x2B | 0x2B |\n\n## Dependencies\n\n- [RadioLib](https://github.com/jgromes/RadioLib) ^7.5.0 — LoRa radio driver\n- [M5Unified](https://github.com/m5stack/M5Unified) ^0.2.13 — display, touch, power, and audio\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleshniak%2Fmesh-pager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleshniak%2Fmesh-pager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleshniak%2Fmesh-pager/lists"}