Skip to content

Tech500/EoRa-PI-Foundation

Repository files navigation

Ultra-Low Power LoRa Remote Control with ESP32-S3 Deep Sleep + Duty Cycle Reception

GitHub

🚀 Project Overview

Successfully implemented an ultra-low power LoRa remote control system using ESP32-S3 with SX1262 radio, achieving months of battery operation through optimized deep sleep and duty cycle reception.

Key Achievement: 175 µA average current consumption with 13-19 months battery life on a 3000 mAh LiPo battery.

Hardware Configuration

  • Development Board: EoRa Pi ESP32-S3 (SX1262 LoRa 915MHz)
  • Power Consumption: ~175 µA average (measured with Nordic Power Profiler Kit II)
  • Battery Life: 13-19 months on 3000 mAh LiPo
  • Custom wake-up circuit using a 74HC04N DIP package of six inverters (two used); for clean unity gain and signal routing

🛠️ Getting Started

What You'll Need

Essential Hardware

  • Ebyte EoRa-S3-900TB (EoRa PI) - Pair of transceivers for your country's ISM frequency band
  • 3000 mAh LiPo Battery - JST-2 1.25 SH Series connector
  • Development Environment - Arduino IDE 2.3.6
  • Compiled with 2.0.17 Board Manager
  • Choose Board - "ESP32S3 Development Module"

For Remote Control Applications

  • KY-002S bistable MOSFET switch - Enables remote load switching
  • 74HC04N DIP package of Six inverters (two used) - For unity gain buffering and clean wake signal routing (GPIO33 → RTC_GPIO16)

Quick Start Guide

  1. Install Dependencies

    • Install RadioLib library in Arduino IDE
    • Download this repository and open desired sketch
    • Compiled using ESP32 Board Manager 2.0.17
  2. Basic Setup

    • Transmitter: Uses "EoRa PI" board only (no additional wiring needed)
    • Receiver: See wiring schematic for component connections
  3. Upload & Test

    • Flash EoRa_PI_WOR_Transmitter.ino to transmitter board
    • Flash EoRa_PI_WOR_Receiver.ino to receiver board
    • Power on both units and test basic communication

⚡ Power Optimization & Battery Performance

Ultra-Low Power Achievement

  • Average Current: 175 µA (ESP32-S3 deep sleep + SX1262 duty cycle)
  • Battery Configuration: 3000 mAh LiPo with JST-2 1.25 SH connector
  • Measured with: Nordic Power Profiler Kit II (NPPK II)

Battery Life Projections

Scenario Duration Notes
Theoretical Maximum ~1.96 years (714 days) Ideal conditions
Realistic Estimate ~19.2 months (586 days) 82% usable capacity
Practical Limit ~13.5 months Accounting for self-discharge

Key Power Management Features

  • ESP32-S3 Deep Sleep: Ultra-low consumption when idle
  • LoRa Duty Cycle: radio.startReceiveDutyCycleAuto() minimizes radio power
  • Wake-on-Radio Protocol: Two-stage packet system for reliable operation; single transmission
  • Smart RTC_GPIO Routing: SX1262 DIO1 → GPIO33 → 74HC04N (input A1, Y1 output connected to A2 input, y2 output) → RTC_GPIO16 → ESP32 RTC_GPIO external0 Wake up.

Power-Saving Configuration

// Optimized LoRa parameters for duty cycle operation
Frequency: 915.0 MHz
Bandwidth: 125.0 kHz
Spreading Factor: 7
Coding Rate: 4/7
TX Power: 14 dBm
Preamble: 512 symbols (critical for duty cycle timing)
Sync Word: RADIOLIB_SX126X_SYNC_WORD_PRIVATE

📡 Communication Protocol

Wake-On-Radio System

Implemented a two-packet protocol for reliable one-transmission operation:

  1. WOR (Wake-On-Radio) packet → Wakes ESP32 → Initializes duty cycle mode
  2. Payload packet → Received by duty cycle radio → Executes command immediately
