Skip to content

Latest commit

 

History

History
776 lines (672 loc) · 26.8 KB

File metadata and controls

776 lines (672 loc) · 26.8 KB

Forj Link ESP32 Firmware - Comprehensive Development Guide

Project Overview

Forj Link is a complete overlanding convoy communication system consisting of two main components:

  1. Mobile App (mobile/) - React Native application for iOS/Android
  2. ESP32 Firmware (link/) - Bluetooth radio dongle firmware (this project)

The ESP32 firmware acts as a bridge between the mobile application and GMRS radio hardware, enabling convoy communication in off-grid environments. This document provides comprehensive guidance for developing the ESP32 firmware based on the mobile app architecture.

System Architecture

Hardware Components

  • ESP32-WROOM-32 development board (prototyping)
  • GMRS Radio Interface (RJ45 breakout board for direct radio connection)
  • Midland MXT275/MXT575 or compatible GMRS radios
  • GPS Module (I2C interface)
  • Real-time Clock (I2C interface)
  • Status LEDs (convoy, emergency, transmission)
  • Push Button (emergency activation)
  • External Flash (4MB+ for data storage)
  • Power Conditioning (LDO/Buck converter for radio power vampiring)

Communication Interfaces

  • Bluetooth Low Energy - Mobile app communication
  • RJ45 Interface - Direct GMRS radio connection (audio, PTT, power, control)
  • ESP32 ADC/DAC - Audio signal processing and sub-audible data transmission
  • I2C - GPS and sensor communication
  • GPIO - Status indicators and emergency button

GMRS Radio Interface Implementation

RJ45 Radio Connection

The ESP32 connects directly to GMRS radios (Midland MXT275/MXT575) via RJ45 interface using a breakout board for signal access and monitoring.

ESP32 Pin Mapping

// RJ45 breakout board connections
#define RJ45_PIN_1          GPIO_NUM_32     // ADC1_CH4 - Power/Ground
#define RJ45_PIN_2          GPIO_NUM_33     // ADC1_CH5 - Audio Input (Microphone)
#define RJ45_PIN_3          GPIO_NUM_34     // ADC1_CH6 - Audio Output (Speaker)
#define RJ45_PIN_4          GPIO_NUM_35     // ADC1_CH7 - PTT (Push-to-Talk)
#define RJ45_PIN_5          GPIO_NUM_36     // ADC1_CH0 - Channel Control
#define RJ45_PIN_6          GPIO_NUM_39     // ADC1_CH3 - Volume Control
#define RJ45_PIN_7          GPIO_NUM_25     // DAC1 - Data Transmission
#define RJ45_PIN_8          GPIO_NUM_26     // DAC2 - Control Signals

Power Vampiring

The system can be powered directly from the radio's RJ45 interface:

  • Voltage Range: 5V or 12V (auto-detected)
  • Current Capacity: 200-500mA (sufficient for ESP32 + peripherals)
  • Power Conditioning: LDO regulator (5V→3.3V) or buck converter (12V→3.3V)
  • Current Limiting: Fuse protection and soft-start circuitry

Sub-Audible Data Transmission

Digital packets are transmitted using frequencies inaudible to users:

Transmission Frequencies

#define FORJ_DATA_TONE_LOW_HZ       67      // Sub-audible low tone (like CTCSS)
#define FORJ_DATA_TONE_HIGH_HZ      203     // Sub-audible high tone
#define FORJ_DATA_CARRIER_HZ        4500    // Ultrasonic carrier (above voice)
#define FORJ_VOICE_THRESHOLD_HZ     300     // Voice activity cutoff

Data Transmission Modes

  1. Sub-Audible Mode: Use tones below 300Hz (filtered out by radio speakers)
  2. Ultrasonic Mode: Use frequencies above 3kHz (above voice bandwidth)
  3. Burst Mode: Inject brief data packets (10-50ms) during voice silence
  4. Mixed Mode: Low-level continuous data mixed with voice audio

