first test

This commit is contained in:
richonguzman 2025-01-22 12:47:18 -03:00
parent ae4d5baac2
commit 87ceb9b5a4
8 changed files with 124 additions and 65 deletions

View File

@ -518,13 +518,44 @@
>Enable bluetooth</label >Enable bluetooth</label
> >
</div> </div>
<div class="col-6 mt-1"> <div class="col-12">
<label for="bluetooth.type" class="form-label">Bluetooth Type</label> <label
<select name="bluetooth.type" id="bluetooth.type" class="form-control"> for="bluetooth.deviceName"
<option value="0">BLE for iPhone</option> class="form-label"
<option value="1">BT Classic</option> >Password</label>
<option value="2">BLE for Android</option> <input
</select> name="bluetooth.deviceName"
id="bluetooth.deviceName"
class="form-control"
placeholder="LoRaTracker"
value="LoRaTracker"
/>
</div>
<div class="form-check form-switch">
<input
type="checkbox"
name="bluetooth.useBLE"
id="bluetooth.useBLE"
class="form-check-input"
/>
<label
for="bluetooth.useBLE"
class="form-label"
>Enable = BLE / Disable = BT Classic</label
>
</div>
<div class="form-check form-switch">
<input
type="checkbox"
name="bluetooth.useKISS"
id="bluetooth.useKISS"
class="form-check-input"
/>
<label
for="bluetooth.useKISS"
class="form-label"
>Enable = KISS / Disable = TNC2</label
>
</div> </div>
</div> </div>
</div> </div>

View File

