Send data from react native to ttgo t-display using BLE

Problem:

I’m trying to send data from a React Native app to my TTGO T-Display using Bluetooth communication. However, whenever I send a string (e.g., “John”), the TTGO T-Display receives garbled data (e.g., e&g instead of “John”).

What I have tried:

I’ve experimented with different encoding methods and data types, but none seem to resolve the issue.

React Native Code:

    let connectedDevice = null;

    function stringToBase64(str) {
        return btoa(unescape(encodeURIComponent(str)));
    }

    try {
        const isReady = await prepareBluetooth();
        if (!isReady) {
            console.error("Bluetooth voorbereiding mislukt.");
            return;
        }

        const TTGO_T_DISPLAY_UUID = '4fafc201-1fb5-459e-8fcc-c5c9c331914b';
        const TTGO_T_DISPLAY_Characteristic_UUID = 'beb5483e-36e1-4688-b7f5-ea07361b26a8';

        const scanAndConnectDevice = new Promise((resolve, reject) => {
            manager.startDeviceScan(null, null, async (error, device) => {
                if (error) {
                    console.error(error);
                    reject(error);
                    return;
                }

                if (device.name === 'TTGO_T_Display') {
                    console.log('Apparaat gevonden: ', device.name);

                    try {
                        manager.stopDeviceScan();
                        const isConnected = await device.isConnected();
                        if (isConnected) {
                            console.log('Device already connected.');
                            resolve(device);
                            return;
                        }

                        connectedDevice = await device.connect();
                        console.log('Succesvol verbonden met ', device.name);

                        await connectedDevice.discoverAllServicesAndCharacteristics();
                        resolve(connectedDevice);

                    } catch (err) {
                        console.error('Fout bij verbinden met device:', err);
                        reject(err);
                    }
                }
            });
        });

        const device = await scanAndConnectDevice;

        if (color) {
            const colorRGB = convertToColor(color);
            if (Array.isArray(colorRGB) && colorRGB.length === 3) {
                const [r, g, b] = colorRGB;
                const colorInt = (r << 16) | (g << 8) | b;
                const colorHex = colorInt.toString(16).padStart(6, '0').toUpperCase();

                await device.writeCharacteristicWithResponseForService(
                    TTGO_T_DISPLAY_UUID,
                    TTGO_T_DISPLAY_Characteristic_UUID,
                    colorHex
                );

                console.log('Kleur verzonden naar TTGO T-display:', colorHex);
            } else {
                console.error('Ongeldige kleurarray:', colorRGB);
            }
        }

        if (voornaam) {
            try {
                console.log('Bezig met verzenden van voornaam:', voornaam);
                await device.writeCharacteristicWithResponseForService(
                    TTGO_T_DISPLAY_UUID,
                    TTGO_T_DISPLAY_Characteristic_UUID,
                    voornaam
                );
                console.log('Voornaam succesvol verzonden naar TTGO T-display:', voornaam);
            } catch (error) {
                console.error('Fout bij het verzenden van de voornaam:', error);
            }
        }

        if (medicijnNaam) {
            try {
                let encodedMedicijnNaam = stringToBase64(medicijnNaam);
                await device.writeCharacteristicWithResponseForService(
                    TTGO_T_DISPLAY_UUID,
                    TTGO_T_DISPLAY_Characteristic_UUID,
                    encodedMedicijnNaam
                );
                console.log('Medicijnnaam succesvol verzonden naar TTGO T-display:', medicijnNaam);
            } catch (error) {
                console.error('Fout bij het verzenden van de medicijnNaam:', error);
            }
        }

        if (notitie) {
            try {
                let encodedNotitie = stringToBase64(notitie);
                await device.writeCharacteristicWithResponseForService(
                    TTGO_T_DISPLAY_UUID,
                    TTGO_T_DISPLAY_Characteristic_UUID,
                    encodedNotitie
                );
                console.log('Notitie succesvol verzonden naar TTGO T-display:', notitie);
            } catch (error) {
                console.error('Fout bij het verzenden van de notitie:', error);
            }
        }

    } catch (error) {
        console.warn('Fout tijdens scannen en verbinden:', error);
    } finally {
        if (connectedDevice) {
            try {
                await connectedDevice.cancelConnection();
                console.log('Verbinding geannuleerd.');
            } catch (err) {
                console.error('Fout bij annuleren van de verbinding:', err);
            }
        }
    }
}

```scanAndConnect(null, null, "John", null);
TTGO T-Display Code:

```#include <BLEDevice.h>
   #include <BLEUtils.h>
#include <BLEServer.h>
#include <TFT_eSPI.h>

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

TFT_eSPI tft = TFT_eSPI();
uint16_t currentColor = TFT_BLACK;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
        // Wanneer apparaat verbindt
    }

    void onDisconnect(BLEServer* pServer) {
        // Wanneer apparaat loskoppelt
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
        std::string value = pCharacteristic->getValue();
        if (value.length() > 0) {
            // Vergelijk ontvangen bytes met verwachte hex-waarden
            // (implement logic here)
        }
    }
};

void setup() {
    Serial.begin(9600);
    tft.begin();
    tft.setRotation(1);
    tft.fillScreen(currentColor);

    BLEDevice::init("TTGO_T_Display");
    BLEServer *pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());
    BLEService *pService = pServer->createService(SERVICE_UUID);
    BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
    pCharacteristic->setCallbacks(new MyCallbacks());
    pService->start();
    BLEAdvertising *pAdvertising = pServer->getAdvertising();
    pAdvertising->start();
}

void loop() {
    // (implement loop logic here)
```}
Expected Behavior:

I expect that when I send the string "John" from my React Native app, the TTGO T-Display should receive and display "John".

Question:

Does anyone know why the data is getting garbled and how I can ensure that the data is correctly received and displayed on the TTGO T-Display?