How to connect dev boards with Protopie

Paolo Perego
9 min readNov 1, 2020

--

THIS ARTICLE IS DEPRECATED, TO CONNECT ARDUINO OR OTHER BOARD YOU NEED TO USE “PROTOPIE CONNECT”

Arduino, Micro:bit, ESP32… connected to Mobile app prototype.

Protopie is one of the most complete software for prototyping software.

It reaches version 6.2, adding some stunning interaction capability. Protopie is one of the few prototyping software which gives the designer the possibility to create interactions using smartphone sensors (such as camera, accelerometer, and proximity sensor).

Mobile prototype

Nevertheless, Protopie cannot use Bluetooth connectivity and wireless connectivity; you can send messages between screens, different phone prototype, but not over wifi or BLE directly.

On the other hand, Protopie gives android users the possibility to send messages in broadcast, which is being able to send a message to “the whole smartphone” so that other apps can read and process it.

Thanks to this capability, Android users can use an external application, which we can call a “bridge app”, that gets broadcast messages and send them to WiFi, BLE, or USB connection. This bridge app can also work in the opposite way; it takes messages received from wifi, BLE… and sends them back on Android broadcast so that Protopie is able to receive and process them.

In summary: an app bridge can be used to communicate prototypes made in Protopie and run on Android Smartphones, with physical prototypes that have any connectivity: USB, Bluetooth Low Energy, Wifi…

Protopie provides a repository with some examples of Bridge app: https://github.com/ProtoPie/protopie-connect-bridge-apps

In order to simplify all the procedure, I already created some app which can be downloaded from the google play store.

Bridge app for Micro:bit

This app can be used to connect Micro:bit with Protopie. On Micro:bit you need to install Bluetooth extension and use UART Service.

Instruction for the Bridge app:

  1. Install the app
  2. Open it
  3. Select your micro:bit from the list (you have to program it first and then pair it).
  4. Reduce the bridge app in the background and open ProtoPie app
  5. Select the right prototype and use it.

The bridge app automatically redirects messages from Microbit USB to ProtoPie prototype and vice-versa.

Bluetooth stack on Micro:bit is big, and it is not possible to implement both send and receive in the same firmware. Down here there are two examples of send and receive firmware.

Microbit v2 has a new microcontroller (nRF52833) with more memory and power; this allows for using the full Bluetooth stack for both send and receive.

Receive example

In this receive example, you can see that in the forever loop we use “Bluetooth UART read until $”. A terminal character is mandatory in order to understand the end of the command. You need to insert it in the message on ProtoPie.

To send a message from Protopie you need to use the Send action, indicating Android Broadcast as Channel and “command”+% as Message.

On the opposite, to send a message for Micro:bit to Protopie, you need a Trigger: the Receive trigger, indicating Android Broadcast as Channel and the correct message in Message.

Here is the link to an example for sending commands: https://makecode.microbit.org/_Y0P5u1MrCD7V

Here is the link to an example for receiving commands: https://makecode.microbit.org/_h5Fi6DFjaFde

Here is the example for Protopie project and Micro:bit: link

Bridge for Arduino USB

Here is the version for Arduino. Standard Arduino and Compatible ones use the USB connection for programming and also Serial Communication.

The same Serial Communication can be used to communicate with ProtoPie. In order to connect USB-A cable (the one you use to connect Arduino board to your computer) with Android, you need a USB OTG adapter. This adapter is the same which can be used to connect a USB key to Android.

USB Bridge instruction:

  1. Install the app
  2. Run it
  3. Connect the USB Arduino to Android USB port (you should see on Android a message which indicates the USB connection).
  4. Run the bridge app in the background
  5. Open ProtoPie and select the right prototype.

Any message you write on the Serial port is automatically redirected to ProtoPie and vice-versa. To send a message from Arduino to ProtoPie, you need to insert your message between the character <…> (eg. “<ON>”).
The most important part that you need to remember is to fix the Arduino Serial speed (the baud rate) to 9600 bps. Here is an example of receiving data from Protopie app.

This new version of the application is able to receive messages and values togheter. It need both the variables and for this reason, in order to avoid app crashes, on ProtoPie it is mandatory to activate the “Send Value Together” flag. The value could be from a variable or also a fixed one (when not used).