@ -246,7 +246,9 @@ function loadSettings(settings) {
// BLUETOOTH // BLUETOOTH
document.getElementById("bluetooth.active").checked = settings.bluetooth.active; document.getElementById("bluetooth.active").checked = settings.bluetooth.active;
document.getElementById("bluetooth.type").value = settings.bluetooth.type; document.getElementById("bluetooth.deviceName").value = settings.bluetooth.deviceName;
document.getElementById("bluetooth.useBLE").checked = settings.bluetooth.useBLE;
document.getElementById("bluetooth.useKISS").checked = settings.bluetooth.useKISS;
// PTT Trigger // PTT Trigger
document.getElementById("ptt.active").checked = settings.pttTrigger.active; document.getElementById("ptt.active").checked = settings.pttTrigger.active;

View File

@ -91,8 +91,10 @@ public:
class BLUETOOTH { class BLUETOOTH {
public: public:
byte type;
bool active; bool active;
String deviceName;
bool useBLE;
bool useKISS;
}; };

View File

@ -57,7 +57,7 @@ TinyGPSPlus gps;
BluetoothSerial SerialBT; BluetoothSerial SerialBT;
#endif #endif
String versionDate = "2025.01.11"; String versionDate = "2025.01.22";
uint8_t myBeaconsIndex = 0; uint8_t myBeaconsIndex = 0;
int myBeaconsSize = Config.beacons.size(); int myBeaconsSize = Config.beacons.size();
@ -76,6 +76,7 @@ uint32_t refreshDisplayTime = millis();
bool sendUpdate = true; bool sendUpdate = true;
bool bluetoothActive = Config.bluetooth.active;
bool bluetoothConnected = false; bool bluetoothConnected = false;
uint32_t lastTx = 0.0; uint32_t lastTx = 0.0;
@ -136,12 +137,14 @@ void setup() {
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Main", "WiFi controller stopped"); logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Main", "WiFi controller stopped");
if (Config.bluetooth.type == 0 || Config.bluetooth.type == 2) { if (bluetoothActive) {
BLE_Utils::setup(); if (Config.bluetooth.useBLE) {
} else { BLE_Utils::setup();
#ifdef HAS_BT_CLASSIC } else {
BLUETOOTH_Utils::setup(); #ifdef HAS_BT_CLASSIC
#endif BLUETOOTH_Utils::setup();
#endif
}
} }
if (!Config.simplifiedTrackerMode) { if (!Config.simplifiedTrackerMode) {
@ -200,14 +203,16 @@ void loop() {
MSG_Utils::processOutputBuffer(); MSG_Utils::processOutputBuffer();
MSG_Utils::clean15SegBuffer(); MSG_Utils::clean15SegBuffer();
if (Config.bluetooth.type == 0 || Config.bluetooth.type == 2) { if (bluetoothActive) {
BLE_Utils::sendToPhone(packet.text.substring(3)); if (Config.bluetooth.useBLE) {
BLE_Utils::sendToLoRa(); BLE_Utils::sendToPhone(packet.text.substring(3));
} else { BLE_Utils::sendToLoRa();
#ifdef HAS_BT_CLASSIC } else {
BLUETOOTH_Utils::sendToPhone(packet.text.substring(3)); #ifdef HAS_BT_CLASSIC
BLUETOOTH_Utils::sendToLoRa(); BLUETOOTH_Utils::sendToPhone(packet.text.substring(3));
#endif BLUETOOTH_Utils::sendToLoRa();
#endif
}
} }
MSG_Utils::ledNotification(); MSG_Utils::ledNotification();

View File

@ -15,23 +15,23 @@
#define CHARACTERISTIC_UUID_RX_0 "00000002-ba2a-46c9-ae49-01b0961f68bb" #define CHARACTERISTIC_UUID_RX_0 "00000002-ba2a-46c9-ae49-01b0961f68bb"
// ANDROID - BLE Terminal app (Serial Bluetooth Terminal from Playstore) // ANDROID - BLE Terminal app (Serial Bluetooth Terminal from Playstore)
#define SERVICE_UUID_2 "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" #define SERVICE_UUID_1 "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX_2 "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_TX_1 "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_RX_2 "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_RX_1 "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
BLEServer *pServer; BLEServer *pServer;
BLECharacteristic *pCharacteristicTx; BLECharacteristic *pCharacteristicTx;
BLECharacteristic *pCharacteristicRx; BLECharacteristic *pCharacteristicRx;
extern Configuration Config; extern Configuration Config;
extern Beacon *currentBeacon; extern Beacon *currentBeacon;
extern logging::Logger logger; extern logging::Logger logger;
extern bool bluetoothConnected; extern bool bluetoothConnected;
extern bool bluetoothActive;
bool shouldSendBLEtoLoRa = false; bool shouldSendBLEtoLoRa = false;
String BLEToLoRaPacket = ""; String BLEToLoRaPacket = "";
String kissSerialBuffer = "";
String kissSerialBuffer = "";
class MyServerCallbacks : public NimBLEServerCallbacks { class MyServerCallbacks : public NimBLEServerCallbacks {
@ -52,7 +52,7 @@ class MyServerCallbacks : public NimBLEServerCallbacks {
class MyCallbacks : public NimBLECharacteristicCallbacks { class MyCallbacks : public NimBLECharacteristicCallbacks {
void onWrite(NimBLECharacteristic *pCharacteristic) { void onWrite(NimBLECharacteristic *pCharacteristic) {
if (Config.bluetooth.type == 0) { // AX25 KISS if (Config.bluetooth.useKISS) { // KISS (AX.25)
std::string receivedData = pCharacteristic->getValue(); std::string receivedData = pCharacteristic->getValue();
delay(100); delay(100);
for (int i = 0; i < receivedData.length(); i++) { for (int i = 0; i < receivedData.length(); i++) {
@ -72,7 +72,7 @@ class MyCallbacks : public NimBLECharacteristicCallbacks {
} }
} }
} }
} else if (Config.bluetooth.type == 2) { // TNC2 } else { // TNC2
std::string receivedData = pCharacteristic->getValue(); std::string receivedData = pCharacteristic->getValue();
String receivedString = ""; String receivedString = "";
for (int i = 0; i < receivedData.length(); i++) receivedString += receivedData[i]; for (int i = 0; i < receivedData.length(); i++) receivedString += receivedData[i];
@ -90,22 +90,21 @@ namespace BLE_Utils {
} }
void setup() { void setup() {
String id = currentBeacon->callsign; String BLEid = Config.bluetooth.deviceName;
String BLEid = id.substring(0, id.indexOf("-")) + "-BLE";
BLEDevice::init(BLEid.c_str()); BLEDevice::init(BLEid.c_str());
pServer = BLEDevice::createServer(); pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks()); pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = nullptr; BLEService *pService = nullptr;
if (Config.bluetooth.type == 0) { if (Config.bluetooth.useKISS) { // KISS (AX.25)
pService = pServer->createService(SERVICE_UUID_0); pService = pServer->createService(SERVICE_UUID_0);
pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_0, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_0, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_0, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_0, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
} else if (Config.bluetooth.type == 2) { } else { // TNC2
pService = pServer->createService(SERVICE_UUID_2); pService = pServer->createService(SERVICE_UUID_1);
pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_2, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_1, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_2, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR); pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_1, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
} }
if (pService != nullptr) { if (pService != nullptr) {
@ -114,10 +113,10 @@ namespace BLE_Utils {
BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
if (Config.bluetooth.type == 0) { if (Config.bluetooth.useKISS) {
pAdvertising->addServiceUUID(SERVICE_UUID_0); pAdvertising->addServiceUUID(SERVICE_UUID_0);
} else if (Config.bluetooth.type == 2) { } else {
pAdvertising->addServiceUUID(SERVICE_UUID_2); pAdvertising->addServiceUUID(SERVICE_UUID_1);
} }
pServer->getAdvertising()->setScanResponse(true); pServer->getAdvertising()->setScanResponse(true);
pServer->getAdvertising()->setMinPreferred(0x06); pServer->getAdvertising()->setMinPreferred(0x06);
@ -125,7 +124,7 @@ namespace BLE_Utils {
pAdvertising->start(); pAdvertising->start();
logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BLE", "%s", "Waiting for BLE central to connect..."); logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BLE", "%s", "Waiting for BLE central to connect...");
} else { } else {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "BLE", "Failed to create BLE service. Invalid bluetoothType: %d", Config.bluetooth.type); logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "BLE", "Failed to create BLE service");
} }
} }
@ -155,7 +154,7 @@ namespace BLE_Utils {
} }
void txToPhoneOverBLE(const String& frame) { void txToPhoneOverBLE(const String& frame) {
if (Config.bluetooth.type == 0) { // AX25 KISS if (Config.bluetooth.useKISS) { // KISS (AX.25)
const String kissEncodedFrame = KISS_Utils::encodeKISS(frame); const String kissEncodedFrame = KISS_Utils::encodeKISS(frame);
const char* t = kissEncodedFrame.c_str(); const char* t = kissEncodedFrame.c_str();
@ -171,7 +170,7 @@ namespace BLE_Utils {
delete[] chunk; delete[] chunk;
delay(200); delay(200);
} }
} else { // TNC2 } else { // TNC2
for (int n = 0; n < frame.length(); n++) txBLE(frame[n]); for (int n = 0; n < frame.length(); n++) txBLE(frame[n]);
txBLE('\n'); txBLE('\n');
} }

View File

@ -14,16 +14,14 @@ extern BluetoothSerial SerialBT;
extern logging::Logger logger; extern logging::Logger logger;
extern TinyGPSPlus gps; extern TinyGPSPlus gps;
extern bool bluetoothConnected; extern bool bluetoothConnected;
extern bool bluetoothActive;
bool bluetoothActive;
namespace BLUETOOTH_Utils { namespace BLUETOOTH_Utils {
String serialReceived; String serialReceived;
bool shouldSendToLoRa = false; bool shouldSendToLoRa = false;
bool useKiss = false; bool useKiss = Config.bluetooth.useKISS? true : false;
void setup() { void setup() {
bluetoothActive = Config.bluetooth.active;
if (!bluetoothActive) { if (!bluetoothActive) {
btStop(); btStop();
esp_bt_controller_disable(); esp_bt_controller_disable();
@ -36,8 +34,7 @@ namespace BLUETOOTH_Utils {
SerialBT.register_callback(BLUETOOTH_Utils::bluetoothCallback); SerialBT.register_callback(BLUETOOTH_Utils::bluetoothCallback);
SerialBT.onData(BLUETOOTH_Utils::getData); // callback instead of while to avoid RX buffer limit when NMEA data received SerialBT.onData(BLUETOOTH_Utils::getData); // callback instead of while to avoid RX buffer limit when NMEA data received
String id = currentBeacon->callsign; String BTid = Config.bluetooth.deviceName;
String BTid = id.substring(0, id.indexOf("-")) + "-BT";
if (!SerialBT.begin(String(BTid))) { if (!SerialBT.begin(String(BTid))) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Bluetooth", "Starting Bluetooth failed!"); logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Bluetooth", "Starting Bluetooth failed!");
@ -53,7 +50,6 @@ namespace BLUETOOTH_Utils {
if (event == ESP_SPP_SRV_OPEN_EVT) { if (event == ESP_SPP_SRV_OPEN_EVT) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client connected !"); logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client connected !");
bluetoothConnected = true; bluetoothConnected = true;
useKiss = false;
} else if (event == ESP_SPP_CLOSE_EVT) { } else if (event == ESP_SPP_CLOSE_EVT) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client disconnected !"); logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client disconnected !");
bluetoothConnected = false; bluetoothConnected = false;
@ -63,9 +59,7 @@ namespace BLUETOOTH_Utils {
} }
void getData(const uint8_t *buffer, size_t size) { void getData(const uint8_t *buffer, size_t size) {
if (size == 0) { if (size == 0) return;
return;
}
shouldSendToLoRa = false; shouldSendToLoRa = false;
serialReceived.clear(); serialReceived.clear();
bool isNmea = buffer[0] == '$'; bool isNmea = buffer[0] == '$';
@ -111,7 +105,7 @@ namespace BLUETOOTH_Utils {
} }
void sendToPhone(const String& packet) { void sendToPhone(const String& packet) {
if (!packet.isEmpty() && bluetoothActive) { if (!packet.isEmpty()) {
if (useKiss) { if (useKiss) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BT RX Kiss", "%s", serialReceived.c_str()); logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BT RX Kiss", "%s", serialReceived.c_str());
SerialBT.println(KISS_Utils::encodeKISS(packet)); SerialBT.println(KISS_Utils::encodeKISS(packet));

View File

@ -1,6 +1,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <SPIFFS.h> #include <SPIFFS.h>
#include "configuration.h" #include "configuration.h"
#include "board_pinout.h"
#include "display.h" #include "display.h"
#include "logger.h" #include "logger.h"
@ -75,8 +76,14 @@ void Configuration::writeFile() {
data["pttTrigger"]["postDelay"] = ptt.postDelay; data["pttTrigger"]["postDelay"] = ptt.postDelay;
data["pttTrigger"]["reverse"] = ptt.reverse; data["pttTrigger"]["reverse"] = ptt.reverse;
data["bluetooth"]["type"] = bluetooth.type;
data["bluetooth"]["active"] = bluetooth.active; data["bluetooth"]["active"] = bluetooth.active;
data["bluetooth"]["deviceName"] = bluetooth.deviceName;
#ifdef HAS_BT_CLASSIC
data["bluetooth"]["useBLE"] = bluetooth.useBLE;
#else
data["bluetooth"]["useBLE"] = true; // fixed as BLE
#endif
data["bluetooth"]["useKISS"] = bluetooth.useKISS;
data["other"]["simplifiedTrackerMode"] = simplifiedTrackerMode; data["other"]["simplifiedTrackerMode"] = simplifiedTrackerMode;
data["other"]["sendCommentAfterXBeacons"] = sendCommentAfterXBeacons; data["other"]["sendCommentAfterXBeacons"] = sendCommentAfterXBeacons;
@ -175,8 +182,15 @@ bool Configuration::readFile() {
ptt.postDelay = data["pttTrigger"]["postDelay"] | 0; ptt.postDelay = data["pttTrigger"]["postDelay"] | 0;
ptt.reverse = data["pttTrigger"]["reverse"] | false; ptt.reverse = data["pttTrigger"]["reverse"] | false;
bluetooth.type = data["bluetooth"]["type"] | 1;
bluetooth.active = data["bluetooth"]["active"] | false; bluetooth.active = data["bluetooth"]["active"] | false;
bluetooth.deviceName = data["bluetooth"]["deviceName"] | "LoRaTracker";
#ifdef HAS_BT_CLASSIC
bluetooth.useBLE = data["bluetooth"]["useBLE"] | false;
bluetooth.useKISS = data["bluetooth"]["useKISS"] | false;
#else
bluetooth.useBLE = true; // fixed as BLE
bluetooth.useKISS = data["bluetooth"]["useKISS"] | true; // true=KISS, false=TNC2
#endif
simplifiedTrackerMode = data["other"]["simplifiedTrackerMode"] | false; simplifiedTrackerMode = data["other"]["simplifiedTrackerMode"] | false;
sendCommentAfterXBeacons = data["other"]["sendCommentAfterXBeacons"] | 10; sendCommentAfterXBeacons = data["other"]["sendCommentAfterXBeacons"] | 10;
@ -299,8 +313,15 @@ void Configuration::init() {
ptt.postDelay = 0; ptt.postDelay = 0;
ptt.reverse = false; ptt.reverse = false;
bluetooth.type = 1;
bluetooth.active = false; bluetooth.active = false;
bluetooth.deviceName = "LoRaTracker";
#ifdef HAS_BT_CLASSIC
bluetooth.useBLE = false;
bluetooth.useKISS = false;
#else
bluetooth.useBLE = true; // fixed as BLE
bluetooth.useKISS = true;
#endif
simplifiedTrackerMode = false; simplifiedTrackerMode = false;
sendCommentAfterXBeacons = 10; sendCommentAfterXBeacons = 10;

View File

@ -179,7 +179,9 @@ namespace WEB_Utils {
// Bluetooth // Bluetooth
Config.bluetooth.active = request->hasParam("bluetooth.active", true); Config.bluetooth.active = request->hasParam("bluetooth.active", true);
Config.bluetooth.type = request->getParam("bluetooth.type", true)->value().toInt(); Config.bluetooth.deviceName = request->getParam("bluetooth.deviceName", true)->value();
Config.bluetooth.useBLE = request->hasParam("bluetooth.useBLE", true);
Config.bluetooth.useKISS = request->hasParam("bluetooth.useKISS", true);
// PTT Trigger // PTT Trigger
Config.ptt.active = request->hasParam("ptt.active", true); Config.ptt.active = request->hasParam("ptt.active", true);
@ -190,7 +192,10 @@ namespace WEB_Utils {
// WiFi AP // WiFi AP
Config.wifiAP.password = request->getParam("wifiAP.password", true)->value(); Config.wifiAP.password = request->getParam("wifiAP.password", true)->value();
Config.wifiAP.active = false; // when Configuration is finished Tracker returns to normal mode.
//
Config.wifiAP.active = true;
//Config.wifiAP.active = false; // when Configuration is finished Tracker returns to normal mode.
Config.writeFile(); Config.writeFile();