Protobuf (short for protocol buffers) is a structured data serialization method developed by Google. This extensible format, which is both language- and platform-neutral, is used extensively within Google’s infrastructure, where it is considered the "lingua franca" for data.
Protobuf is gaining momentum among developers and is being used more widely within open source software projects.
Bluetera II is one of the first open source platforms to have adopted Protobuf as a medium for seamless information exchange between hardware and software.
In many Bluetooth Low-Energy (BLE) applications, adding new functionality means either:
Based on our experience, both options face significant limitations.
Adding BLE Characteristics is usually a cumbersome, error-prone procedure, whereas binary structures are unreadable and hard to maintain. Furthermore, both methods often require changes to the entire SDK (firmware, mobile software, cloud infrastructure, etc.), which breaks backward-compatibility and complicates future development.
Bluetera uses Protobuf to streamline messages between the BLE module and the BLE SDK. This has some nice benefits:
This simple example presents a Desktop WPF application to turn Bluetera’s LEDs on and off. Notice how simple it is to add the new messages. There is very little boilerplate, and most of the code is pure business logic.
The stages are:
You can find the sources for this example in the led-demo
branch of our GitHub repository. To build and run this example, you will need to Download and install Protobuf.
bluetera_messages.proto
Clone the Bluetera firmware repository
Locate bluetera_messages.proto
and add the following messages:
// define a new LED command
message LedCommand {
uint32 ledId = 1;
bool isOn = 2;
}
// update UplinkMessage to include the new command
message UplinkMessage
{
oneof payload {
ImuCommand imu = 1;
EchoPayload echo = 17;
LedCommand led = 18;
}
}
Clone the Bluetera Windows repository
Copy the bluetera_messages.proto
file to the protobuf
folder and generate the C# classes by running source/gen-messages.bat
. This will generate all necessary boilerplate code (such as the LedCommand
class).
Add a ‘ToggleLed’ button to MainWindow.xaml
Add the following code to MainWindow.xaml.cs
private async void ToggleLedButton_Click(object sender, RoutedEventArgs e)
{
// toggle LED state
isLedOn = !isLedOn;
// create the Uplink message
UplinkMessage msg = new UplinkMessage()
{
Led = new LedCommand()
{
LedId = 1, // 1 - red, 2 - green, 3- blue
IsOn = isLedOn
}
};
// send message
await _bluetera.SendMessage(msg);
}
Generate the boilerplate C code by running
application/messages/gen-messages.bat
. This will create the
necessary types to handle the new message
(BLUETERA_UPLINK_MESSAGE_LED_TAG
, bluetera_led_command_t
, etc.)
Modify bluetera_uplink_message_handler()
in main.c
to handle the
new command:
...
switch(msg->which_payload)
{
case BLUETERA_UPLINK_MESSAGE_LED_TAG:
{
const bluetera_led_command_t* cmd = (const bluetera_led_command_t*)&msg->payload.led;
nrfx_gpiote_pin_t led_pin;
switch(cmd->ledId)
{
case 1:
led_pin = LED_RED_PIN;
err = BLTR_SUCCESS;
break;
case 2:
led_pin = LED_GREEN_PIN;
err = BLTR_SUCCESS;
break;
case 3:
led_pin = LED_BLUE_PIN;
err = BLTR_SUCCESS;
break;
}
if(err == BLTR_SUCCESS)
{
if(cmd->isOn)
nrfx_gpiote_out_clear(led_pin);
else
nrfx_gpiote_out_set(led_pin);
}
}
break;
...
}
Protobuf is Google’s way of streamlining data serialization. Most current applications of the framework are software-specific. Bluetera II is one of the first platforms to adopt this powerful technology as a way of handling interactions between hardware and software.
We hope the LED example above illustrates how Bluetera’s usage of Protobuf can help you:
Meanwhile, please send us your questions, feedback, and suggestions!