Hi
I am try to read GPS data from ESP32 using the BLEExample
I can not get the raw NMEA data
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
** Activity (main) Resume **
Starting scan...
Target device found: ESP32_BLE_GPS (1C:C3:AB
1:45:9E)
Connecting to: 1C:C3:AB
1:45:9E
Discovering services.
Connected. Waiting for GATT table to stabilize...
--- Starting Read Data ---
Total services to read: 3
Requesting data for Service UUID: 00001801-0000-1000-8000-00805f9b34fb
Requesting data for Service UUID: 00001800-0000-1000-8000-00805f9b34fb
Requesting data for Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
--- Read Request Completed ---
RAW DATA RECEIVED: ESP32_BLE_GPS
Buffer contents: ESP32_BLE_GPS
RAW DATA RECEIVED: ����
Buffer contents: ESP32_BLE_GPS����
RAW DATA RECEIVED: ��
Buffer contents: ESP32_BLE_GPS������
This is the Arduino code
I am try to read GPS data from ESP32 using the BLEExample
I can not get the raw NMEA data
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
** Activity (main) Resume **
Starting scan...
Target device found: ESP32_BLE_GPS (1C:C3:AB
Connecting to: 1C:C3:AB
Discovering services.
Connected. Waiting for GATT table to stabilize...
--- Starting Read Data ---
Total services to read: 3
Requesting data for Service UUID: 00001801-0000-1000-8000-00805f9b34fb
Requesting data for Service UUID: 00001800-0000-1000-8000-00805f9b34fb
Requesting data for Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
--- Read Request Completed ---
RAW DATA RECEIVED: ESP32_BLE_GPS
Buffer contents: ESP32_BLE_GPS
RAW DATA RECEIVED: ����
Buffer contents: ESP32_BLE_GPS����
RAW DATA RECEIVED: ��
Buffer contents: ESP32_BLE_GPS������
This is the Arduino code
B4X:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
// UART configuration for ESP32-WROOM-32
#define RX1_PIN 16 // GPS TX -> ESP32 RX
#define TX1_PIN 17 // GPS RX <- ESP32 TX
// Device name
const char* bleName = "ESP32_BLE_GPS";
const int ledPin = 2;
// BLE UUIDs for Nordic UART Service
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
BLEServer* pServer = NULL;
BLECharacteristic* pTxCharacteristic = NULL;
BLECharacteristic* pRxCharacteristic = NULL;
bool bleDeviceConnected = false;
bool oldBleDeviceConnected = false;
unsigned long uartBaudrate = 460800; // ✅ CORRECT BAUD RATE!
void blinkLED(uint32_t millis) {
digitalWrite(ledPin, HIGH);
delay(millis);
digitalWrite(ledPin, LOW);
}
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
bleDeviceConnected = true;
Serial.println("🔵 BLE device connected.");
};
void onDisconnect(BLEServer* pServer) {
bleDeviceConnected = false;
Serial.println("🔴 BLE device disconnected.");
pServer->startAdvertising();
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic* pCharacteristic) override {
String value = pCharacteristic->getValue();
if (value.length() > 0) {
Serial.println("\n📱 BLE -> ESP32:");
Serial1.write((uint8_t*)value.c_str(), value.length());
blinkLED(10);
}
}
};
void uartTask(void *pvParameters) {
static char line[256];
static int pos = 0;
while (1) {
// 1. FAST READ: Pull every single byte out of the hardware buffer
while (Serial1.available()) {
char c = Serial1.read();
if (c == '$') {
pos = 0;
}
if (pos < 255) {
line[pos++] = c;
} else {
pos = 0;
}
// 2. PARSE: Only when we hit the end of a line
if (c == '\n') {
line[pos] = '\0';
// --- SEND TO BLE ---
if (bleDeviceConnected) {
pTxCharacteristic->setValue((uint8_t*)line, pos);
pTxCharacteristic->notify();
}
// --- EFFICIENT PARSING (Zero String Objects) ---
// Check for GNGGA or GPGGA using strncmp
if (line[0] == '$' && (strncmp(line, "$GNGGA", 6) == 0 || strncmp(line, "$GPGGA", 6) == 0)) {
// Pointer arithmetic to find the 6th comma (Fix Quality)
int commaCount = 0;
char* ptr = line;
char* fixPtr = NULL;
while (*ptr && commaCount < 6) {
if (*ptr == ',') commaCount++;
ptr++;
}
if (commaCount == 6) {
fixPtr = ptr;
int fixQuality = *fixPtr - '0'; // Convert char to int
Serial.println("--- GPS STATUS ---");
Serial.print("Fix Quality: ");
switch(fixQuality) {
case 4: Serial.println("RTK FIX"); break;
case 5: Serial.println("RTK FLOAT"); break;
case 1: Serial.println("GPS FIX"); break;
default: Serial.println("NO FIX / INVALID");
}
// For other fields like satellites, you could continue using
// similar pointer arithmetic if needed.
Serial.println("------------------");
}
}
pos = 0; // Reset buffer
}
}
// Minimal delay to allow other tasks to run
vTaskDelay(1 / portTICK_PERIOD_MS);
}
}
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("\n--- BLE Bridge Starting ---");
// Initialize GPS Serial at 460800 baud
Serial1.begin(uartBaudrate, SERIAL_8N1, RX1_PIN, TX1_PIN);
Serial.println("✅ UART initialized at 460800 baud!");
pinMode(ledPin, OUTPUT);
BLEDevice::init(bleName);
Serial.println("✅ BLE initialized");
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService* pService = pServer->createService(SERVICE_UUID);
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pTxCharacteristic->addDescriptor(new BLE2902());
pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pRxCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinInterval(160);
pAdvertising->setMaxInterval(160);
pAdvertising->start();
Serial.println("✅ BLE advertising started!");
Serial.println("📱 Device: " + String(bleName));
xTaskCreatePinnedToCore(uartTask, "UART Task", 8192, NULL, 1, NULL, 1);
}
void loop() {
if (bleDeviceConnected && !oldBleDeviceConnected) {
oldBleDeviceConnected = bleDeviceConnected;
Serial.println("\n🎉 BLE CONNECTED! 🎉");
blinkLED(200);
}
if (!bleDeviceConnected && oldBleDeviceConnected) {
oldBleDeviceConnected = bleDeviceConnected;
pServer->startAdvertising();
Serial.println("\n⚠️ BLE disconnected, advertising restarted...");
}
delay(10);
}