Connect the Simplest CPS

In this section we will build the simplest real cyber-physical system!

We will buy a “wink” from Arduino, e.g. make Arduino blink with its onboard led. The lesson is tested on Arduino Uno, but any other board with a led will do the job.


The source code of this lesson is here.


The firmware for the board is located in arduino_blink/misc/arduino/arduino.ino. Use Arduino IDE to load the code to your Arduino board.

In the code we subscribe for the /blink_led topic and set a callback. The type of the topic is Empty, so the board waits until someone publishes to the topic and performs the LED blinking.

#include <ros.h>
#include <std_msgs/Empty.h>

ros::NodeHandle  nh;

void blink(int led, int mil) {

  digitalWrite(led, HIGH);
  digitalWrite(led, LOW);


void messageCb( const std_msgs::Empty& toggle_msg){
  blink(LED_BUILTIN, 500);
  blink(LED_BUILTIN, 500);
  blink(LED_BUILTIN, 500);

ros::Subscriber<std_msgs::Empty> sub("blink_led", &messageCb );

void setup()

void loop()

AIRA client


You can download the latest release from here

Set up the COM port forwarding as described in this lesson. You should forward your /dev/ttyUSB0 or /dev/ttyACM0 port (depending on the system) to COM1. In the client /dev/ttyS0 will represent the board. After this launch the virtual machine.


When new liability is created it goes to /liability/ready topic. We have to remember the address and call /liability/start service to get the data from objective.

def newliability(l):
  self.liability = l.address
  rospy.loginfo("Got new liability {}".format(self.liability))

  prefix = "/liability/eth_" + self.liability
  rospy.Subscriber(prefix + '/blink', Empty, self.blink)

  rospy.ServiceProxy('/liability/start', StartLiability)(StartLiabilityRequest(address=self.liability))
rospy.Subscriber("/liability/ready", Liability, newliability)

A message in the /blink topic come from the objective field. Have a look at Basic usage page.


Connect to AIRA client via SSH as described here. All tutorials are pre-installed. To launch the ros package run the following command:

$ rosrun arduino_blink

Also we need to add a rosbag file to IPFS:

$ ipfs add rosbag/blink.bag


Before the next step you should approve XRT tokens on the Factory.

On your host system build and launch an Dapp for the lesson:

$ git clone
$ cd robonomics_tutorials/arduino_blink_dapp
$ npm i && npm run dev

Open the link and press Demand then Offer buttons. Wait until a new liability is created and you should see the board blinking. Congratulations on the first agent!