PiBle Design Tips

PiBle is an adapter interface tool for transfer from Raspberry Pi to Unity via Windows PC using BLE (Bluetooth low energy). By connecting the sensor device (gyro, accelerometer, GPS, etc.) with Raspberry Pi you can input various sense data to Unity. You can also output various data from Unity by connecting the display device (LED, LCD panel, etc.) with Raspberry Pi. This design tip explains how to modify for transfer data between Unity and Raspberry Pi based on the purchased Unity script example and the purchased Raspberry Pi code. PiBle transfers array data up to 64 bytes from Unity to Raspberry Pi and array data up to 64 bytes from Raspberry Pi to Unity by changing the Unity script example and the Raspberry Pi code.

1. How to transfer data from Raspberry Pi to Unity
1.1 How to set up data to Unity in Raspberry Pi
1.2 How to get data from Raspberry Pi in Unity
2. How to transfer data from Unity to Raspberry Pi
2.1 How to set up data to Raspberry Pi in Unity
2.2 How to get data from Unity in Raspberry Pi

1. How to transfer data from Raspberry Pi to Unity

1.1 How to set up data to Unity in Raspberry Pi

The Raspberry Pi code ‘pible-v2.py’ generates 3D Object‘glasses’ tilt data ‘x, y, z’ using the ‘math.sin’ function and convert it to strings using the ‘format’ function. The Raspberry Pi code needs to change the strings to byte array data type using ‘str(formatted_msg).encode’ function for sending data to Unity when Raspberry Pi connects some sensors device.

   …

def generatedata():
    x = 0.12
    y = 0.13
    z = 0.14
    for degx in range(-40, 40, 10):
        x = math.sin(math.radians(degx))
        for degy in range(-30, 30, 5):
            y = math.sin(math.radians(degy))
            formatted_msg = "{:.3f},{:.3f},{:.3f}".format(x, y, z)
            print(formatted_msg)
            value = str(formatted_msg).encode()
            print(value)
            if tomosoftCharacteristic_read._updateValueCallback:
                tomosoftCharacteristic_read._updateValueCallback(data=value)
                time.sleep(0.3)
            else:
                return

    return

   …

The Raspberry Pi code ‘pible-v2.py’ calls the ‘encode()’ function in the following format for sending byte array data type to Unity. The ‘encode’ function encodes the string, using the specified encoding.

string.encode(encoding=encoding, errors=errors)

1.2 How to get data from Raspberry Pi in Unity

Unity script example ‘PiBleSampleCode.cs’ receives BLE data from Raspberry Pi as byte array data ‘readdata’ of return value of ‘m_Pi32BleLib.UpdateRead’ function. The byte array data ‘readdata’ encodes string code using ‘System.Text.Encoding.UTF8.GetString’ function and, using ‘text.Split’ function and ‘float.Parse’ function, the string code is converted to float position data.

       ...

// Update is called once per frame
void Update()
{
    byte[] readdata = new byte[] { };
    //UnityEngine.Debug.LogWarning("Update");
    if (!m_PiBleLib.UpdateRead(ref readdata))
    {
        return;
    }
    UnityEngine.Debug.LogWarning(" Read1: " + readdata[0] + " " + readdata[1] + " " + readdata[2]); 
    UnityEngine.Debug.LogWarning(" Read2: " + readdata.Length);

    string text = System.Text.Encoding.UTF8.GetString(readdata);
    UnityEngine.Debug.LogWarning(" Read3: " + text);
    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);
}
       ...

Unity script example ‘PiBleSampleCode.cs’ calls the ‘UpdateRead’ function in the following format for reading data from Raspberry Pi.

bool UpdateRead(ref byte[] readdata)

2. How to transfer data from Unity to Raspberry Pi

2.1 How to set up data to Raspberry Pi in Unity

Unity script example ‘PiBleSampleCode.cs’ calls back ‘ButtonClick’ function at button ‘On’ clicked. ‘ButtonClick’ function inputs data from ’inputFieldno0’ / ‘inputFieldno1’, then calls ‘m_PiBleLib.Command’ function with the parameter of ‘writedata’ byte array.

   …
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]);
    m_PiBleLib.Command(writedata);
}
   …

Unity script example ‘PiBleSampleCode.cs’ calls the ‘Command’ function in the following format for sending byte array data to Raspberry Pi.

 
void Command(byte[] writedata);

2.2 How to get data from Unity in Raspberry Pi

The Raspberry Pi code ‘pible-v2.py’calls back ‘onWrite’ function at received data from Unity. The ‘onWriteReques’ function receives Inputfield ’No0’ / Inputfield ‘No1’ of Unity as 2 bytes of data using the parameter ‘data’ of the ‘onWriteReques’ function.

   …
class PiBleCharacteristic(Characteristic):

   …

    def onWriteRequest(self, data, offset, withoutResponse, callback):
        self._value = data

        #print('EchoCharacteristic - %s - onWriteRequest: value = %s' % (self['uuid'], [hex(c) for c in self._value]))
        print("************** receive data! ******************")
        print(self._value[0])
        print(self._value[1])

        if self._updateValueCallback:
            #pass
            #print('EchoCharacteristic - onWriteRequest: notifying');

            self._updateValueCallback(self._value)

        callback(Characteristic.RESULT_SUCCESS)   …

The Raspberry Pi code ‘pible-v2.py’ sets byte array data in the parameter ‘data’ of the ‘onWriteReques’ function for receiving from Unity in the following format.

self._value [x]

x: byte array index