Red Amber Unity Tutorial



To begin with: Link to our Api Reference

Notice: The Red Amber SDK is not compatible with obsolete Blue Amber devices!

Notice: The Unity plugin now is beta and on some computers you might experience some crashes when running your game from the editor, so make sure you save frequently when you make changes to the scene!

Also, when building for iOS you need to add GemSDK.framework to Embedded Binaries under project settings manually before running the application.

Coordinate system

In GemSDK we use left-handed local coordinate system (fig. above).

GemSDK features:

Start with GemSDK

To run it on Windows it’s necessarily to install certain driver. The instruction can be found here

Download the GemSDK plugin for Unity from our download page

After importing  plugin to your project in “GemSDK/Scenes” you can find a sample scene:


The key script is “GemController.cs” that attached to Gem model:

public class GemController : MonoBehaviour
    public Text stateText;
    private IGem gem;

    // Use this for initialization
    void Start()
        if (Application.platform == RuntimePlatform.Android)
            //To get gem by number instead of address on Android the Gem should be paired to Gem SDK Utility app
            //Also it is possible to get the gem by address
            gem = GemManager.Instance.GetGem(0);
        else if(Application.platform == RuntimePlatform.WindowsPlayer ||
                Application.platform == RuntimePlatform.WindowsEditor)
            //On Windows it is possible to connect only by address
            string Address = ""; //For example "00:80:98:DC:9F:CD"

               print("Please specify the address for gem to connect");
            gem = GemManager.Instance.GetGem(Address);

    void FixedUpdate()
        if (gem != null)
            if (Input.GetMouseButton(0))

                //Use this instead of CalibrateAzimuth() to calibrate also tilt and elevation

            transform.rotation = gem.Rotation;
            stateText.text = gem.State.ToString();

To connect to the Gem you need to specify its address or number in the list of paired devices. Second option is supported only on Android and recommended only for developement. In Start() function you can usage both approaches for different platforms. The paired devices on Andoird should be configured by our utility app – Gem SDK Utility app(Play Market or apk), it simplifies Gem devices management during developement.

To get full list of paired Gems use this code for Android:

string[] gemAddresses = GemSDKUtilityApp.GetWhiteList(); 

To find out how to scan for gems manually on Android check out the corresponding section below.

[Android]If the Gem wasn’t disconnected manually before the app goes to background, the SDK will keep connection for 10 sec.

Getting basic data

void Update()
    if (gem != null) 
        GemState gemState = gem.State;

        Quaternion rotation = gem.Rotation;
        Vector3 acceleration = gem.Acceleration;

        PedometerData pedometer = gem.Pedometer;

Pedometer handling should be enabled manually:

gem.PedometerActive = true;


Some of gem data can be retrieved also or only via events:

gem.OnStateChanged += (GemState state) => { stateText.text = state.ToString(); };
gem.OnTap += (TapDirection dir) => { Debug.Log("Tap!"); };   
gem.OnPedometer += (PedometerData data) => { stepsText.text = data.Steps.ToString(); };

Tap handling should be enabled manually:

gem.TapActive = true; 

Orientation calibration

To consider current azimuth(yaw) angle as zero for curtain Gem just use


And to make rotation completely relative to current rotation use



Red Amber supports 8 GPIOs, 3 Analog inputs, 1 PWM output, I2C and SPI bus communications.
All this functionality is available via SDK. Physically additional sensors, LED’s, Buttons, and so on should be connected to corresponding pins of development board.

To make effect all the following commands should be executed when Gem is connected!

First of all extensions should be activated

gem.ExtensionsActive = true;


All the GPIOs will return to the initial state after disconnection.

Any GPIO pin should be configured before use

gem.ConfigDigital(DigitalPin.Direct0, PinConfig.Output);
gem.ConfigDigital(DigitalPin.Direct1, PinConfig.Input);

//Will rise OnDigital event when input value changes
gem.ConfigDigital(DigitalPin.Direct1, PinConfig.InputNotify);

Then you can set them or read their values

gem.WriteDigital(DigitalPin.Direct0, true);

Read request result will be returned via corresponding event

gem.OnDigital += (DigitalPinData data) => {
    if(data.Pin == DigitalPin.Direct0)
        digitalPinText.text = data.Value.ToString();

Analog inputs

Analog inputs reads the voltage on the corresponding pin


Result will be returned via corresponding event (see below)

gem.OnAnalog += (AnalogPinData data) => {
    if(data.Pin == AnalogPin.A0)
        analogPinText.text = data.Value.ToString();

PWM (Pulse-Width Modulation)


Sets PWM output to certain voltage 0V..3.6V. The value is limited by board supply votage. For example, with battery extension board the supply voltage is 3V.


Up to 16bytes can be written to the I2C bus or read from there per request
Result of read requests will be returned via ExtensionsListener (see below)

//Write directly to the bus to 0x5c address
gem.WriteI2c(0x5c, new byte[] { 0, 0x12, 0x14 });

//Write to the 0x5c device to 0x02 register 
gem.WriteI2c(0x5c, 0x02, new byte[] { 0, 0x12, 0x14 });

//Read 4 bytes from the device with 0x5c address
gem.ReadI2c(0x5c, 4);

//Read 4 bytes from 16, register 0x02
gem.ReadI2c(0x5c, 0x04, 16);

Read request result will be returned via corresponding event

gem.OnI2cData += (I2cData data) {
    if(data.Address == 0x5c) {
        byte[] lastPacket = data.Data;


Up to 16bytes can be written to the I2C bus or read from there per request
Result of read requests will be returned with the same request ID via ExtensionsListener (see below)

//Read 5 bytes from SPI bus. Request ID is 0
gem.ReadSpi(0, 5);

//Write data to SPI 
gem.WriteSpi(new byte[] { 0, 0x12, 0x14 });

//Writes to SPI bus with following reading simultaneously
gem.WriteReadSpi(0, new byte[] { 0, 0x12, 0x14 });

Read request result will be returned via corresponding event

gem.OnSpiData += (SpiData data) {
    byte[] lastPacket = data.Data;

Using multiple gems

You can call easily use multiple gems (as much as your bluetooth controller can handle)
Usually 4-5 gems can be connected simultaneously whout any significant lags

gem1 = GemManager.Instance.getGem(0);
gem2 = GemManager.Instance.getGem(1);

Scanning gems (Advanced)

Temporary only for Android

To your own way of building Gem white list inside your Android app we provide API for scanning Gems around.

Create scanner class instance and specify its callback:

scanner = new GemAndroidScanner();

Then you can start scanning:

scanner.StartScan(15); //Stop scanning automatically in 15 sec 

Scan process can be stopped earlier with:


You can access scanning results this way:

GemInfo[] gems = scanner.Devices;

This list updates when any new scan response has been cought. Not only when scanning has been stopped.


Over-the-Air updating (Advanced)

Currently API is not available. Bur you can update your Gems via Gem SDK Utility for Android mentioned above


Sample scenes come with the plugin and can be found in “GemSDK/Scenes” directory