ESP32 Audio Capabilities

  • ADC: 12-bit resolution, 0-3.3V range, 100kHz sampling (sufficient for voice audio)
  • DAC: 8-bit resolution, 0-3.3V output (adequate for tone generation)
  • Processing: Real-time audio analysis, voice activity detection, tone generation
  • Quality: Suitable for GMRS radio audio quality (300Hz-3kHz bandwidth)

Radio Interface Monitoring

The firmware includes comprehensive monitoring utilities:

Features

  • 8-Channel Monitoring: Real-time voltage monitoring on all RJ45 pins
  • Signal Classification: Automatic detection of power, audio, and digital signals
  • Change Detection: Logs only when pin states change
  • Audio Analysis: Detailed sampling and frequency analysis
  • Power Analysis: Voltage and current measurement for power vampiring

Monitoring Output Example

=== RJ45 Pin Readings ===
*RJ45_PIN_1: 5000mV (raw:4095) [HIGH]  <- Power pin detected
 RJ45_PIN_2: 0mV (raw:0) [LOW]         <- Ground
*RJ45_PIN_3: 1650mV (raw:2048) [AUDIO] <- Audio signal varying
 RJ45_PIN_4: 0mV (raw:0) [LOW]         <- PTT inactive
 RJ45_PIN_5: 3300mV (raw:4095) [HIGH]  <- Channel control

Forj Radio Protocol Specification

Protocol Constants

#define FORJ_MAGIC_BYTES        {0x46, 0x4F, 0x52, 0x4A}  // "FORJ"
#define FORJ_PROTOCOL_VERSION   1
#define FORJ_MAX_PACKET_SIZE    1024
#define FORJ_MAX_PAYLOAD_SIZE   950
#define FORJ_HEADER_SIZE        24
#define FORJ_GMRS_CHANNELS      22
#define FORJ_DEFAULT_CHANNEL    15

Packet Header Structure (24 bytes)

typedef struct __attribute__((packed)) {
    uint8_t magic[4];           // "FORJ" magic bytes
    uint8_t version;            // Protocol version (1)
    uint8_t type;               // Packet type (0-9)
    uint8_t priority;           // Priority level (0-3)
    uint8_t flags;              // Protocol flags
    uint8_t sender_id[4];       // Sender UUID hash
    uint8_t convoy_id[4];       // Convoy UUID hash
    uint16_t sequence_number;   // Sequence number (big-endian)
    uint8_t total_packets;      // Total packets in message
    uint8_t packet_index;       // Current packet index
    uint16_t payload_length;    // Payload length (big-endian)
    uint16_t checksum;          // CRC16 checksum (big-endian)
} forj_packet_header_t;

Packet Types

typedef enum {
    FORJ_PACKET_HEARTBEAT = 0,      // Regular status/location updates
    FORJ_PACKET_MESSAGE = 1,        // Text messages
    FORJ_PACKET_EMERGENCY = 2,      // Emergency alerts
    FORJ_PACKET_LOCATION = 3,       // Location updates
    FORJ_PACKET_STATUS = 4,         // Member status changes
    FORJ_PACKET_CONVOY_INFO = 5,    // Convoy metadata
    FORJ_PACKET_RELAY = 6,          // Store-and-forward relay
    FORJ_PACKET_ACK = 7,            // Acknowledgment packets
    FORJ_PACKET_DISCOVERY = 8,      // Network discovery
    FORJ_PACKET_SYSTEM = 9          // System control messages
} forj_packet_type_t;

Priority Levels

typedef enum {
    FORJ_PRIORITY_LOW = 0,
    FORJ_PRIORITY_NORMAL = 1,
    FORJ_PRIORITY_HIGH = 2,
    FORJ_PRIORITY_EMERGENCY = 3
} forj_priority_t;

Protocol Flags

#define FORJ_FLAG_ENCRYPTED         0x01    // Payload is encrypted
#define FORJ_FLAG_COMPRESSED        0x02    // Payload is compressed
#define FORJ_FLAG_FRAGMENTED        0x04    // Multi-packet message
#define FORJ_FLAG_RELAY_ALLOWED     0x08    // Can be relayed
#define FORJ_FLAG_ACK_REQUESTED     0x10    // Acknowledgment requested
#define FORJ_FLAG_PRIORITY_HIGH     0x20    // High priority transmission
#define FORJ_FLAG_BROADCAST         0x40    // Broadcast to all members
#define FORJ_FLAG_EXPERIMENTAL      0x80    // Experimental/testing

Compressed Location Format (16 bytes)

typedef struct __attribute__((packed)) {
    int32_t lat;                // Latitude * 1e7 (1.1m precision)
    int32_t lon;                // Longitude * 1e7
    int16_t alt;                // Altitude in meters
    uint8_t speed;              // Speed in km/h (0-255)
    uint8_t heading;            // Heading compressed (0-255 = 0-359°)
    uint8_t accuracy_hdop;      // Accuracy (4 bits) + HDOP (4 bits)
    uint16_t timestamp;         // Timestamp offset (seconds)
    uint8_t reserved;           // Reserved for future use
} forj_compressed_location_t;

Heartbeat Payload (32 bytes)

typedef struct __attribute__((packed)) {
    forj_compressed_location_t location;    // 16 bytes
    uint8_t battery_level;                  // Battery level (0-100%)
    uint8_t signal_strength;                // Signal strength (0-100%)
    uint8_t status;                         // Status flags
    uint8_t radio_channel;                  // Current GMRS channel
    uint8_t member_count;                   // Visible convoy members
    uint8_t capabilities;                   // Capability flags
    uint8_t reserved[6];                    // Reserved for expansion
} forj_heartbeat_payload_t;

Emergency Payload

typedef struct __attribute__((packed)) {
    uint8_t emergency_type;                 // Emergency type (0-5)
    uint8_t severity;                       // Severity level (0-3)
    forj_compressed_location_t location;    // 16 bytes
    char description[];                     // UTF-8 description
} forj_emergency_payload_t;

// Emergency types
#define FORJ_EMERGENCY_SOS          0
#define FORJ_EMERGENCY_MEDICAL      1
#define FORJ_EMERGENCY_MECHANICAL   2
#define FORJ_EMERGENCY_WEATHER      3
#define FORJ_EMERGENCY_ACCIDENT     4
#define FORJ_EMERGENCY_LOST         5

GMRS Channel Configuration

Channel Frequencies

typedef struct {
    uint8_t channel;
    float frequency;
    bool simplex;
    char* name;
} gmrs_channel_t;

static const gmrs_channel_t gmrs_channels[] = {
    {1,  462.5625, true,  "GMRS 1"},
    {2,  462.5875, true,  "GMRS 2"},
    {3,  462.6125, true,  "GMRS 3"},
    {4,  462.6375, true,  "GMRS 4"},
    {5,  462.6625, true,  "GMRS 5"},
    {6,  462.6875, true,  "GMRS 6"},
    {7,  462.7125, true,  "GMRS 7"},
    // Channels 8-14 are repeater inputs (excluded)
    {15, 462.5500, true,  "GMRS 15"},
    {16, 462.5750, true,  "GMRS 16"},
    {17, 462.6000, true,  "GMRS 17"},
    {18, 462.6250, true,  "GMRS 18"},
    {19, 462.6500, true,  "GMRS 19"},
    {20, 462.6750, true,  "GMRS 20"},
    {21, 462.7000, true,  "GMRS 21"},
    {22, 462.7250, true,  "GMRS 22"}
};

Radio Configuration

typedef struct {
    uint8_t channel;
    float frequency;
    uint8_t power_level;        // 1-5 watts
    uint8_t squelch_level;      // 0-9
    uint16_t ctcss_code;        // CTCSS tone (0 = off)
    uint8_t dcs_code;           // DCS code (0 = off)
    bool encryption_enabled;
} radio_config_t;

Bluetooth Low Energy Interface

BLE Service Structure

// Service and characteristic UUIDs (replace with actual values)
#define FORJ_SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define FORJ_CONFIG_CHAR_UUID       "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define FORJ_STATUS_CHAR_UUID       "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
#define FORJ_MESSAGE_CHAR_UUID      "6E400004-B5A3-F393-E0A9-E50E24DCCA9E"
#define FORJ_LOCATION_CHAR_UUID     "6E400005-B5A3-F393-E0A9-E50E24DCCA9E"
#define FORJ_EMERGENCY_CHAR_UUID    "6E400006-B5A3-F393-E0A9-E50E24DCCA9E"

BLE Characteristics

  • Configuration (Write): Radio settings, convoy configuration
  • Status (Read/Notify): Radio status, statistics, health
  • Message (Write/Notify): Send/receive message packets
  • Location (Read/Notify): Location updates and tracking
  • Emergency (Write/Notify): Emergency alerts and SOS

Device Advertisement

typedef struct {
    char device_name[32];       // "Forj-Link-XXXX"
    uint8_t battery_level;      // 0-100%
    uint8_t signal_strength;    // 0-100%
    uint8_t radio_status;       // Radio status flags
    uint8_t convoy_members;     // Number of visible members
} ble_advertisement_t;

Core Firmware Architecture

Main System Components

// Core system initialization
void forj_system_init(void);
void forj_radio_init(void);
void forj_ble_init(void);
void forj_gps_init(void);
void forj_storage_init(void);

// Main application loop
void forj_main_loop(void);

Message Queue System

typedef struct {
    forj_packet_header_t header;
    uint8_t payload[FORJ_MAX_PAYLOAD_SIZE];
    uint32_t timestamp;
    uint8_t retry_count;
    uint8_t max_retries;
} forj_message_t;

// Message queue operations
bool forj_queue_push(forj_message_t* msg, forj_priority_t priority);
bool forj_queue_pop(forj_message_t* msg);
size_t forj_queue_size(forj_priority_t priority);
void forj_queue_clear(void);

Packet Processing

// Packet encoding/decoding
size_t forj_encode_packet(const forj_packet_header_t* header, 
                         const uint8_t* payload, uint8_t* buffer);
bool forj_decode_packet(const uint8_t* buffer, size_t length,
                       forj_packet_header_t* header, uint8_t* payload);
bool forj_validate_packet(const forj_packet_header_t* header,
                         const uint8_t* payload);
uint16_t forj_calculate_crc16(const uint8_t* data, size_t length);

Radio Interface

// Radio control functions
bool forj_radio_set_channel(uint8_t channel);
bool forj_radio_set_power(uint8_t power_level);
bool forj_radio_set_squelch(uint8_t squelch_level);
bool forj_radio_transmit(const uint8_t* data, size_t length);
bool forj_radio_receive(uint8_t* data, size_t* length);
bool forj_radio_carrier_detect(void);

GPS Interface

// GPS data structure
typedef struct {
    double latitude;
    double longitude;
    float altitude;
    float speed;
    float heading;
    float accuracy;
    uint32_t timestamp;
    bool valid;
} forj_gps_data_t;

// GPS functions
bool forj_gps_read(forj_gps_data_t* gps_data);
forj_compressed_location_t forj_compress_location(const forj_gps_data_t* gps);
forj_gps_data_t forj_decompress_location(const forj_compressed_location_t* compressed);

Storage System

// Configuration storage
bool forj_storage_save_config(const radio_config_t* config);
bool forj_storage_load_config(radio_config_t* config);
bool forj_storage_save_convoy(const char* convoy_id, const char* convoy_name);
bool forj_storage_load_convoy(char* convoy_id, char* convoy_name);

// Message caching for offline support
bool forj_storage_cache_message(const forj_message_t* msg);
bool forj_storage_retrieve_cached_messages(forj_message_t* msgs, size_t max_count);

Development Tools and Libraries

Required ESP-IDF Components

- esp32 (ESP32 hardware abstraction)
- driver (GPIO, UART, SPI, I2C)
- nvs_flash (non-volatile storage)
- bt (Bluetooth Low Energy)
- freertos (real-time OS)
- lwip (TCP/IP stack)
- mbedtls (cryptography)
- json (JSON parsing)
- esp_timer (high-resolution timers)
- esp_log (logging system)

External Libraries

  • TinyGPS++ - GPS NMEA parsing
  • ArduinoJson - JSON configuration parsing
  • CRC16 - Checksum calculation
  • Base64 - BLE data encoding
  • AES - Encryption/decryption

Development Environment Setup

# Install ESP-IDF
mkdir -p ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32
. ./export.sh

