Universal Serial Parser (USP) - How-to with USB to UART

In this tutorial, we will emulate the asset sending data over USP. For that purpose, we will use a developement PC, a USB (PC) to UART (Octave mangOH) connection, and a python script to generate the serial data.

In this example, we will use the delimiter way of extracting frames over USP:

  • the simulated asset will be transmitting "PAYLOADX" as a string, where "X" is the end of frame separator
  • we will therefore configure USP in delimiter mode, with "X" as a delimiter

🚧

Preview

This feature is in preview, available from edge firmware 3.0.x. We appreciate your feedback !
It also means we may make some changes.

Preparing your USB to UART setup

This tutorial uses a mangOH Red connected to your development PC over a USB-to-UART bridge, connected to your development PC over a USB-to-serial cable.

You can easily adapt this tutorial for a mangOH Yellow or FX30S (the only difference is that you will map the UART to the IoT Connector or to the main RS-232 port of the FX30S)

The example performs the following:

  • creates a UART connection using Octave's southbound Universal Serial Protocol
  • pushes data periodically to the USP resource

In order to setup this test environment, you can refer to the ORP USB to UART setup.
Follow all the steps prior to launching the ORP python script. The principles are quite the same but we will run another dedicated script in this section.
Setting up your USB to UART setup

USP Configuration

We first need to assign the UART being owned by the usp service in the io/config resource by adding the following JSON entry.

📘

Adding the USP UART configuration

Until the USP UI is provided, you can directly edit the io/serial configuration in the Resource panel. To help you doing so, you can for instance use the Service/ORP UI to configure ORP on the UART & Port routing o your choice. Then in the /io/config/ Resource UI, just replate the "own":"orp" by "own":"usp" as indicated below.

We map "usp" to "UART1" ( "own":"usp"), and are here using the Rasbberry Pi connector on the MangOH Red.

{
  "devs": [
    {
      "conf": [
        {
          "baud": "9600",
          "bits": 8,
          "flow": "N",
          "own": "usp",
          "pair": "N",
          "routing": "IOT0",
          "std": "232",
          "stop": "1",
          "type": "UART2",
          "wire": "2"
        }}
      ],
      "type": "serial"
    }
  ]
}

📘

Configure the USP service (frame delimiters & timeouts)

The configuration of the service is done writing a json document to /usp/config resource:
Here we will select 'delimiter' and define it as "X": 58 is the Hex representation of our "X" ascii separator

USP is mapped to UART1 which we will configure to USP in the section below.

{
  "frame_timeout": 0.5,
  "framing": {
    "delimiter": [
      "58"
    ]
  },
  "uart": "UART1"
}

Observe received data

In order to report the received data to the cloud, we are going to configure an Observation on the '/usp/value' resource.

Go to Observations, and create Cloud Stream observation on that resource.

Launch the Python script to send data from the simulated asset over USP

Open a terminal window on your computer and launch the usp_sample.py script:
python ./usp_sample.py

\Python27> python .\usp_sample.py
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART
Sent 'PAYLOADX' over UART

usp_sample.py

import os

from serial import Serial

import string
from time import sleep


DEV = os.getenv('DEV', '/dev/ttyS0')

# Create serial object and use it to create SbSerial connection
s = Serial(port='COM16')
s.baudrate=115200


# Run Forever
while True:
    try:
       sleep(5)
       s.write(b'PAYLOADX')
       print "Sent 'PAYLOADX' over UART"
    except KeyboardInterrupt:
        exit(0)

View the received data

The Cloud Stream Observation you have created reports events in a usp stream
This is what the received data should look like

{
  "elems": {
    "usp": {
      "data": [
        80, // decimal ascii for P
        65, // decimal ascii for A
        89, // decimal ascii for Y
        76, // decimal ascii for L
        79, // decimal ascii for O
        65, // decimal ascii for A
        68, // decimal ascii for D
        88 // decimal ascii for X
      ]
    }
  }
}

You have now setup a simple asset to cloud data collection over USP

Decode the USP data locally and send it to the cloud

In order to parse the Ascii locally on the Edge side before sending it to the cloud, you can do the following:

  • create (or modify) the observation on the usp/data resource and route it to an Edge Action
  • create an Edge Action with the following code
  • the USP data will be sent as string to the cloud in the device/:default stream
function(event) {

	var array = event.value.data;
	var data = array.splice(-1); // remove bytes at the end of the frame (one per delimiter byte)

	var parsed = array.map(function(elem){return String.fromCharCode(elem)}).join('')
	//console.log(parsed);

return {
  "cl://": [{ "usp_data": parsed}]};
}

You can see the parsed data pushed periodically in the device/:default stream:

"elems": {
    "usp_data": "PAYLOAD"
  }