PicoHID Design Tips

PicoHID is an adapter interface tool for transfer from Raspberry Pi Pico to Unity via Windows PC using BLE (Bluetooth low energy). By connecting the sensor device (gyro, accelerometer, GPS, etc.) with Raspberry Pi Pico 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 Pico. This design tip explains how to modify for transfer data between Unity and Raspberry Pi Pico based on the purchased Unity script example and the purchased Raspberry Pi Pico code. PicoHID transfers array data up to 64 bytes from Unity to Raspberry Pi Pico and array data up to 64 bytes from Raspberry Pi Pico to Unity by changing the Unity script example and the Raspberry Pi Pico code.

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

1. How to transfer data from Raspberry Pi Pico to Unity

1.1 How to set up data to Unity in Raspberry Pi Pico

The code ‘picohid-v2.ino’ on Raspberry Pi Pico generates 3D object position data in ‘x’, ‘y’, and ‘z’ with trigonometric functions. This data is then stored in variables ‘sin_value’, ‘cos_value’, and ‘angle_value’. When the Raspberry Pi Pico is connected to a sensor device, the sample code needs to be modified to correspond to the input methods from the sensors. The sample code converts the 3D object position data to a fixed9 bytes fixed data. The ‘usb_hid.sendReport’ function sends this 9-byte fixed data using USB HID.

void loop()
{
   …
  Rad = (double)angle / (180.0 / PI);
  sin_value = sin(Rad) * (double)127.0;
  cos_value = cos(Rad) * (double)127.0;
  angle_value = (double)angle / (double)3;
 
  …
   angle += 5;
  if (360 <= angle) {
    angle = 0;
  }

  gp[0] = 123;
  gp[1] = angle_value;
  gp[2] = sin_value;
  gp[3] = cos_value;
  gp[4] = 1;
  gp[5] = 2;
  gp[6] = 3;
  gp[7] = 4;
  gp[8] = 5;
   …
 
  usb_hid.sendReport(0, &gp, sizeof(gp));
  delay(300);
}
   …

The Raspberry Pi Pico code ‘picohid-v2.ino’ calls the ‘sendReport function in the following format for sending data to Unity.

  
void sendReport (uint8_t id, uint8_t const* data, uint32_t len);

1.2 How to get data from Raspberry Pi Pico in Unity

Unity script example ‘PicoHIDSampleCode.cs’ receives HID data from Raspberry Pi Pico in array data ‘hiddata.’ The byte array data ‘hiddata[0] – [8]’ store the Hid data from Raspberry Pi Pico. This sample code converts each received data ‘x’ or ‘y’ (28 data) to ‘signed char’ (-128 to 127), then sets up ‘x’ ‘y’ and ‘z’ into the variable ‘transform.localPosition.’

       …

// Update is called once per frame
void Update()
{
    byte[] hiddata = new byte[bufferSize];
    //UnityEngine.Debug.LogWarning("Update");
    if (!m_PicoHIDLib.UpdateRead(ref hiddata))
    {
        return;
    }

     …

    if (x <= 128)
    {
        x /= 127;

    }
    else
    {
        x = -(255 - x) / 127;
    }

    y = hiddata[3];
    if (y <= 128)
    {
        y /= 127;

    }
    else
    {
        y = -(255 - y) / 127;
    }


    z = hiddata[1];
    if (z < beforevalue)
    {
        downcnt = (downcnt + 1) % 2;
    }
    beforevalue = z;
    if (downcnt == 0)
    {
        z = (z * 10) / 120;
    }
    else
    {
        z = max - ((z * 10) / 120);
    }

    UnityEngine.Debug.LogWarning(" x y z : " + x + " " + y + " " + z);

    Vector3 m_pos = transform.localPosition;
    m_pos.x = 5 * x;
    m_pos.y = 5 * y;
    m_pos.z = z;
    transform.localPosition = m_pos;
}
       ...

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

bool UpdateRead(ref byte[] readdata)

2. How to transfer data from Unity to Raspberry Pi Pico

2.1 How to set up data to Raspberry Pi Pico in Unity

Unity script example ‘PicoHIDSampleCode.cs’ call back ‘ButtonClick’ function at button ‘On’ clicked. ‘ButtonClick’ function inputs data from ’inputFieldno0’ / ‘inputFieldno1’, then calls ‘m_PicoHILib.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_PicoHIDLib.Command(writedata);
}
   …

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

 
void Command(byte[] writedata);

2.2 How to get data from Unity in Raspberry Pi Pico

The Raspberry Pi Pico code ‘picohid-v2.ino’calls back ‘set_report_callback’ function at received data from Unity. The ‘set_report_callback’ function receives Inputfield ’No0’ / Inputfield ‘No1’ of Unity as 2 bytes of data using ‘uint8_t const*’data type.

   …

// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void set_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
  byte no0 =   *buffer  ;
  byte no1 =   *(buffer + 1) ;
  Serial.println("************** receive data! ******************");
  Serial.println(no0);
  Serial.println(no1);

  // This example doesn't use multiple report and report ID
  (void) report_id;
  (void) report_type;
}
   …

The Raspberry Pi Pico code ‘picohid-v2.ino’ gets the received data from the buffer of the ‘set_report_callback’ function parameter in the following format from Unity.

#1 byte: *buffer
#2 byte: *(buffer + 1)
…
#n byte: *(buffer + n - 1)