Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LoRa

End-to-end LoRa communication system: bare-metal STM32 firmware, Go backend, TypeScript dashboard, Android range-test app, and a custom PCB design.

[Phone + LoRa Board] --LoRa 433MHz--> [Base LoRa Board] --USB Serial--> [PC / Go Server]
                                                                              |
                                                                        :8080 HTTP + WS
                                                                              |
                                                                        [Web Dashboard]

Screenshots

Range Test Dashboard

Live Leaflet map with color-coded signal markers, heatmap overlay, and real-time stats.

Range Test Dashboard

Dev Kit Info Dashboard

System info, USB devices, serial ports, and LoRa module configuration via GraphQL.

Dev Kit Dashboard

Components

Component Stack Description
Firmware C99, bare-metal STM32F103, SX1262 Transparent UART-to-LoRa serial bridge
Backend Go 1.24, GraphQL, SQLite, WebSocket Dev kit dashboard + range test server
Frontend Vite + TypeScript Hardware info dashboard
Range App Android / Java GPS + LoRa signal mapper
Hardware KiCad Dog tracker PCB (ESP32 + SX1262 + GPS)

Hardware

  • 2x DX-LR30 boards: STM32F103C8T6 + SX1262 LoRa + CH340C USB-serial
  • Android phone with USB OTG
  • Linux PC

Prerequisites

# Firmware toolchain
sudo apt install gcc-arm-none-eabi stm32flash python3-serial

# Backend + Frontend
# Go 1.24+, Node.js + pnpm
go install github.com/air-verse/air@latest        # Go hot reload
go install github.com/99designs/gqlgen/cmd/gqlgen@latest  # GraphQL codegen

# Serial port access
sudo usermod -aG dialout $USER

Android SDK at ~/Android/Sdk for building the range test app.

Quick Start

Dev Kit Dashboard

make install   # pnpm install + go mod tidy
make dev       # Start Go + Vite with hot reload

Range Test

# One command: builds firmware, starts server
./dev-all.sh

# Or manually:
cd firmware && make
cd ../backend && CGO_ENABLED=1 go build -o bin/rangetest ./cmd/rangetest
sudo ./bin/rangetest -firmware ../firmware/build/firmware.bin -listen :8080
  1. Plug base board into PC, run the server
  2. Connect second board to phone via USB OTG
  3. Open the LoRa Range Test app, grant location permission
  4. Press THIS IS HOME at your starting location
  5. Walk around -- phone records GPS + signal strength every 5 seconds
  6. Readings appear as color-coded markers on the web dashboard in real time
  7. Out of range: phone buffers locally. Back in range: flushes in batches
  8. CSV log saved to Downloads/lora_range_YYYYMMDD_HHmmss.csv on phone

Firmware Only

cd firmware && make                # Build
make flash                         # Flash to /dev/ttyUSB0

# Test serial bridge between two boards:
sudo screen /dev/ttyUSB0 9600     # Terminal 1
sudo screen /dev/ttyUSB1 9600     # Terminal 2
# Type in one -> appears in the other via LoRa

To enter bootloader mode: hold KEY, press RST, release KEY.

Android App

cd range_app && ./gradlew assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk

Make Targets

Command Description
make dev Start both servers with hot reload
make dev-rangetest Build firmware + range test server, run with sudo
make build Production build (Go binary + Vite bundle)
make generate Regenerate GraphQL code from schema
make install Install all dependencies
make clean Remove build artifacts

Architecture

Backend (Hexagonal)

infrastructure/        HTTP server, GraphQL, WebSocket
  app/                 Service layer
    ports/             Interfaces (SystemReader, USBReader, SerialReader, LoRa)
      adapters/        Implementations (sysfs, lsusb, serial, SQLite)
        domain/        Pure data structs

Firmware (Bare-Metal C99)

No HAL, no RTOS. Direct register access. ~2.7KB flash.

Module Purpose
main.c UART <-> LoRa bridge loop
sx1262.c SX1262 LoRa radio driver
uart.c IRQ-driven USART1 with ring buffers
spi.c Hardware SPI1 @ 4.5 MHz
gpio.c Pin configuration
system.c 72 MHz clock setup, SysTick
startup.c Vector table, Reset_Handler

LoRa Parameters

Parameter Value
Frequency 433.0 MHz
Spreading Factor 7
Bandwidth 125 kHz
Coding Rate 4/5
TX Power +22 dBm
Max Packet 255 bytes

Binary Protocol

Packets are binary structs, base64-encoded over 9600 baud serial.

Type Code Payload
Single Reading 0x01 seq(2) lat(4) lon(4) rssi(1) snr(1) time_offset(2)
Batch 0x02 count(1) + N x reading (max 13)
Home Location 0x03 lat(4) lon(4)
Version 0x04 major(1) minor(1) patch(1) hash(1)

Coordinates: int32 degrees x 1e7, big-endian. Base station prepends: [RSSI:-45 SNR:12] <base64>\r\n

Signal Strength

RSSI Quality Color
> -70 dBm Excellent Green
-70 to -90 Good Yellow
-90 to -110 Weak Orange
< -110 dBm Very Weak Red

Range Test API

Route Description
GET / Leaflet map dashboard
GET /ws WebSocket (init, reading, home messages)
GET /api/readings All readings JSON
GET /api/session Current session + home location

GraphQL API (Dev Kit Dashboard)

type Query {
  systemInfo: SystemInfo!
  usbDevices: [USBDevice!]!
  serialPorts: [SerialPort!]!
  loraModules: [LoRaModule!]!
  sendATCommand(port: String!, command: String!): ATResponse!
}

Measured Throughput

Packet Size Effective Rate
1 byte 29 B/s
32 bytes 225 B/s
100 bytes 258 B/s
250 bytes 273 B/s

Hardware Design

The hardware/ directory contains a KiCad project for a dog tracker PCB (ESP32 + SX1262 + GPS + accelerometer). Includes schematic, routed PCB, Gerber files, BOM, and a JLCPCB ordering guide.

Project Structure

firmware/                    Bare-metal STM32 + SX1262 firmware
  src/                       C source files
  include/                   CMSIS headers, version defines
  Makefile                   ARM GCC build
  range_test_pc.py           PC-side ping sender
  test_throughput.py         Throughput measurement

backend/                     Go backend
  cmd/server/                Dev kit dashboard entry point
  cmd/rangetest/             Range test server entry point
  domain/                    Data structs
  ports/                     Interfaces
  adapters/                  Implementations (sysfs, lsusb, serial, SQLite, WebSocket)
  app/                       Service layer
  infrastructure/            HTTP + GraphQL

frontend/                    Vite + TypeScript dashboard
  src/components/            Card renderers (system, USB, serial, LoRa)
  src/api.ts                 GraphQL client

range_app/                   Android range test app
  app/src/main/java/         GPS, serial, map, binary protocol, CSV export

hardware/                    KiCad dog tracker PCB
  kicad-dog-tracker/         Schematic, PCB, Gerbers
  BOM.csv                    Bill of materials

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages