pleasedontcode

# Wireless Relay rev_03

Mar 12th, 2026
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 21.44 KB | None | 0 0
  1. /********* Pleasedontcode.com **********
  2.  
  3.     Pleasedontcode thanks you for automatic code generation! Enjoy your code!
  4.  
  5.     - Terms and Conditions:
  6.     You have a non-exclusive, revocable, worldwide, royalty-free license
  7.     for personal and commercial use. Attribution is optional; modifications
  8.     are allowed, but you're responsible for code maintenance. We're not
  9.     liable for any loss or damage. For full terms,
  10.     please visit pleasedontcode.com/termsandconditions.
  11.  
  12.     - Project: # Wireless Relay
  13.     - Version: 003
  14.     - Source Code NOT compiled for: Firebeetle 2 ESP32-S3
  15.     - Source Code created on: 2026-03-12 12:35:36
  16.  
  17. ********* Pleasedontcode.com **********/
  18.  
  19. /****** SYSTEM REQUIREMENTS *****/
  20. /****** SYSTEM REQUIREMENT 1 *****/
  21.     /* Receive radio station data on GPIO47/48 (115200 */
  22.     /* baud) and transmit to active channel (Bluetooth or */
  23.     /* LoRa). Device name DMR-Radio with random 4-digit */
  24.     /* suffix. PIN 8800 required */
  25. /****** SYSTEM REQUIREMENT 2 *****/
  26.     /* LoRa SX1262: 433 MHz, SF8, 250 kHz. Bidirectional */
  27.     /* TX/RX. Receive LoRa data and transmit to radio and */
  28.     /* Bluetooth */
  29. /****** SYSTEM REQUIREMENT 3 *****/
  30.     /* GPIO0 long press (7000ms) toggles between */
  31.     /* Bluetooth and LoRa modes. Display current mode on */
  32.     /* Heltec built-in screen */
  33. /****** SYSTEM REQUIREMENT 4 *****/
  34.     /* Bidirectional data flow: Radio ↔ Active Channel */
  35.     /* (Bluetooth or LoRa). LoRa RX data → Radio and */
  36.     /* Bluetooth. Bluetooth RX data → Radio and LoRa TX */
  37. /****** END SYSTEM REQUIREMENTS *****/
  38.  
  39.  
  40. /****** DEFINITION OF LIBRARIES *****/
  41. #include <BluetoothSerial.h>
  42. #include <SPI.h>
  43. #include <LoRa.h>
  44. #include <Wire.h>
  45. #include "heltec.h"
  46.  
  47. /****** DEFINITION OF CONSTANTS *****/
  48. // Heltec ESP32-S3 Pin Definitions
  49. #define GPIO0_BUTTON_PIN 0          // GPIO0 button for mode toggle
  50. #define SERIAL2_RX_PIN 47           // GPIO47 for Serial2 RX (from radio station)
  51. #define SERIAL2_TX_PIN 48           // GPIO48 for Serial2 TX (to radio station)
  52. #define SERIAL2_BAUDRATE 115200
  53.  
  54. // LoRa SX1262 Pin Configuration (Heltec ESP32-S3)
  55. #define LORA_CS_PIN 8               // Chip Select
  56. #define LORA_RST_PIN 12             // Reset
  57. #define LORA_IRQ_PIN 14             // Interrupt
  58. #define LORA_BUSY_PIN 13            // Busy
  59. #define LORA_MOSI_PIN 10            // MOSI
  60. #define LORA_MISO_PIN 9             // MISO
  61. #define LORA_SCK_PIN 11             // SCK
  62.  
  63. // LoRa Configuration Constants
  64. #define LORA_FREQUENCY 433000000    // 433 MHz
  65. #define LORA_SPREADING_FACTOR 8     // SF8
  66. #define LORA_BANDWIDTH 250000        // 250 kHz (125000, 250000, or 500000)
  67. #define LORA_CODING_RATE 5          // 4/5
  68. #define LORA_PREAMBLE_LENGTH 8
  69. #define LORA_SYNC_WORD 0x34
  70.  
  71. // Button and Mode Configuration
  72. #define BUTTON_LONG_PRESS_TIME 7000 // 7 seconds for long press (mode toggle)
  73. #define BUTTON_DEBOUNCE_TIME 50     // Debounce time in milliseconds
  74. #define DISPLAY_UPDATE_INTERVAL 500 // Update display every 500ms
  75.  
  76. // Bluetooth Configuration
  77. #define BLUETOOTH_PIN_CODE "8800"
  78. #define BLUETOOTH_DEVICE_NAME_BASE "DMR-Radio"
  79.  
  80. // LoRa Message Configuration
  81. #define LORA_RX_BUFFER_SIZE 256
  82. #define LORA_TX_TIMEOUT 3000
  83.  
  84. /****** DEFINITION OF GLOBAL VARIABLES *****/
  85. // Bluetooth Serial object
  86. BluetoothSerial SerialBT;
  87. bool bluetoothPinSet = false;
  88. bool bluetoothConnected = false;
  89.  
  90. // Mode selection: true = Bluetooth mode, false = LoRa mode
  91. volatile bool currentMode = true; // Start in Bluetooth mode
  92. bool previousMode = true;
  93.  
  94. // Button state management
  95. volatile unsigned long buttonPressStartTime = 0;
  96. volatile bool buttonPressed = false;
  97. volatile bool buttonLongPressDetected = false;
  98. unsigned long lastButtonCheckTime = 0;
  99. bool previousButtonState = HIGH;
  100.  
  101. // LoRa variables
  102. uint8_t loraRxBuffer[LORA_RX_BUFFER_SIZE];
  103. int loraRxLength = 0;
  104. bool loraPacketReceived = false;
  105.  
  106. // Display and status variables
  107. unsigned long lastDisplayUpdate = 0;
  108. uint32_t packetsSentBluetooth = 0;
  109. uint32_t packetsReceivedBluetooth = 0;
  110. uint32_t packetsSentLoRa = 0;
  111. uint32_t packetsReceivedLoRa = 0;
  112. uint32_t packetsReceivedRadio = 0;
  113. uint32_t packetsSentRadio = 0;
  114. char bluetoothDeviceName[32];
  115.  
  116. /****** FUNCTION PROTOTYPES *****/
  117. void setup(void);
  118. void loop(void);
  119. void initializeDisplay(void);
  120. void updateDisplay(void);
  121. void initializeLoRa(void);
  122. void initializeBluetooth(void);
  123. void checkButtonInput(void);
  124. void toggleMode(void);
  125. void setBluetoothPin(const char* pinCode);
  126. void handleSerialFromRadio(void);
  127. void handleBluetoothFromClient(void);
  128. void handleLoRaReceive(void);
  129. void sendDataToRadio(const uint8_t* data, size_t length);
  130. void sendDataToBluetooth(const uint8_t* data, size_t length);
  131. void sendDataViaLoRa(const uint8_t* data, size_t length);
  132. void loraOnReceive(int packetSize);
  133. void displayBluetoothMode(void);
  134. void displayLoRaMode(void);
  135. void generateRandomSuffix(void);
  136.  
  137. /****** HELTEC DISPLAY FUNCTIONS *****/
  138. /**
  139.  * initializeDisplay() - Initialize Heltec built-in display
  140.  *
  141.  * Sets up the OLED display connected to the Heltec ESP32-S3 board.
  142.  * Initializes I2C communication and configures display parameters.
  143.  */
  144. void initializeDisplay(void)
  145. {
  146.     // Initialize Heltec board display (SSD1306 OLED)
  147.     Heltec.begin(true /* DisplayEnable */, false /* LoRaEnable */);
  148.     Heltec.display->setFont(ArialMT_Plain_10);
  149.     Heltec.display->clear();
  150.     Heltec.display->drawString(0, 0, "Wireless Bridge");
  151.     Heltec.display->drawString(0, 12, "Initializing...");
  152.     Heltec.display->display();
  153.    
  154.     Serial.println("Heltec display initialized");
  155.     delay(500);
  156. }
  157.  
  158. /**
  159.  * generateRandomSuffix() - Generate a random 4-digit suffix for Bluetooth device name
  160.  *
  161.  * Creates a random 4-digit number and appends it to the Bluetooth device name base.
  162.  * This ensures unique device names across multiple devices.
  163.  */
  164. void generateRandomSuffix(void)
  165. {
  166.     // Generate random 4-digit suffix (1000-9999)
  167.     uint16_t randomSuffix = random(1000, 10000);
  168.     sprintf(bluetoothDeviceName, "%s-%04d", BLUETOOTH_DEVICE_NAME_BASE, randomSuffix);
  169.    
  170.     Serial.print("Generated Bluetooth device name: ");
  171.     Serial.println(bluetoothDeviceName);
  172. }
  173.  
  174. /**
  175.  * displayBluetoothMode() - Display Bluetooth mode information on screen
  176.  *
  177.  * Shows current mode status, connection state, and statistics on the OLED display.
  178.  */
  179. void displayBluetoothMode(void)
  180. {
  181.     Heltec.display->clear();
  182.     Heltec.display->setFont(ArialMT_Plain_16);
  183.     Heltec.display->drawString(0, 0, "MODE: BLUETOOTH");
  184.    
  185.     Heltec.display->setFont(ArialMT_Plain_10);
  186.    
  187.     // Display connection status
  188.     if (bluetoothConnected && SerialBT.hasClient())
  189.     {
  190.         Heltec.display->drawString(0, 18, "Status: CONNECTED");
  191.     }
  192.     else
  193.     {
  194.         Heltec.display->drawString(0, 18, "Status: WAITING...");
  195.     }
  196.    
  197.     // Display device name
  198.     Heltec.display->drawString(0, 28, bluetoothDeviceName);
  199.    
  200.     // Display PIN requirement
  201.     Heltec.display->drawString(0, 38, "PIN: 8800");
  202.    
  203.     // Display statistics
  204.     char stats[32];
  205.     sprintf(stats, "Sent: %lu", packetsSentBluetooth);
  206.     Heltec.display->drawString(0, 48, stats);
  207.    
  208.     sprintf(stats, "Recv: %lu", packetsReceivedBluetooth);
  209.     Heltec.display->drawString(64, 48, stats);
  210.    
  211.     Heltec.display->drawString(0, 58, "Press GPIO0 (7s) to switch");
  212.    
  213.     Heltec.display->display();
  214. }
  215.  
  216. /**
  217.  * displayLoRaMode() - Display LoRa mode information on screen
  218.  *
  219.  * Shows current mode status, LoRa configuration, and statistics on the OLED display.
  220.  */
  221. void displayLoRaMode(void)
  222. {
  223.     Heltec.display->clear();
  224.     Heltec.display->setFont(ArialMT_Plain_16);
  225.     Heltec.display->drawString(0, 0, "MODE: LORA");
  226.    
  227.     Heltec.display->setFont(ArialMT_Plain_10);
  228.    
  229.     // Display LoRa configuration
  230.     Heltec.display->drawString(0, 18, "433MHz SF8 250kHz");
  231.     Heltec.display->drawString(0, 28, "Listening...");
  232.    
  233.     // Display statistics
  234.     char stats[32];
  235.     sprintf(stats, "TX: %lu", packetsSentLoRa);
  236.     Heltec.display->drawString(0, 38, stats);
  237.    
  238.     sprintf(stats, "RX: %lu", packetsReceivedLoRa);
  239.     Heltec.display->drawString(64, 38, stats);
  240.    
  241.     sprintf(stats, "Radio: %lu", packetsReceivedRadio);
  242.     Heltec.display->drawString(0, 48, stats);
  243.    
  244.     sprintf(stats, "Sent: %lu", packetsSentRadio);
  245.     Heltec.display->drawString(64, 48, stats);
  246.    
  247.     Heltec.display->drawString(0, 58, "Press GPIO0 (7s) to switch");
  248.    
  249.     Heltec.display->display();
  250. }
  251.  
  252. /**
  253.  * updateDisplay() - Update display based on current mode
  254.  *
  255.  * Periodically refreshes the OLED display with current mode information
  256.  * and statistics. Called from main loop at regular intervals.
  257.  */
  258. void updateDisplay(void)
  259. {
  260.     unsigned long currentTime = millis();
  261.    
  262.     // Update display at defined interval
  263.     if ((currentTime - lastDisplayUpdate) >= DISPLAY_UPDATE_INTERVAL)
  264.     {
  265.         lastDisplayUpdate = currentTime;
  266.        
  267.         if (currentMode)
  268.         {
  269.             displayBluetoothMode();
  270.         }
  271.         else
  272.         {
  273.             displayLoRaMode();
  274.         }
  275.     }
  276. }
  277.  
  278. /****** LORA FUNCTIONS *****/
  279. /**
  280.  * initializeLoRa() - Initialize LoRa SX1262 module
  281.  *
  282.  * Configures SPI pins, initializes LoRa library, and sets up parameters
  283.  * for 433 MHz operation with SF8 spreading factor and 250 kHz bandwidth.
  284.  */
  285. void initializeLoRa(void)
  286. {
  287.     Serial.println("Initializing LoRa SX1262...");
  288.    
  289.     // Configure SPI pins for LoRa module
  290.     SPI.begin(LORA_SCK_PIN, LORA_MISO_PIN, LORA_MOSI_PIN, LORA_CS_PIN);
  291.    
  292.     // Initialize LoRa with appropriate pins for SX1262
  293.     LoRa.setPins(LORA_CS_PIN, LORA_RST_PIN, LORA_IRQ_PIN);
  294.     LoRa.setSPI(SPI);
  295.    
  296.     // Begin LoRa with 433 MHz frequency
  297.     if (!LoRa.begin(LORA_FREQUENCY))
  298.     {
  299.         Serial.println("ERROR: Failed to initialize LoRa module!");
  300.         Heltec.display->clear();
  301.         Heltec.display->drawString(0, 20, "LoRa Init Failed!");
  302.         Heltec.display->display();
  303.         return;
  304.     }
  305.    
  306.     // Configure LoRa parameters
  307.     LoRa.setSpreadingFactor(LORA_SPREADING_FACTOR);
  308.     LoRa.setSignalBandwidth(LORA_BANDWIDTH);
  309.     LoRa.setCodingRate4(LORA_CODING_RATE);
  310.     LoRa.setPreambleLength(LORA_PREAMBLE_LENGTH);
  311.     LoRa.setSyncWord(LORA_SYNC_WORD);
  312.     LoRa.enableCrc();
  313.    
  314.     // Set receiver gain
  315.     LoRa.setGain(6);
  316.    
  317.     // Register callback for incoming packets
  318.     LoRa.onReceive(loraOnReceive);
  319.    
  320.     // Start receiving
  321.     LoRa.receive();
  322.    
  323.     Serial.println("LoRa initialized successfully:");
  324.     Serial.println("  Frequency: 433 MHz");
  325.     Serial.println("  Spreading Factor: SF8");
  326.     Serial.println("  Bandwidth: 250 kHz");
  327.     Serial.println("  Coding Rate: 4/5");
  328.     Serial.println("  Preamble Length: 8");
  329.     Serial.println("  Sync Word: 0x34");
  330.     Serial.println("  CRC: Enabled");
  331. }
  332.  
  333. /**
  334.  * loraOnReceive() - LoRa interrupt callback for packet reception
  335.  *
  336.  * Called when LoRa module detects an incoming packet. Reads packet data
  337.  * into buffer and sets flag for main loop processing.
  338.  *
  339.  * @param packetSize - Number of bytes in the received packet
  340.  */
  341. void loraOnReceive(int packetSize)
  342. {
  343.     if (packetSize <= 0) return;
  344.    
  345.     // Limit packet size to buffer capacity
  346.     if (packetSize > LORA_RX_BUFFER_SIZE)
  347.     {
  348.         packetSize = LORA_RX_BUFFER_SIZE;
  349.     }
  350.    
  351.     // Read packet into buffer
  352.     loraRxLength = 0;
  353.     while (LoRa.available() && loraRxLength < packetSize)
  354.     {
  355.         loraRxBuffer[loraRxLength++] = LoRa.read();
  356.     }
  357.    
  358.     // Set flag to indicate packet received
  359.     loraPacketReceived = true;
  360.     packetsReceivedLoRa++;
  361.    
  362.     Serial.print("LoRa packet received: ");
  363.     Serial.print(loraRxLength);
  364.     Serial.println(" bytes");
  365.    
  366.     // Resume receiving
  367.     LoRa.receive();
  368. }
  369.  
  370. /**
  371.  * sendDataViaLoRa() - Transmit data via LoRa
  372.  *
  373.  * Sends a buffer of data through the LoRa SX1262 module. Includes error
  374.  * handling and transmission status feedback.
  375.  *
  376.  * @param data - Pointer to data buffer to send
  377.  * @param length - Number of bytes to send
  378.  */
  379. void sendDataViaLoRa(const uint8_t* data, size_t length)
  380. {
  381.     if (data == NULL || length == 0)
  382.     {
  383.         Serial.println("ERROR: Invalid LoRa TX data (NULL or zero length)");
  384.         return;
  385.     }
  386.    
  387.     if (length > LORA_RX_BUFFER_SIZE)
  388.     {
  389.         Serial.println("ERROR: LoRa TX data too large");
  390.         return;
  391.     }
  392.    
  393.     // Begin LoRa packet transmission
  394.     LoRa.beginPacket();
  395.    
  396.     // Write data to packet
  397.     LoRa.write(data, length);
  398.    
  399.     // End packet and wait for transmission
  400.     if (LoRa.endPacket(true)) // true = wait for transmission
  401.     {
  402.         packetsSentLoRa++;
  403.         Serial.print("LoRa TX success: ");
  404.         Serial.print(length);
  405.         Serial.println(" bytes");
  406.     }
  407.     else
  408.     {
  409.         Serial.println("ERROR: LoRa transmission failed");
  410.     }
  411.    
  412.     // Resume receiving after transmission
  413.     LoRa.receive();
  414. }
  415.  
  416. /**
  417.  * handleLoRaReceive() - Process received LoRa packets
  418.  *
  419.  * Checks if a LoRa packet was received, and forwards it to both
  420.  * the radio station (Serial2) and Bluetooth client (if connected).
  421.  */
  422. void handleLoRaReceive(void)
  423. {
  424.     // Check if a LoRa packet was received
  425.     if (!loraPacketReceived) return;
  426.    
  427.     loraPacketReceived = false;
  428.    
  429.     // Forward LoRa data to radio station via Serial2
  430.     for (int i = 0; i < loraRxLength; i++)
  431.     {
  432.         Serial2.write(loraRxBuffer[i]);
  433.     }
  434.     packetsReceivedRadio++;
  435.    
  436.     // Forward LoRa data to Bluetooth client if connected
  437.     if (SerialBT.hasClient())
  438.     {
  439.         for (int i = 0; i < loraRxLength; i++)
  440.         {
  441.             SerialBT.write(loraRxBuffer[i]);
  442.         }
  443.         packetsReceivedBluetooth++;
  444.     }
  445.    
  446.     Serial.print("LoRa->Radio+BT: ");
  447.     Serial.print(loraRxLength);
  448.     Serial.println(" bytes");
  449. }
  450.  
  451. /****** BLUETOOTH FUNCTIONS *****/
  452. /**
  453.  * initializeBluetooth() - Initialize Bluetooth Classic SPP
  454.  *
  455.  * Sets up Bluetooth Serial with generated device name and PIN authentication.
  456.  */
  457. void initializeBluetooth(void)
  458. {
  459.     Serial.println("Initializing Bluetooth Classic SPP...");
  460.    
  461.     // Generate random suffix for device name
  462.     generateRandomSuffix();
  463.    
  464.     // Initialize Bluetooth with generated device name
  465.     if (SerialBT.begin(bluetoothDeviceName))
  466.     {
  467.         Serial.print("Bluetooth initialized as: ");
  468.         Serial.println(bluetoothDeviceName);
  469.     }
  470.     else
  471.     {
  472.         Serial.println("ERROR: Failed to initialize Bluetooth");
  473.         return;
  474.     }
  475.    
  476.     // Set PIN code for authentication
  477.     setBluetoothPin(BLUETOOTH_PIN_CODE);
  478.    
  479.     Serial.println("Bluetooth waiting for authenticated connections...");
  480. }
  481.  
  482. /**
  483.  * setBluetoothPin() - Set PIN code for Bluetooth authentication
  484.  *
  485.  * Configures the PIN (8800) that clients must provide during pairing
  486.  * to connect to this device.
  487.  *
  488.  * @param pinCode - PIN code string (e.g., "8800")
  489.  */
  490. void setBluetoothPin(const char* pinCode)
  491. {
  492.     if (pinCode == NULL)
  493.     {
  494.         Serial.println("ERROR: PIN code is NULL");
  495.         return;
  496.     }
  497.    
  498.     if (strlen(pinCode) < 4 || strlen(pinCode) > 16)
  499.     {
  500.         Serial.print("ERROR: Invalid PIN code length: ");
  501.         Serial.println(strlen(pinCode));
  502.         return;
  503.     }
  504.    
  505.     if (SerialBT.setPin(pinCode))
  506.     {
  507.         bluetoothPinSet = true;
  508.         Serial.print("Bluetooth PIN set to: ");
  509.         Serial.println(pinCode);
  510.     }
  511.     else
  512.     {
  513.         bluetoothPinSet = false;
  514.         Serial.print("ERROR: Failed to set Bluetooth PIN: ");
  515.         Serial.println(pinCode);
  516.     }
  517. }
  518.  
  519. /**
  520.  * sendDataToBluetooth() - Send data to Bluetooth client
  521.  *
  522.  * Transmits data to connected Bluetooth client (SPP mode).
  523.  *
  524.  * @param data - Pointer to data buffer
  525.  * @param length - Number of bytes to send
  526.  */
  527. void sendDataToBluetooth(const uint8_t* data, size_t length)
  528. {
  529.     if (data == NULL || length == 0) return;
  530.    
  531.     // Only send if client is connected
  532.     if (SerialBT.hasClient())
  533.     {
  534.         SerialBT.write(data, length);
  535.         packetsSentBluetooth++;
  536.     }
  537. }
  538.  
  539. /**
  540.  * handleBluetoothFromClient() - Process data from Bluetooth client
  541.  *
  542.  * Reads incoming data from Bluetooth client and forwards it to:
  543.  * - Radio station (Serial2) in both Bluetooth and LoRa modes
  544.  * - LoRa module (if in LoRa mode)
  545.  */
  546. void handleBluetoothFromClient(void)
  547. {
  548.     // Check if data is available from Bluetooth client
  549.     while (SerialBT.available() > 0)
  550.     {
  551.         uint8_t byteBT = SerialBT.read();
  552.        
  553.         // Forward to radio station
  554.         Serial2.write(byteBT);
  555.         packetsReceivedRadio++;
  556.        
  557.         // Forward to LoRa if in LoRa mode
  558.         if (!currentMode)
  559.         {
  560.             // In LoRa mode, accumulate bytes into a packet
  561.             // For simplicity, send immediately (can be optimized with buffering)
  562.             uint8_t loraPacket[1] = {byteBT};
  563.             sendDataViaLoRa(loraPacket, 1);
  564.         }
  565.        
  566.         Serial.print("BT->Radio");
  567.         if (!currentMode) Serial.print("+LoRa");
  568.         Serial.print(": 0x");
  569.         Serial.println(byteBT, HEX);
  570.     }
  571.    
  572.     // Update Bluetooth connection status
  573.     bluetoothConnected = SerialBT.hasClient();
  574. }
  575.  
  576. /****** BUTTON FUNCTIONS *****/
  577. /**
  578.  * checkButtonInput() - Monitor GPIO0 button for long press (mode toggle)
  579.  *
  580.  * Detects 7-second long press on GPIO0 to toggle between Bluetooth and LoRa modes.
  581.  * Includes debounce logic to prevent false triggers.
  582.  */
  583. void checkButtonInput(void)
  584. {
  585.     unsigned long currentTime = millis();
  586.    
  587.     // Debounce check
  588.     if ((currentTime - lastButtonCheckTime) < BUTTON_DEBOUNCE_TIME) return;
  589.     lastButtonCheckTime = currentTime;
  590.    
  591.     // Read current button state (active LOW on GPIO0)
  592.     bool currentButtonState = digitalRead(GPIO0_BUTTON_PIN);
  593.    
  594.     // Detect button press (transition from HIGH to LOW)
  595.     if (previousButtonState == HIGH && currentButtonState == LOW)
  596.     {
  597.         buttonPressed = true;
  598.         buttonPressStartTime = currentTime;
  599.         Serial.println("Button pressed (GPIO0)");
  600.     }
  601.    
  602.     // Detect button release (transition from LOW to HIGH)
  603.     if (previousButtonState == LOW && currentButtonState == HIGH)
  604.     {
  605.         if (buttonPressed)
  606.         {
  607.             unsigned long pressDuration = currentTime - buttonPressStartTime;
  608.            
  609.             // Check for long press (>= 7 seconds)
  610.             if (pressDuration >= BUTTON_LONG_PRESS_TIME)
  611.             {
  612.                 if (!buttonLongPressDetected)
  613.                 {
  614.                     buttonLongPressDetected = true;
  615.                     toggleMode();
  616.                 }
  617.             }
  618.            
  619.             buttonPressed = false;
  620.             buttonLongPressDetected = false;
  621.         }
  622.     }
  623.    
  624.     previousButtonState = currentButtonState;
  625. }
  626.  
  627. /**
  628.  * toggleMode() - Toggle between Bluetooth and LoRa modes
  629.  *
  630.  * Switches active communication mode between Bluetooth Classic SPP
  631.  * and LoRa SX1262. Updates mode indicator and reinitializes relevant
  632.  * peripherals.
  633.  */
  634. void toggleMode(void)
  635. {
  636.     currentMode = !currentMode;
  637.    
  638.     Serial.println("\n=== MODE TOGGLE ===");
  639.     Serial.print("New Mode: ");
  640.     Serial.println(currentMode ? "BLUETOOTH" : "LORA");
  641.    
  642.     if (currentMode)
  643.     {
  644.         // Switched to Bluetooth mode
  645.         Serial.println("Bluetooth mode active - ready for client connections");
  646.        
  647.         // Resume LoRa receiver if switching away from it
  648.         LoRa.receive();
  649.     }
  650.     else
  651.     {
  652.         // Switched to LoRa mode
  653.         Serial.println("LoRa mode active - 433MHz SF8 250kHz listening");
  654.        
  655.         // Ensure LoRa is initialized and receiving
  656.         LoRa.receive();
  657.     }
  658.    
  659.     // Update display
  660.     updateDisplay();
  661. }
  662.  
  663. /****** RADIO SERIAL FUNCTIONS *****/
  664. /**
  665.  * sendDataToRadio() - Send data to radio station via Serial2
  666.  *
  667.  * Transmits data to the connected radio station on GPIO47/48 at 115200 baud.
  668.  *
  669.  * @param data - Pointer to data buffer
  670.  * @param length - Number of bytes to send
  671.  */
  672. void sendDataToRadio(const uint8_t* data, size_t length)
  673. {
  674.     if (data == NULL || length == 0) return;
  675.    
  676.     for (size_t i = 0; i < length; i++)
  677.     {
  678.         Serial2.write(data[i]);
  679.     }
  680.     packetsSentRadio++;
  681. }
  682.  
  683. /**
  684.  * handleSerialFromRadio() - Process data from radio station
  685.  *
  686.  * Reads incoming data from radio station (Serial2) and forwards it to:
  687.  * - Bluetooth client (if connected and in Bluetooth mode)
  688.  * - LoRa module (if in LoRa mode)
  689.  */
  690. void handleSerialFromRadio(void)
  691. {
  692.     // Check if data is available from radio station on Serial2
  693.     while (Serial2.available() > 0)
  694.     {
  695.         uint8_t byteRadio = Serial2.read();
  696.         packetsReceivedRadio++;
  697.        
  698.         // Forward to active channel based on current mode
  699.         if (currentMode)
  700.         {
  701.             // Bluetooth mode: forward to Bluetooth client
  702.             if (SerialBT.hasClient())
  703.             {
  704.                 SerialBT.write(byteRadio);
  705.                 packetsSentBluetooth++;
  706.             }
  707.         }
  708.         else
  709.         {
  710.             // LoRa mode: accumulate for LoRa transmission
  711.             // For simplicity, send single bytes (can be optimized with buffering)
  712.             uint8_t loraPacket[1] = {byteRadio};
  713.             sendDataViaLoRa(loraPacket, 1);
  714.         }
  715.        
  716.         Serial.print("Radio->");
  717.         Serial.println(currentMode ? "BT" : "LoRa");
  718.     }
  719. }
  720.  
  721. /****** SETUP FUNCTION *****/
  722. /**
  723.  * setup() - Initialize all peripherals and subsystems
  724.  *
  725.  * Performs complete initialization of:
  726.  * - Serial communication (USB debug)
  727.  * - Heltec display
  728.  * - GPIO0 button
  729.  * - Serial2 for radio station communication
  730.  * - Bluetooth Classic SPP
  731.  * - LoRa SX1262 module
  732.  */
  733. void setup(void)
  734. {
  735.     // Initialize USB serial for debug output
  736.     Serial.begin(115200);
  737.     delay(1000);
  738.    
  739.     Serial.println("\n\n=== Heltec ESP32-S3 Wireless Bridge ===");
  740.     Serial.println("LoRa SX1262 + Bluetooth + Radio Station");
  741.     Serial.println("433MHz LoRa, Bluetooth Classic SPP, GPIO0 Mode Toggle");
  742.    
  743.     // Initialize Heltec display (I2C: GPIO21=SDA, GPIO22=SCL by default)
  744.     initializeDisplay();
  745.    
  746.     // Configure GPIO0 as input (button)
  747.     pinMode(GPIO0_BUTTON_PIN, INPUT_PULLUP);
  748.     Serial.println("GPIO0 button configured (7s long press to toggle mode)");
  749.    
  750.     // Initialize Serial2 for radio station communication (GPIO47=RX, GPIO48=TX)
  751.     Serial2.begin(SERIAL2_BAUDRATE, SERIAL_8N1, SERIAL2_RX_PIN, SERIAL2_TX_PIN);
  752.     Serial.println("Serial2 initialized for radio station");
  753.     Serial.print("  RX Pin: GPIO");
  754.     Serial.print(SERIAL2_RX_PIN);
  755.     Serial.print(", TX Pin: GPIO");
  756.     Serial.print(SERIAL2_TX_PIN);
  757.     Serial.print(", Baud: ");
  758.     Serial.println(SERIAL2_BAUDRATE);
  759.    
  760.     // Initialize Bluetooth Classic SPP
  761.     initializeBluetooth();
  762.    
  763.     // Initialize LoRa SX1262
  764.     initializeLoRa();
  765.    
  766.     Serial.println("\n=== Initialization Complete ===");
  767.     Serial.println("Starting in Bluetooth mode");
  768.     Serial.println("Current mode: BLUETOOTH");
  769.     Serial.println("Button (GPIO0): 7s long press to toggle to LoRa mode\n");
  770.    
  771.     // Initial display update
  772.     lastDisplayUpdate = 0;
  773.     updateDisplay();
  774. }
  775.  
  776. /****** MAIN LOOP FUNCTION *****/
  777. /**
  778.  * loop() - Main processing loop
  779.  *
  780.  * Continuously processes:
  781.  * - GPIO0 button input for mode toggle
  782.  * - Radio station data (Serial2)
  783.  * - Bluetooth client data
  784.  * - LoRa received packets
  785.  * - Display updates
  786.  *
  787.  * Implements bidirectional data flow between radio, Bluetooth, and LoRa.
  788.  */
  789. void loop(void)
  790. {
  791.     // Monitor GPIO0 button for 7-second long press (mode toggle)
  792.     checkButtonInput();
  793.    
  794.     // Process radio station data (forward to active channel)
  795.     handleSerialFromRadio();
  796.    
  797.     // Process Bluetooth client data (forward to radio and LoRa)
  798.     handleBluetoothFromClient();
  799.    
  800.     // Process LoRa received packets (forward to radio and Bluetooth)
  801.     handleLoRaReceive();
  802.    
  803.     // Update display with current mode and statistics
  804.     updateDisplay();
  805.    
  806.     // Small delay to prevent overwhelming processor
  807.     delay(10);
  808. }
  809.  
  810. /* END CODE */
  811.  
Advertisement
Add Comment
Please, Sign In to add comment