// Server side - dual transmission
sendWakePacket();     // Wake the receiver
delay(500);           // Brief pause
sendCommandPacket();  // Actual command execution

Packet Format

  • Command: "1, + timestamp"
  • Keep Alive: Only one command (turn ON)
  • Dead Man's Switch: Automatic timeout shutdown (2-minute safety)
  • Timestamp: NTP-based time from transmitter

Communication Flow

  1. Web request received → Preamble message switches radio to Duty Cycle mode
  2. ESP32-S3 awakens from deep sleep
  3. Transmitter sends "1,timestamp" packet
  4. Receiver processes command → Resets 2-minute safety timer
  5. No packet received → Timer expires → Switch turns OFF automatically

🚀 Operation & Setup

Network Configuration

The transmitter uses WiFiManager (by tzapu) for easy network setup without hardcoding credentials:

  1. Initial Setup Mode

    • Power on the transmitter device
    • Device creates WiFi access point: EoRa-PI-Setup
    • Connect to this network from your phone/computer
    • Open web browser and navigate to: 192.168.4.1
  2. Configure Your Network

    • Select your home WiFi network from the list
    • Enter your WiFi password
    • Device will connect and display the assigned IP address
  3. Remote Control Operation

    • Note the IP address displayed (e.g., 192.168.1.100)
    • Open web browser on any device connected to your network
    • Navigate to: [YOUR_IP_ADDRESS]/relay
    • Example: 192.168.1.100/relay
    • This sends the LoRa WOR (Wake-On-Radio) packet followed by command packet to the receiver

Web Interface

  • Simple HTTP endpoint: Just add /relay to your device's IP address
  • Instant transmission: Sends wake packet + command packet sequence
  • No complex interface: Single-click operation for remote control

🔧 Technical Implementation

Library Integration

  • Successfully converted from SX126x-Arduino library, example "DeepSleep.ino" to RadioLib, "EoRa_PI_Foundation_Receiver.ino"
  • Preserved duty cycle reception capabilities
  • Clean String-based packet reading implementation

Deep Sleep Management

void goToSleep(void) {

  Serial.println("=== PREPARING FOR DEEP SLEEP ===");
  Serial.printf("DIO1 pin state before sleep: %d\n", digitalRead(RADIO_DIO1_PIN));
  Serial.printf("Wake pin (GPIO16) state before sleep: %d\n", digitalRead(WAKE_PIN));

  // Set up the radio for duty cycle receiving
  radio.startReceiveDutyCycleAuto();

  Serial.println("Configuring RTC GPIO and deep sleep wake-up...");
  // Configure GPIO16 for RTC wake-up - using internal pull-down
  rtc_gpio_pulldown_en(WAKE_PIN);  // Internal pull-down on GPIO16

  // Setup deep sleep with wakeup by GPIO16 - RISING edge (buffered DIO1 signal)
  esp_sleep_enable_ext0_wakeup(WAKE_PIN, RISING);

  // Turn off LED before sleep
  digitalWrite(BOARD_LED, LED_OFF);

  Serial.println("✅ Going to deep sleep now...");
  Serial.println("Wake-up sources: DIO1 pin reroute");
  Serial.flush();  // Make sure all serial data is sent before sleep

  SPI.end();

  // Finally set ESP32 into sleep
  esp_deep_sleep_start();  
}

📊 Performance Results

Duty Cycle Calculation:

  • Average current: 175µA

  • Sleep current: 25.38µA

  • Active current: 11,000µA (11mA)

  • Duty cycle ≈ (175 - 25.38) / (11,000 - 25.38) ≈ 1.36%

  • Achieving a very low ~1.4% duty cycle, which is excellent for battery life.

  • Interrupt-driven system is working well:

  • 98.6% of time in deep sleep (25.38µA)

  • 1.4% of time active receiving (11mA)

  • Clean transitions with no lingering current

