Esp32Ble Design Tips

Esp32Ble is an adapter interface tool designed to bridge an ESP32 and Unity via a Windows PC using BLE (Bluetooth Low Energy).

By connecting sensors (gyroscope, accelerometer, GPS, etc.) to the ESP32, you can send real-time data to Unity. Conversely, you can send data from Unity to the ESP32 to control output devices like LEDs or LCD panels. This guide explains how to customize the data transmission logic by modifying the provided Unity scripts and ESP32 code.

Data Specifications
Payload Data: byte array (Converted ASCII code).
Direction: Bi-directional (ESP32 to Unity / Unity to ESP32).

1. Data Transmission: ESP32 to Unity

1.1 Preparing Data on ESP32

The sample code “esp32ble-v2.1.ino” generates dummy tilt data (x, y, z) for a 3D object ‘Glasses’ using the “sin” function. To send sensor data, you must convert your values into a byte array via the ” pCharacteristic->setValue ” function.

Customize the data transmission logic:

  ・・・
// notify changed value
if (deviceConnected) {
  x = motion_table[value].azimuth;
  y = motion_table[value].elevation;
  dtostrf(x, 4, 2, sx);
  dtostrf(y, 4, 2, sy);

  sprintf(formatted_msg, "%s,%s,%s,", sx, sy, z);
  Serial.println(formatted_msg);

  String saccel = String(formatted_msg);
  //Serial.println(saccel);
  byte sbyte[saccel.length()];
  saccel.getBytes(sbyte, saccel.length() + 1);

  pCharacteristic->setValue(sbyte, saccel.length());
  pCharacteristic->notify();
    ・・・

Function Signature:

void pCharacteristic->setValue(byte[] sbyte, int length);

1.2 Receiving Data in Unity

The Unity script example “Esp32BleSampleCode.cs” receives the BLE data from ESP32 as a byte array “readdata” via the “m_Esp32BleLib.UpdateRead” function. The data is then decoded from UTF-8 to a string and parsed into float values using the “text.Split” and “float.Parse” functions.

Customize the data transmission logic:

    ・・・
// Update is called once per frame
void Update()
{
    string readdata = null;
    //UnityEngine.Debug.LogWarning("Update");
    try
    {
        if (!Esp32BleLib_v2_1.Esp32BleLib_v2_1.UpdateRead(ref readdata))
        {
            return;
        }
        //UnityEngine.Debug.LogWarning(" Read1: " + readdata);

        //string input = "45484653484448464857444846495244";
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < readdata.Length; i += 2)
        {
            string part = readdata.Substring(i, 2);

            int code = int.Parse(part);
            sb.Append((char)code);
        }
        //UnityEngine.Debug.LogWarning(" Read3: " + sb.ToString());

        string text = sb.ToString();
        string[] arr = text.Split(',');
        float[] acceldata = new float[3];
        acceldata[0] = float.Parse(arr[0]);
        acceldata[1] = float.Parse(arr[1]);
        acceldata[2] = float.Parse(arr[2]);

        UnityEngine.Debug.LogWarning(" Update: " + acceldata[0] + " " + acceldata[1] + " " + acceldata[2]);

        accelx = acceldata[0] * 100;
        accely = acceldata[1] * 100;
        accelz = acceldata[2] * 100;

        transform.rotation = Quaternion.AngleAxis(accelx, Vector3.up) * Quaternion.AngleAxis(accely, Vector3.right);
    }
    ・・・

Function Signature:

bool m_Esp32BleLib.UpdateRead(ref byte[] readdata);

2. Data Transmission: Unity to ESP32

2.1 Sending Data from Unity

In “Esp32BleSampleCode.cs”, the “ButtonClick” function is triggered when the On button is clicked. It retrieves values from “inputFieldno0” and “inputFieldno1”, then calls the “m_Esp32BleLib.Command” function with the “writedata” byte array as a parameter.

Customize the data transmission logic:

    ・・・
public void ButtonClick()
{
    UnityEngine.Debug.LogWarning("ButtonClick: ");

    byte[] writedata = new byte[2] { byte.Parse(inputFieldno0.text), byte.Parse(inputFieldno1.text) };
    UnityEngine.Debug.LogWarning(writedata[0] + " " + writedata[1]);
    Esp32BleLib_v2_1.Esp32BleLib_v2_1.Command(writedata);
}
    ・・・

Function Signature:

void Esp32BleLib_v2_1.Command(byte[] writedata);

2.2 Receiving Data on ESP32

The ESP32 code “esp32ble-v2.1.ino” handles incoming data via the “onWrite” callback function. It receives the data sent from Unity using the “pCharacteristic->getValue” function.

Customize the data transmission logic:

class RxCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic* pCharacteristic) {
    // std::string rxValue = pCharacteristic->getValue();
    byte row = pCharacteristic->getValue()[0];
    byte col = pCharacteristic->getValue()[1];
    Serial.println("************** receive data! ******************");
    Serial.println(row);
    Serial.println(col);
  }
};

Function Signature:

byte value = pCharacteristic->getValue()[index]; 
 (Where "index" is the position in the byte array)