String value_received_from_protopie;
String fullString;
String message_from_protopie;
int ind1;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if(Serial.available()){
fullString = Serial.readString();
ind1 = fullString.indexOf(":");
message_from_protopie = fullString.substring(0,ind1);
value_received_from_protopie = fullString.substring(ind1+1);

if (cmd=="O")
digitalWrite(LED_BUILTIN,HIGH);
if (cmd=="X")
digitalWrite(LED_BUILTIN,LOW);
}
//Serial.println("<ON>"); //Serial.println is used to send command
//to Protopie
}

The same application can be used also with Micro:bit via USB cable. On Micro:bit you can use Serial over USB to communicate with Protopie, in the same way, you use it with Arduino.

Bridge for other Arduino via BLE

If you do not want to use SPP over BLE like the one presented in the Mcirobit session, you can use this application. I tested it with ESP32, Arduino Nano BLE Sense, and Adafruit Bluefruit.

It use the same characteristic both for TX ad RX data. Here is the service and characteristic used:

const char* SERVICE_UUID = “4fafc201–1fb5–459e-8fcc-c5c9c331914b”;
const char* CHARACTERISTIC_UUID = “beb5483e-36e1–4688-b7f5-ea07361b26a8”;

Here is an example for the code:

#include <Arduino.h>
#include <SPI.h>
#include “Adafruit_BLE.h”
#include “Adafruit_BluefruitLE_SPI.h”
#include “Adafruit_BluefruitLE_UART.h”
#include “Adafruit_BLEGatt.h”
#include “BluefruitConfig.h”#if SOFTWARE_SERIAL_AVAILABLE
#include <SoftwareSerial.h>
#endif
const char* SERVICE_UUID = “4fafc201–1fb5–459e-8fcc-c5c9c331914b”;
const char* CHARACTERISTIC_UUID = “beb5483e-36e1–4688-b7f5-ea07361b26a8”;
/* …hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);
Adafruit_BLEGatt gatt(ble);
/* The service information */
int32_t htsServiceId;
int32_t htsMeasureCharId;
int32_t charid_string;// A small helper
void error(const __FlashStringHelper*err) {
Serial.println(err);
while (1);
}

void setup(void)
{
//while (!Serial); // required for Flora & Micro
//delay(500);
Serial.begin(115200);
Serial.println(“INIT BLE”);
Serial.print(F(“Initialising the Bluefruit LE module: “));if ( !ble.begin(VERBOSE_MODE) )
{
error(F(“Couldn’t find Bluefruit, make sure it’s in CoMmanD mode & check wiring?”));
}
if ( ! ble.factoryReset() ) {
Serial.println(F(“Couldn’t factory reset”));
}
ble.echo(false);if (ble.sendCommandCheckOK(F(“AT+GAPDEVNAME=BLEFriend”)))
Serial.println(“NAME CHANGED”);
if (ble.sendCommandCheckOK(F(“AT+GATTCLEAR”)))
Serial.println(“GATT DELETED”);
if (ble.sendCommandCheckOK( F(“AT+GATTADDSERVICE=UUID128=4F-AF-C2–01–1F-B5–45–9E-8F-CC-C5-C9-C3–31–91–4B”)))
Serial.println(“Service add”);
if (ble.sendCommandCheckOK( F(“AT+GATTADDCHAR=UUID128=be-b5–48–3e-36-e1–46–88-b7-f5-ea-07–36–1b-26-a8,PROPERTIES=0x3E,MIN_LEN=1,MAX_LEN=1,DATATYPE=INTEGER,DESCRIPTION=num,VALUE=0”))) {
Serial.println(“ Char add”);
charid_string = 1;
}
ble.reset();
/* Wait for connection */
while (! ble.isConnected()) {
delay(500);
}
Serial.println(F(“******************************”));pinMode(LED_BUILTIN, OUTPUT);}

void loop(void)
{
// Echo received data
if ( ble.isConnected() )
{
//Send command to Protopie. 2 is the number sent to protopie
//if (ble.sendCommandCheckOK(F(“AT+GATTCHAR=1,2”)))
// Serial.println(“Char updated”);
//Receive command from portopie
int32_t val;
if (ble.sendCommandWithIntReply(F(“AT+GATTCHAR=1”), &val) == 1)
{
Serial.println(val);
if (val == ‘3’)
digitalWrite(LED_BUILTIN, HIGH);
if (val == ‘4’)
digitalWrite(LED_BUILTIN, LOW);
}
delay(100);
}
}

Here is the link of a ProtoPie project example for Arduino, with voice recognition and text to speech example: link