Power Consumption

  • Deep Sleep: ~23 µA, Average current ~175 µA (ESP32-S3) + duty cycle radio consumption
  • Active Time: <5% duty cycle during command execution
  • Wake-up Time: <2 seconds
  • Command Processing: Immediate response
  • Return to Sleep: Automatic after task completion

Reliability Metrics

  • 100% packet reception success rate
  • Consistent wake-up and command execution
  • Sub-second response time from transmission to action

📈 Applications & Use Cases

Ideal Applications

  • Remote equipment control in field deployments (months of operation)
  • Battery-powered IoT sensor networks
  • Agricultural automation systems
  • Emergency/backup communication systems
  • Environmental monitoring with long-term deployment
  • Camera activation systems (original use case)

Optional Features

  • Local logging: Store sensor data on SD card or flash memory
  • Cloud integration: Optional by request; POST INA226 data to Google Sheets via Apps Script
  • Power monitoring: Track current consumption and battery health
  • Multi-node networks: Scale to multiple sensor/control points

🧠 Key Lessons Learned

  1. GPIO Routing Critical: RTC_GPIO access essential for deep sleep wake-up
  2. Parameter Matching: TX/RX LoRa parameters must match exactly
  3. Duty Cycle Timing: Longer preambles (512 symbols) crucial for reliable reception
  4. RadioLib Integration: String-based packet reading provides clean implementation
  5. Two-Stage Protocol: Wake-On-Radio approach solves timing challenges elegantly
  6. Power Measurement: NPPK II essential for validating ultra-low power performance

📁 Documentation & Resources

Project Files

  • Complete Pin Mapping Guide: /Docs/Complete Ebyte EoRa-S3-900TB Pin Mapping Guide.pdf
  • Power Waveforms: /Docs/Deep Sleep Waveforms (Latest Nordic PPK2 Observations)/
  • User Manual: /Docs/EoRa_PI_UserManual_EN_v1.1.pdf
  • Power Reference: /Docs/ESP32-S3 Power Consumption Reference Guides.pdf

Battery Specifications (from EoRa-PI User Manual)

  • Connector: JST-2 1.25 SH Series
  • Power Off Consumption: ~5 µA (battery only, no USB)
  • Sleep Mode Consumption: ~25 µA (all peripherals in sleep mode)
  • Max Charging Current: 500mA

🤝 Credits & Acknowledgements

This project was developed with testing and guidance from:

  • William Lucid – Founder & Developer
  • OpenAI ChatGPT – Engineering Assistant & Debugging Partner
  • Claude – Lead programmer & Debugger, Battery Analysis, "EoRa_PI_WOR_Receiver.ino"
  • Copilot, "DIO1 re-routing" and Gemini – Support and Contributions to coding
  • Community testers and contributors

🤝 Contributing

We welcome contributions! Here's how to help:

  • 🐛 Found a bug? Open an issue with details and steps to reproduce
  • 💡 Have an idea? Submit a feature request or start a discussion
  • 🔧 Want to code? Fork the repo and submit a pull request
  • 📚 Documentation: Help improve examples, guides, or troubleshooting

📜 License

MIT License – see LICENSE for details.


🎯 Conclusion

Successfully achieved the goal of creating a production-ready, ultra-low power LoRa remote control system. The combination of ESP32-S3 deep sleep, SX1262 duty cycle reception, and smart protocol design delivers months of battery operation with reliable command execution.

Hardware: EoRa Pi ESP32-S3 + SX1262
Software: Arduino IDE, RadioLib, ESP-IDF framework
Power: Battery-optimized for 13-19 month field deployment
Range: LoRa 915MHz with excellent rural coverage

73's de AB9NQ thanks for stopping by!
What started as a simple Wyze Cam switch evolved into a flexible, ultra-low-power LoRa + ESP32-S3 foundation achieving sub-200µA operation.

About

Ebyte EoRa-S3-900TB Transmitter and Receiver and Deep Sleep

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published