# Create project
mkdir forj-link
cd forj-link
idf.py create-project link
cd link

Project Structure

link/
├── main/
│   ├── main.c                  # Main application entry
│   ├── forj_protocol.c         # Radio protocol implementation
│   ├── forj_radio.c            # Radio hardware interface
│   ├── forj_ble.c              # Bluetooth Low Energy
│   ├── forj_gps.c              # GPS location services
│   ├── forj_storage.c          # Data storage and persistence
│   ├── forj_crypto.c           # Cryptography and security
│   ├── forj_queue.c            # Message queue system
│   └── forj_config.h           # Configuration constants
├── components/
│   ├── radio_driver/           # Radio module driver
│   ├── gps_driver/             # GPS module driver
│   └── crypto_utils/           # Cryptography utilities
├── test/
│   ├── test_protocol.c         # Protocol unit tests
│   ├── test_radio.c            # Radio interface tests
│   └── test_integration.c      # Integration tests
├── docs/
│   ├── hardware_design.md      # Hardware specifications
│   ├── protocol_spec.md        # Protocol documentation
│   └── api_reference.md        # API documentation
├── CMakeLists.txt              # Build configuration
├── sdkconfig                   # ESP-IDF configuration
└── README.md                   # Project documentation

Configuration Management

JSON Configuration Format

{
  "radio": {
    "channel": 15,
    "frequency": 462.575,
    "power_level": 5,
    "squelch_level": 5,
    "ctcss_code": 0,
    "dcs_code": 0,
    "encryption": true
  },
  "convoy": {
    "id": "convoy-uuid-here",
    "name": "Moab Adventure",
    "member_id": "member-uuid-here",
    "member_name": "Trail Rider 1"
  },
  "location": {
    "update_interval": 30,
    "accuracy_threshold": 10,
    "enable_breadcrumbs": true
  },
  "emergency": {
    "auto_broadcast": true,
    "broadcast_interval": 30,
    "emergency_channel": 1
  }
}

Configuration Commands from Mobile App

{
  "type": "RADIO_CONFIG",
  "channel": 15,
  "frequency": 462.575,
  "power_level": 5,
  "squelch_level": 5,
  "ctcss_code": null,
  "encryption": true
}

Emergency System Implementation

Emergency Activation

// Emergency button interrupt handler
void IRAM_ATTR emergency_button_isr(void* arg);

// Emergency system functions
void forj_emergency_activate(uint8_t emergency_type, const char* description);
void forj_emergency_cancel(void);
bool forj_emergency_is_active(void);
void forj_emergency_broadcast_loop(void);

Emergency Broadcast Protocol

  • Immediate transmission on current channel
  • Automatic retransmission every 30 seconds
  • Highest priority in transmission queue
  • Multi-channel emergency broadcast
  • GPS location included in all emergency packets

Congestion Management

Channel Health Monitoring

typedef struct {
    uint8_t channel;
    uint8_t activity_level;         // 0-100%
    int8_t signal_strength;         // -120 to 0 dBm
    uint8_t air_time_utilization;   // 0-100%
    uint8_t interference_level;     // 0-100%
    uint8_t conversation_count;     // Number of active conversations
    uint8_t quality_score;          // 0-100%
} channel_health_t;

Adaptive Transmission

// Congestion avoidance functions
uint32_t forj_calculate_backoff_delay(uint8_t retry_count);
bool forj_channel_is_clear(void);
void forj_update_channel_health(channel_health_t* health);
uint8_t forj_recommend_channel(void);

Security Implementation

Encryption Support

// Encryption functions
bool forj_encrypt_payload(const uint8_t* plaintext, size_t length,
                         uint8_t* ciphertext, const uint8_t* key);
bool forj_decrypt_payload(const uint8_t* ciphertext, size_t length,
                         uint8_t* plaintext, const uint8_t* key);
void forj_generate_convoy_key(const char* convoy_id, uint8_t* key);

Message Authentication

// HMAC message authentication
bool forj_sign_message(const uint8_t* message, size_t length,
                      uint8_t* signature, const uint8_t* key);
