Skip to content

psytraxx/lora-android-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LoRa Android RS

A long-range communication system for sending text messages (up to 50 characters) and GPS coordinates via 433 MHz LoRa using ESP32-S3 and Android devices.

Features

  • 📱 Android App: Java-based app with GPS integration and BLE communication
  • 📡 Long Range: 5-10 km typical range (up to 15+ km in ideal conditions)
  • 🔋 Power Optimized: 40-50% power savings (70-100 hours on 2500 mAh battery)
  • 📦 Message Buffering: Buffers up to 10 messages when phone is disconnected
  • Reliable: ACK mechanism confirms message delivery
  • 🌍 GPS Precision: ±1 meter accuracy (GPS sent only when available)
  • 🚀 Fast: ~1-2 second end-to-end latency
  • 📉 Bandwidth Efficient: 6-bit character packing (40% smaller than UTF-8)

Recent Improvements

Protocol v2.0 - Separate Message Types (Oct 2025)

  • Separate Messages: Text and GPS now sent as independent messages
    • TextMessage (0x01): Text only with 6-bit packing
    • GpsMessage (0x02): GPS coordinates only (10 bytes fixed)
    • AckMessage (0x03): Acknowledgments
  • Bandwidth Savings:
    • Text-only: 40% smaller (7 bytes for "SOS" vs 15 bytes)
    • 6-bit encoding: 25% smaller than UTF-8 for uppercase text
    • GPS optional: Only sent when GPS is enabled
  • Flexible Usage:
    • Send text without GPS when location not needed
    • Send GPS updates separately for tracking
    • Text always sent, GPS only when available

Power Optimization (40-50% savings)

  • CPU Clock: Reduced from 240 MHz to 160 MHz
  • Auto Light Sleep: Enabled via Embassy async framework
  • Battery Life: 70-100 hours on 2500 mAh (was 50-60 hours)

Message Buffering

  • Buffer Capacity: 10 messages (was 1)
  • BLE→LoRa Channel: 5 messages (increased from 1 for text+GPS bursts)
  • Behavior: Continues receiving LoRa messages even when phone is disconnected
  • On Reconnect: All buffered messages delivered immediately

Architecture

graph TD
    A[Android Phone 1<br/>- Internal GPS<br/>- Text Input<br/>- Display<br/>- Java App] -->|Text + GPS Data| B[BLE]
    B --> C[ESP32-S3<br/>LoRa Transmitter<br/>- Sx1276 Module<br/>- Pins: SCK18, MISO19, MOSI21, SS5, RST12, DIO015<br/>- Firmware: Rust/Arduino]
    C -->|LoRa Transmission| D[LoRa Radio Waves]
    D --> E[ESP32-S3<br/>LoRa Receiver<br/>- Same hardware/firmware]
    E -->|Forwarded Data| F[BLE]
    F --> G[Android Phone 2<br/>- Display<br/>- Receives Text + GPS<br/>- Same Java App]
    
    E -->|ACK| D
    D --> C
    C -->|ACK| B
    B --> A
    
    subgraph "Sender Side"
        A
        B
        C
    end
    
    subgraph "Receiver Side"
        E
        F
        G
    end
Loading

Project Structure

lora-android-rs/
├── esp32s3/              # ESP32-S3 firmware (Rust)
│   ├── src/
│   │   ├── main.rs       # Main entry point
│   │   ├── ble.rs        # BLE GATT server and event handling
│   │   ├── lora.rs       # LoRa radio driver and message handling
│   │   └── protocol.rs   # Binary protocol implementation
│   └── Cargo.toml
├── android/              # Android application (Java)
│   ├── app/src/main/
│   │   ├── java/
│   │   │   ├── com/lora/android/MainActivity.java
│   │   │   └── lora/Protocol.java
│   │   └── res/layout/activity_main.xml
│   └── build.gradle
├── protocol.md           # Protocol specification
├── architecture.md       # System architecture
└── README.md            # This file

Building & Installation

Prerequisites

ESP32 Firmware

  • Rust (stable)
  • espup - ESP32 Rust toolchain installer
  • ESP32-S3 development board
  • SX1276 LoRa module

