Here, we will review a basic "Hello World!" example:
You will need an ESP32 device, and PlatformIO.
In this example, we will use a set of interfaces called
smart-transducer. So, first
of all, you will need to install the client tools on your machine. Add
the Pike repository to your
sources:
$ wget -qO- http://pike.esi.uclm.es/add-pike-repo.sh | sudo sh
And then, install using your favourite package manager, or run the following command:
$ sudo apt install smart-transducer
Our goal is to switch on/off the onboard LED, so we will use the
ST module, in particular the interface IBool. It has
the following signature:
module st {
interface IBool {
void set(bool v, string sourceAddr);
};
};
So, open your PlatformIO IDE (I use VS Code), and create a new project. Give it a project name, and choose your board. For this example, I used a DOIT ESP32 DevKit, so my settings are:

Now, edit the platformio.ini file and add a pair of
library dependencies: icec and st. Also, I set
the serial speed to match the used in the example:
lib_deps = IceC, st
monitor_speed = 115200
Now, let's delve in the interesting part! Open the
src/main.cpp, which is the core of your program. First,
include the needed headers: those of IceC, the TCP endpoint and
ST:
#include <WiFi.h>
#include <IceC.h>
#include <IceC/platforms/esp8266/TCPEndpoint.h>
#include <IceC/platforms/esp8266/debug.hpp>
#include "st.h"
We also need to declare some basic objects: the Communicator, an Object Adapter and the servant for our LED. Do it in the global scope, to ensure that they are not disposed:
// Some global variables
Ice_Communicator ic;
Ice_ObjectAdapter adapter;
st_IBool servant;
Of course, you need to provide an implementation of every
method of your interface. In this case, there is only one method,
set(), which will change the LED status:
void st_IBoolI_set(st_IBoolPtr self, Ice_Bool v, Ice_String sourceAddr) {
digitalWrite(LED_BUILTIN, v ? HIGH : LOW);
}
Now, inside the setup() function, we need to configure
the wireless conectivity. For this simple example, we will put
the device in AP mode, without credentials:
String ssid = "hello-node";
Serial.printf("\n--------\nWiFi: setting up AP as '%s'\n", ssid.c_str());
WiFi.mode(WIFI_AP);
WiFi.enableSTA(false);
WiFi.softAP(ssid.c_str());
And then, initialize the Communicator, and create an Object
Adapter (please refer to the ZeroC Ice documentation for more information). For
this example, we will listen on port 1234:
Ice_Communicator_init(&ic);
TCPEndpoint_init(&ic);
Ice_Communicator_createObjectAdapterWithEndpoints(
&ic, "adapter", "tcp -p 1234", &adapter
);
Ice_ObjectAdapter_activate(&adapter);
Once the Object Adapter is ready, we can initialize and register
the LED object. In this example, I used the identity "led":
st_IBool_init(&servant);
Ice_ObjectAdapter_add(&adapter, (Ice_ObjectPtr)&servant, "led");
At last (but not least), you should include on your event loop
a call to the middleware engine, just to handle incomming events.
So, the loop() function may be:
void loop() {
Ice_Communicator_loopIteration(&ic);
}
To summarize, your code may be like this:
#include <Arduino.h>
#include <WiFi.h>
#include <IceC.h>
#include <IceC/platforms/esp8266/TCPEndpoint.h>
#include <IceC/platforms/esp8266/debug.hpp>
#include "st.h"
// Some global variables
Ice_Communicator ic;
Ice_ObjectAdapter adapter;
st_IBool servant;
// The servant implementation
void st_IBoolI_set(st_IBoolPtr self, Ice_Bool v, Ice_String sourceAddr) {
digitalWrite(LED_BUILTIN, v ? HIGH : LOW);
}
void setup() {
// Common initialization
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
String ssid = "hello-node";
Serial.printf("\n--------\nWiFi: setting up AP as '%s'\n", ssid.c_str());
WiFi.mode(WIFI_AP);
WiFi.enableSTA(false);
WiFi.softAP(ssid.c_str());
// Initialize the communicator
Ice_Communicator_init(&ic);
TCPEndpoint_init(&ic);
// Create the object adapter
Ice_Communicator_createObjectAdapterWithEndpoints(
&ic, "adapter", "tcp -p 1234", &adapter
);
Ice_ObjectAdapter_activate(&adapter);
// Register servant
st_IBool_init(&servant);
Ice_ObjectAdapter_add(&adapter, (Ice_ObjectPtr)&servant, "led");
Serial.println("Ready, waiting events...");
}
void loop() {
// Wait for events
Ice_Communicator_loopIteration(&ic);
}
The final step is to compile and upload the binary to your
device. Connect it to an USB port, and run the command
>platformio: build (or whatever you have in your IDE).
Once the process is complete, and your device has restarted, it
will create a new WiFi AP, called node-hello. Connect your
computer to it (remember, there is no credentials). It will assign you
the IP address 192.168.4.2, while the node address will be
192.168.4.1.
Now, if you connected successfully, change the state of your
led using the st-client tool:
$ st-client -t bool -p "led -o:tcp -h 192.168.4.1 -p 1234" 1
$ st-client -t bool -p "led -o:tcp -h 192.168.4.1 -p 1234" 0
If you see your device LED shining, congratulations!