RemoteIO-gRPC — I/O abstraction via HTTP/2

Sylwester Sosnowski
2 min readNov 21, 2020
Photo by Chris Ried on Unsplash

Introduction

I’ve started a little project today to learn more about Google gRPC and to allow me to use the RaspberryPi GPIO Pins remotely on my desktop computer via a streaming HTTP/2.0 gRPC API. But what is gRPC?

gRPC (gRPC Remote Procedure Calls[1]) is an open source remote procedure call (RPC) system initially developed at Google in 2015.[2] It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, blocking or nonblocking bindings, and cancellation and timeouts. It generates cross-platform client and server bindings for many languages. Most common usage scenarios include connecting services in microservices style architecture and connect mobile devices, browser clients to backend services.

Accessing the RaspberryPi I/O via gRPC from a Server 200km away.

Protocol Implementation

Embedded systems usually provide functions for getting/setting pin modes, setting/getting values for analog and digital I/O. Therefore I decided to go the same way and implement a semi-HAL compatible to Arduino / wiringPi.

service RemoteIO {
rpc pinMode(PinModeMessage) returns (PinModeMessage){};
rpc digitalRead(DigitalState) returns (DigitalState){};
rpc digitalWrite(DigitalState) returns (DigitalState){};
rpc analogRead(AnalogState) returns (AnalogState){};
rpc analogWrite(AnalogState) returns (AnalogState){};

rpc spiRead(SPIMessage) returns (SPIMessage){};
rpc spiWrite(SPIMessage) returns (SPIMessage){};
rpc i2cRead(I2CMessage) returns (I2CMessage){};
rpc i2cWrite(I2CMessage) returns (I2CMessage){};
rpc subscribeInterrupt(InterruptMessage) returns (stream DigitalState){};
}

https://raw.githubusercontent.com/DatanoiseTV/RemoteIO-gRPC-proto/main/remoteio.proto

Full implementation here.

Adding a WebUI

gRPC is fun, but with grpcui things are really fun. You only need to expose the reflection service and any gRPC client can determine your RPC functions!

Wrapping up

Now we have the following functionality:

  • HTTP 2.0 gRPC service listening on TCP port 9000 (no TLS)
  • gRPC reflection (providing automatic RPC description)
  • pinMode(), digitalRead(), digitalWrite(), analogRead(), analogWrite()
  • spiRead(), spiWrite()
  • i2cRead(), i2cWrite()
  • Streaming mode

Source Code

You can find the unpolished code at https://github.com/DatanoiseTV/RemoteIO-gRPC

Use at your own risk. This uses /dev/mem for go-rpio, so it requires root.

--

--

Sylwester Sosnowski

Embedded Systems and Music Enthusiast based in Berlin, Germany