bool forj_verify_signature(const uint8_t* message, size_t length,
                          const uint8_t* signature, const uint8_t* key);

Testing and Validation

Unit Testing Framework

// Test framework
#define FORJ_TEST_ASSERT(condition) \
    if (!(condition)) { \
        printf("FAIL: %s:%d - %s\n", __FILE__, __LINE__, #condition); \
        return false; \
    }

// Test functions
bool test_packet_encoding(void);
bool test_location_compression(void);
bool test_radio_interface(void);
bool test_congestion_management(void);
bool test_emergency_system(void);

Integration Testing

  • Mobile App Integration: Test BLE communication with actual mobile app
  • Radio Hardware: Test with actual GMRS radios
  • Multi-Device: Test convoy scenarios with multiple devices
  • Range Testing: Test communication range and reliability
  • Emergency Scenarios: Test emergency activation and broadcasting

Field Testing Protocol

  1. Single Device: GPS, radio transmission, BLE connectivity
  2. Two Device: Point-to-point communication, message relay
  3. Multi-Device: Convoy simulation with 3+ devices
  4. Emergency: Emergency activation and multi-device response
  5. Range Test: Communication range in various terrain
  6. Endurance: Long-term operation and battery life

Current Implementation Status

✅ Completed Components

  • Core Protocol Implementation: Packet encoding/decoding, CRC validation, all packet types
  • Radio Interface Monitoring: 8-channel ADC monitoring, signal classification, change detection
  • Audio Analysis: Voice activity detection, frequency analysis, power measurement
  • System Architecture: FreeRTOS task management, logging, configuration structures
  • Development Environment: ESP-IDF build system, flashing, monitoring

🚧 In Progress

  • RJ45 Pinout Discovery: Using monitoring utility to map Midland MXT275/MXT575 pinouts
  • Power Vampiring: Measuring available power from radio interface
  • Sub-Audible Data Transmission: Tone generation and detection implementation

📋 Planned Components

  • GPS Integration: I2C location services and compressed location format
  • BLE Interface: Mobile app communication and command processing
  • Message Queue System: Priority-based packet handling and transmission
  • Emergency System: Button activation and automatic emergency broadcasting
  • Persistent Storage: Configuration and message caching in flash memory

Build and Deployment

Development Workflow

# Set up ESP-IDF environment
source ~/esp/esp-idf/export.sh

# Configure project (first time only)
idf.py menuconfig

# Build firmware
idf.py build

# Flash to device
idf.py flash -p /dev/cu.usbserial-1430

# Monitor serial output and radio interface
idf.py monitor -p /dev/cu.usbserial-1430

Hardware Setup for Radio Interface

RJ45 Breakout Board Connection

Using a Generic RJ45 Breakout Board (B0D3J6PB4S or similar):

  • Two female RJ45 ports for pass-through connection
  • 16 middle pins for signal access (8 pairs mirrored from each port)
  • 8 pins near each port for direct pin access

Connection Strategy

  1. Pass-through Mode: Connect middle pins together for normal radio operation
  2. Monitoring Mode: Connect ESP32 to middle pins for signal monitoring
  3. Man-in-the-Middle: ESP32 can monitor and inject signals simultaneously

ESP32 to Breakout Board Wiring

ESP32 GPIO32 -> RJ45 Breakout Middle Pin 1 (Power detection)
ESP32 GPIO33 -> RJ45 Breakout Middle Pin 2 (Audio input monitoring)
ESP32 GPIO34 -> RJ45 Breakout Middle Pin 3 (Audio output monitoring)
ESP32 GPIO35 -> RJ45 Breakout Middle Pin 4 (PTT monitoring)
ESP32 GPIO36 -> RJ45 Breakout Middle Pin 5 (Control signal monitoring)
ESP32 GPIO39 -> RJ45 Breakout Middle Pin 6 (Volume/additional control)
ESP32 GPIO25 -> RJ45 Breakout Middle Pin 7 (Data injection - DAC1)
ESP32 GPIO26 -> RJ45 Breakout Middle Pin 8 (Control injection - DAC2)
ESP32 GND    -> Common ground

Current Testing Setup

  1. Protocol Testing: Heartbeat and emergency packet creation, encoding/decoding validation
  2. Radio Monitoring: Real-time voltage monitoring on all RJ45 pins
  3. Audio Analysis: Frequency analysis and signal classification
  4. Power Analysis: Voltage/current measurement for power vampiring feasibility
  5. Pinout Discovery: Using monitoring utility to identify Midland MXT275/MXT575 pin functions

OTA Updates

// Over-the-air update support
bool forj_ota_check_update(void);
bool forj_ota_download_update(const char* url);
bool forj_ota_apply_update(void);
void forj_ota_rollback(void);

Performance Optimization

Memory Management

  • Static allocation for packet buffers
  • Ring buffers for message queues
  • Efficient data structures for convoy member tracking
  • Flash storage for configuration and message caching

Power Management

// Power management functions
void forj_enter_sleep_mode(uint32_t sleep_duration_ms);
void forj_wake_from_sleep(void);
void forj_adjust_tx_power(int8_t rssi);
void forj_optimize_gps_power(void);

Network Optimization

  • Adaptive transmission timing based on channel conditions
  • Message aggregation to reduce air time
  • Efficient routing for multi-hop communication
  • Congestion detection and avoidance

Troubleshooting and Debugging

Debug Logging

// Debug levels
#define FORJ_LOG_ERROR   0
#define FORJ_LOG_WARN    1
#define FORJ_LOG_INFO    2
#define FORJ_LOG_DEBUG   3
#define FORJ_LOG_VERBOSE 4

// Logging macros
#define FORJ_LOGE(tag, format, ...) ESP_LOGE(tag, format, ##__VA_ARGS__)
#define FORJ_LOGW(tag, format, ...) ESP_LOGW(tag, format, ##__VA_ARGS__)
#define FORJ_LOGI(tag, format, ...) ESP_LOGI(tag, format, ##__VA_ARGS__)
#define FORJ_LOGD(tag, format, ...) ESP_LOGD(tag, format, ##__VA_ARGS__)
#define FORJ_LOGV(tag, format, ...) ESP_LOGV(tag, format, ##__VA_ARGS__)

Common Issues and Solutions

  1. BLE Connection Issues: Check service UUIDs and characteristic properties
  2. Radio Transmission Failures: Verify UART configuration and radio module
  3. GPS Accuracy Problems: Check antenna placement and satellite visibility
  4. Power Management: Monitor current consumption and sleep modes
  5. Memory Leaks: Use static allocation and proper cleanup

Future Enhancements

Planned Features

  • Mesh Networking: Multi-hop message relay
  • Voice Integration: Voice message transmission
  • Weather Integration: Weather data sharing
  • Advanced Encryption: Perfect forward secrecy
  • Machine Learning: Predictive congestion management

Hardware Upgrades

  • LoRa Integration: Long-range communication
  • Satellite Connectivity: Emergency satellite backup
  • Advanced GPS: RTK GPS for centimeter accuracy
  • Environmental Sensors: Temperature, humidity, pressure

Getting Started Checklist

Development Environment

  • Install ESP-IDF framework
  • Set up toolchain and build system
  • Configure VS Code or preferred IDE
  • Install required libraries and components

Hardware Setup

  • Obtain ESP32-WROOM-32 development board
  • Connect GMRS radio module (UART/SPI)
  • Connect GPS module (I2C)
  • Add status LEDs and emergency button
  • Set up power management circuit

Initial Implementation

  • Implement basic packet encoding/decoding
  • Create BLE service for mobile app communication
  • Implement GPS location reading
  • Add radio transmission and reception
  • Create message queue system

Testing and Validation

  • Unit tests for protocol functions
  • Integration tests with mobile app
  • Hardware-in-the-loop testing
  • Field testing with multiple devices
  • Emergency scenario testing

Production Readiness

  • Optimize for power consumption
  • Implement security features
  • Add OTA update capability
  • Create manufacturing test suite
  • Document installation and usage

This comprehensive guide provides everything needed to develop the Forj Link ESP32 firmware that seamlessly integrates with the existing mobile application architecture. The firmware will enable reliable convoy communication in off-grid environments while maintaining compatibility with the established protocol and data structures.