Android App

  • Android Studio or Android SDK
  • JDK 8 or higher
  • Gradle (included in Android Studio)

ESP32 Firmware Build

  1. Install ESP32 Rust toolchain:

    cargo install espup
    espup install
    . ~/export-esp.sh  # Source the environment
  2. Build firmware:

    cd esp32s3
    cargo build --release
  3. Flash to ESP32-S3:

    cargo run --release
    # Or use espflash:
    espflash flash target/xtensa-esp32s3-none-elf/release/esp32s3 --monitor
  4. Monitor logs:

    espflash monitor

Android App Build

Using Android Studio

  1. Open the android/ folder in Android Studio
  2. Wait for Gradle sync to complete
  3. Connect Android device or start emulator
  4. Click "Run" or press Shift+F10

Using Command Line

cd android
./gradlew assembleDebug           # Build APK
./gradlew installDebug             # Install to connected device

Running Tests

ESP32 Firmware:

cd esp32s3
cargo check                        # Type checking
cargo clippy                       # Linting

Android App:

cd android
./gradlew test                     # Run unit tests (9 tests)
./gradlew connectedAndroidTest     # Run instrumentation tests

Test Coverage

  • ESP32: Protocol serialization/deserialization, 6-bit packing
  • Android: 9 comprehensive unit tests covering:
    • TextMessage, GpsMessage, AckMessage serialization
    • 6-bit character packing/unpacking
    • Round-trip encoding/decoding
    • Character validation and support
    • Edge cases and error handling

Hardware Setup

ESP32-S3 to SX1276 Wiring

SX1276 Pin ESP32-S3 Pin Function
SCK GPIO18 SPI Clock
MISO GPIO19 SPI MISO
MOSI GPIO21 SPI MOSI
NSS/CS GPIO5 Chip Select
RESET GPIO12 Reset
DIO0 GPIO15 Interrupt
3.3V 3.3V Power
GND GND Ground

LoRa Module Configuration

Edit esp32s3/.cargo/config.toml:

[env]
LORA_TX_POWER_DBM = "14"        # Power in dBm (-4 to 20)
LORA_TX_FREQUENCY = "433920000" # Frequency in Hz

Common Frequencies:

  • 433 MHz: 433920000 (worldwide)
  • 868 MHz: 868100000 (Europe)
  • 915 MHz: 915000000 (Americas, Australia)

Regional Power Limits:

  • EU (433 MHz): 2 dBm max
  • US (433 MHz): 17 dBm max
  • US (915 MHz): 30 dBm max
  • Australia: 14 dBm (433 MHz) / 30 dBm (915 MHz)

Antenna: Use antenna tuned for your chosen frequency (~17 cm for 433 MHz quarter-wave)

Message Buffering

The ESP32 firmware buffers up to 10 messages when your phone is disconnected:

When Phone is Connected:

  • Messages delivered instantly

When Phone is Disconnected:

  • Messages buffered (up to 10)
  • ESP32 continues receiving
  • Sender gets ACK immediately

When You Reconnect:

  • All buffered messages delivered instantly
  • Oldest messages first (FIFO)