The same bridge application can be used also with ESP32 based boards. ESP32 is a very powerful microcontroller, which can be programmed with Arduino IDE, and it is able to communicate via Bluetooth, Bluetooth LE, and WiFi. Moreover, the ESP32 boards are very cheap and easy to find on the market; this makes these devices perfect for low-cost connected prototypes.

Here is the code for these boards:

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer *pServer = NULL;
BLECharacteristic * pRxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue = 0;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" // UART service UUID
#define CHARACTERISTIC_UUID_RX "beb5483e-36e1-4688-b7f5-ea07361b26a8"
String stringCommand[4] = {"ON","OFF","OPEN","CLOSE"};class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]);
Serial.println();
Serial.println("*********");
}
}
};
void setup() {
Serial.begin(115200);
// Create the BLE Device
BLEDevice::init("ESP32 BLE test");
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ
);
pRxCharacteristic->setCallbacks(new MyCallbacks());// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
void loop() {if (deviceConnected) { //** Send a value to protopie. The value is in txValue **//
//char txString[8];
//dtostrf(txValue, 1, 2, txString);
//pRxCharacteristic->setValue(txString);
//pRxCharacteristic->notify();
//*******************************************************//
//** Send a string based on the value in txValue **//
switch (txValue){
case 1: pRxCharacteristic->setValue("ON");
break;
case 2: pRxCharacteristic->setValue("OFF");
break;
case 3: pRxCharacteristic->setValue("LEFT");
break;
case 4: pRxCharacteristic->setValue("RIGHT");
break;
}
pRxCharacteristic->notify();
txValue++;
if (txValue>=4)
txValue = 0;
//*************************************************//

delay(2000); // bluetooth stack will go into congestion, if too many packets are sent
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}

Here is the link of a ProtoPie project example for ESP32: link

Down here the code for Arduino Nano BLE using ArduinoBLE library.
The firmware sends the string “ON” and “OFF” every 5 seconds and turns on and off the builtin led when receiving the right string from ProtoPie. This case is different from the Arduino+ProtoPie via USB; you do not neet to insert the message between the characters “<….>”.

//This is the library for Arduino nano BLE
#include <ArduinoBLE.h>
//Service and characteristics required for Protopie
BLEService protopieService("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
BLEStringCharacteristic protopieCharacteristic("beb5483e-36e1-4688-b7f5-ea07361b26a8", BLERead | BLEWrite | BLENotify, 20 );
long timePass = 0;void setup() {
Serial.begin(9600); //Serial is only used for debug
pinMode(LED_BUILTIN,OUTPUT);if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while(1); //stop execution if BLE error
}
Serial.println("Blueooth ok");
//Initialize BLE with name and characteristics
BLE.setLocalName("ProtoPie BLE"); //Change your device name
BLE.setAdvertisedService(protopieService);
protopieService.addCharacteristic(protopieCharacteristic);
BLE.addService(protopieService);BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
protopieCharacteristic.setEventHandler(BLEWritten, protopieCharacteristicWritten);

//Set initial value on characteristic and turn on bluetooth advetising
protopieCharacteristic.writeValue("");
// start advertising
BLE.advertise();
}
//These are the ccommand to send/receive
String ON = "ON";
String OFF = "OFF";
int toggle = 0;
void loop() {
// Get if there is something on ble
BLE.poll();

if (BLE.connected()){ //check if device is connected to smartphone

//Send data
if (millis()-timePass>5000){
if (toggle==0){
protopieCharacteristic.writeValue(ON);
toggle = 1;
timePass = millis();
}else{
protopieCharacteristic.writeValue(OFF);
toggle = 0;
timePass = millis();
}
}
}
}
void blePeripheralConnectHandler(BLEDevice central) {
//This is executed when connect
Serial.print("Connected event, central: ");
Serial.println(central.address());
}
void blePeripheralDisconnectHandler(BLEDevice central) {
//This is executed when disconnect
Serial.print("Disconnected event, central: ");
Serial.println(central.address());
}
void protopieCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) {
//Here I received from ProtoPie
Serial.println("Characteristic received");
String val;
val = protopieCharacteristic.value();
if (val=="ON")
digitalWrite(LED_BUILTIN, HIGH);
if (val=="OFF")
digitalWrite(LED_BUILTIN, LOW);
Serial.println(val);
}

Here is the link to download the ProtoPie project: link

--

--