If Buffer is Full:

  • Messages 11+ are dropped with warning log
  • ESP32 continues receiving (doesn't block)

Adjusting Buffer Size:

Edit esp32s3/src/bin/main.rs:

// BLE to LoRa channel (for text+GPS bursts)
static BLE_TO_LORA: StaticCell<Channel<CriticalSectionRawMutex, Message, 5>> = StaticCell::new();

// LoRa to BLE channel (for phone disconnection)
static LORA_TO_BLE: StaticCell<Channel<CriticalSectionRawMutex, Message, 10>> = StaticCell::new();

Also update function signatures in esp32s3/src/ble.rs and esp32s3/src/lora.rs.

Memory Impact: ~64 bytes per message

Usage

Android App

  1. Launch app on both Android devices
  2. Grant permissions: Bluetooth, Location (GPS)
  3. Wait for BLE connection: App automatically scans for "ESP32-LoRa"
  4. Send message:
    • Type message (max 50 characters, uppercase A-Z, 0-9, punctuation)
    • GPS is optional - app will send text even without GPS
    • Press "Send"
    • App sends text message first, then GPS (if available) 100ms later
  5. Receive message: Messages appear automatically on receiving device
  6. View GPS location: Coordinates displayed if GPS message received

Message Behavior

  • Text message: Always sent when you press Send
  • GPS message: Only sent if GPS is enabled and has a fix
  • No GPS?: App shows "Sent text only (X bytes) - No GPS"
  • With GPS: App shows "Sent text (X bytes) + GPS (Y bytes)"

Character Support

  • Supported: A-Z 0-9 .,!?-:;'"@#$%&*()[]{}=+/<>_
  • Auto-converted: Lowercase → uppercase (e.g., "hello" becomes "HELLO")
  • Not supported: Emoji, special Unicode, characters outside the 64-char set

Performance

  • Max text: 50 characters (42 bytes with 6-bit packing)
  • GPS message: 10 bytes (fixed size)
  • Range: 5-10 km typical (up to 15+ km ideal conditions)
  • Latency: 1-2 seconds end-to-end
  • Battery: 70-100 hours on 2500 mAh
  • Time on Air:
    • Text only: ~350-550ms (empty to 50 chars) at SF10
    • GPS only: ~380ms at SF10
    • Text + GPS: Combined + 100ms delay (~850-930ms)
  • LoRa Config: SF10, BW125kHz, CR4/5, 433.92 MHz default, 14 dBm
  • Duty Cycle: ~38-100 messages/hour depending on message type (EU 1% compliance)

See protocol.md for detailed Time on Air calculations and duty cycle compliance.

Troubleshooting

ESP32 Issues

BLE not advertising:

  • Check serial monitor for "BLE advertising..." message
  • Verify Bluetooth is enabled in ESP32 logs
  • Restart ESP32 (power cycle)

LoRa not transmitting:

  • Check SPI wiring (SCK, MISO, MOSI, CS)
  • Verify 3.3V power to LoRa module
  • Check antenna connection (433 MHz antenna)
  • Monitor serial for "LoRa TX successful" messages

Radio init failed:

  • Check RESET and DIO0 pin connections
  • Verify SX1276 module is 433 MHz capable
  • Check power supply (some modules need more current)

Android Issues

App can't find ESP32:

  • Grant Bluetooth and Location permissions
  • Enable Bluetooth on phone
  • Ensure ESP32 is powered and advertising
  • Check that device name is "ESP32S3-LoRa" in logs
  • Try restarting both phone and ESP32

No GPS fix:

  • Text messages can still be sent without GPS
  • GPS message only sent when location is available
  • Check app shows "Sent text only - No GPS" when GPS unavailable
  • For GPS-required scenarios:
    • Go outdoors or near window
    • Wait 30-60 seconds for GPS acquisition
    • Check Location permission is granted
    • Enable "High accuracy" in phone location settings

Messages not received:

  • Check both ESP32 devices are powered
  • Verify LoRa range (start close, then test distance)
  • Check serial monitor for "LoRa RX: received X bytes"
  • Ensure devices are on same frequency (433 MHz)

Debug Tips

Protocol Version Compatibility:

  • ⚠️ Protocol v2.0 is not backward compatible with v1.0
  • All devices must run same protocol version
  • v2.0 changes:
    • Message types: TEXT (0x01), GPS (0x02), ACK (0x03)
    • 6-bit character encoding (not UTF-8)
    • GPS sent separately from text

ESP32 Serial Monitor:

espflash monitor
# Look for:
# - "BLE advertising..."
# - "LoRa radio ready for RX/TX"
# - "Message forwarded from BLE to LoRa"
# - "LoRa TX successful"
# - "LoRa RX: received X bytes"

Android Logcat:

adb logcat -s LoRaApp
# Or use Android Studio's Logcat viewer

External Resources

License

[Add your license here]

Contributing

[Add contribution guidelines here]

Acknowledgments

Built with:


Ready for long-range adventures! 📡🌍

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published