
Scope
EdgeX framework from EdgeX foundry speeds time to market by providing replaceable reference services for device-data ingestion, normalization, edge intelligence and sharing to support new IoT data services and advanced edge computing applications. More details about EdgeX at Link
The scope of this case study is to leverage and exercise the functionality of EdgeX framework and demonstrate monitoring temperature and humidity sensor. Industrial grade temperature and humidity transmitter, SHT20 is used for the case study. Typical block diagram using EdgeX is below.

High level data flow:
- Read the temperature and humidity values of SHT20 Sensor.
- Leverage EdgeX framework running on Raspberry Pi to provide gateway functionality.
- Using EdgeX framework microservices, process the sensor data and send it to Cloud.
- Actuate LEDs to ON/OFF when temperature readings cross threshold values.
Ubuntu and EdgeX Installation
Ubuntu Installation
Raspberry Pi 3B and Raspberry Pi 4 are used for this case study. Raspberry Pi will boot from the Operating System present in the Micro SD-Card. I have installed Ubuntu 20.04 LTS version on Micro SD-Card using Raspberry Pi manager. Detailed steps of installation can be found at Link
Before booting Raspberry Pi using Micro SD-Card which is installed with Ubuntu, make the following changes in SD-Card. Without these changes, ports will be disabled by default.
a) To enable USB ports for keyboard, add following line in /boot/config.txt file.
b) To enable HDMI ports for display, add following lines in /boot/config.txt file.
- hdmi_force_hotplug=1
- hdmi_drive=2
c) To enable SSH, touch a file “ssh” in /boot directory.
Booting the Raspberry Pi
- Connect the following to Raspberry Pi.
- Power cord for power supply
- USB port for Keyboard input
- HDMI port for monitor output
- Internet access with LAN cable or Wi-Fi
- Power On and boot the device
- Login with default credentials (ubuntu/ubuntu) and update password
- Get the IP address assigned using command “sudo ip addr”
- Once Internet access is configured, we can SSH to Raspberry Pi from another device for remote access.
Install EdgeX on Ubuntu
There are multiple ways to install EdgeX on Ubuntu. Detailed steps for the installation are found at Link
Snap way of installing EdgeX micro services is easy. But the microservice is in read-only filesystem of snap. If there is an issue to debug in any of the microservice, say EdgeX device service, it won’t help with snap installed microservice as we cannot modify the configuration to enable debugs or modify code to add additional logs.
To overcome the read-only problem of snap installed EdgeX microservices and to add more debugs in the code, we can pull the code from GitHub, then build and run. Initially I have used snap installed EdgeX microservices. But later migrated to build it from GitHub repository.
Sensor Device Validation
Sensor used for this case study is Industrial Grade Temperature & Humidity Transmitter SHT20 Sensor High Precision Monitoring Modbus RS485. Sensor SHT20 sends temperature and humidity values with the multiple of 10. After receiving the values, we need to divide them by 10 to get the correct readings. More details about the sensor at Link
Sensor SHT20 communicates with RS-485 protocol. Industrial USB to RS485 Bidirectional half duplex serial line converter is used for sending and receiving values from Sensor. More details about converter at Link
Following is the logical to and fro flow of data using RS-485 to USB converter.
Raspberry Pi ←→ USB-to-RS485-Converter←→ SHT20 Sensor
Actual connectivity used in the case study is captured below. Jumper wires are used to connect Sensor and Converter.

Reading values
Objective is to check the functionality of the sensor without using EdgeX in first place. So that we can validate if Sensor is working as expected or not. I have tested the Modbus messages from sensor with a C program. In C program, libmodbus library is used, which provides the APIs to send and receive messages in Modbus protocol.
[email protected]:/home/ubuntu/test# gcc -o readVaules read_sensor_values.c `pkg-config –cflags –libs libmodbus`
[email protected]:/home/ubuntu/test# ./readVaules
Setting slave_id 1
Opening /dev/ttyUSB0 at 9600 bauds (N, 8, 1)
[01][04][00][01][00][02][20][0B]
Waiting for a confirmation…
<01><04><04><01><4A><02><19><1B><04>
Temperature = 33.000000 & Humidity = 53.700000
[email protected]:/home/ubuntu/test#
Decoding Modbus messages
Let’s decode a pair of messages sent to and received from the Sensor.
Request Sent to Sensor: 01 04 00 01 00 02 20 0B
Sent | Decoding |
1 | Slave ID |
4 | Function, read_input_registers |
00 01 | Register address |
00 02 | No of registers to read |
20 0B | CRC |
Response received from Sensor: 01 04 04 01 4A 02 1A 5B 05
Received | Decoding |
1 | Slave ID |
4 | Function, read_input_registers |
4 | Bytes Count |
01 4A | Data 1, Temperature |
02 1A | Data 2, Humidity |
5B 05 | CRC |
Temperature value received is 0x014a, which is 330 in decimal. SHT20 sends the values in multiple of 10, so temperature is 33.0 degrees. Similarly, Humidity value received is 0x021a, which is 538 in decimal. SHT20 sends the values in multiple of 10, so Humidity is 53.8 %RH.
4. LED Actuation Validation
To check the needed functionality of breadboard connections with LEDs, following items are required.
• Breadboard
• LEDs
• Resistors
• Jumper wires
I have referred to get the enough understanding needed for this case study. And for GPIO understanding I referred
Verify LED connectivity
Like Modbus connectivity verification, here too objective is to verify the breadboard and LEDs connectivity without using EdgeX in first place.
I have made logical diagram of connecting GPIO pins of Raspberry Pi with LEDs present on breadboard using Circuit Diagram provides a convenient way of depicting the connections.

I have tested the LEDs functionality with a python program. Package RPi.GPIO provides a class to control the GPIO on a Raspberry Pi. Breadboard actual connections and output of green LED glow is depicted below.

End-to-End Data flow
Objective of the case study is to use EdgeX framework to:
- Read the data from the Sensor and send it to Cloud and
- Actuate LEDs whenever temperature reading reaches upper or lower threshold values.
Following is the high-level block diagram of the End-to-End Sensor data flow.

Corresponding physical connections are depicted below. Raspberry Pi is the IIoT gateway.

Micro Services within EdgeX
Data flow indicated with Blue arrows are from southbound to northbound i.e., from Sensor to Cloud. Data flow indicated with Orange arrows are from northbound to southbound i.e., from Application Service to LED actuation.

Data flow from Southbound to Northbound (Sensor to Cloud):
- Modbus Device Service will retrieve the temperature and humidity values from Sensor using Modbus messages for every 5 seconds. Pulling data for every 5 seconds is configured using Auto Events in Modbus Device Service.
- Modbus Device Service applies scale factor of 0.1 before sending the sensor data to Core Services.
- Sensor data is stored temporarily in Core Services and received at the Application Service based on the configuration within Application Service.
- Sensor data values can be fetched and verified using Core Command REST APIs.
- Application Service will forward sensor values to the Cloud configured in the configuration.toml file.
- We can monitor the sensor values using the IBM Cloud Portal.
Data flow from Northbound to Southbound (Application Service to LED actuation):
- Application Service will send the sensor data to Rules Engine based on the configuration. Kuiper is the Rules Engine.
- Rules Engine should be added with the required rules, prior to receiving the sensor data from Application Service, so that it can actuate using the Core Commands of the GPIO Device Service mentioned in the rules.
- LEDs which must go ON/OFF are already configured in GPIO Device Service. For this case study, pin GPIO-12 is configured with Red LED and pin GPIO-14 is configured with Blue LED. Core Commands of GPIO-12 and GPIO-14 are added with corresponding rules in Kuiper.
- Threshold values for case study are, Blue LED must glow if the temperature value goes below 28 degrees and Red LED must glow if the temperature value goes above 30 degrees. Between 28 degrees to 30 degrees both the LEDs should be off.
- Sensor Data received from Application Service is analyzed by Kuiper and as per the configured rules, Core Commands of GPIO Device Service are actuated when threshold values are reached.
- Based on the commands triggered by Kuiper, GPIO Device Service will actuate the corresponding LEDs to ON or OFF.
Analyzing the Data Flow
Following section analyzes the data flow at various stages, when sent from Southbound to Northbound and vice versa.
Modbus Device Service
Modbus Device Service will retrieve the temperature and humidity values from Sensor using Modbus messages for every 5 seconds. Modbus logs from the case study are below.
2021/03/02 14:35:21 modbus: sending 01 04 00 01 00 01 60 0a
2021/03/02 14:35:21 modbus: received 01 04 02 01 50 b8 9c
Decoding above messages sent to and received from the Sensor
Sent | Decoding |
1 | Slave ID |
4 | Function, read_input_registers |
00 01 | Register address |
00 01 | No of registers to read |
60 0a | CRC |
Received | Decoding |
1 | Slave ID |
4 | Function, read_input_registers |
2 | Bytes Count |
01 50 | Data, Temperature |
b8 9c | CRC |
Temperature value received is 0x0150, which is 336 in decimal. SHT20 sends the values in multiple of 10, so temperature is 33.6 degrees.
Core Service
Sensor data values fetched using REST APIs of Core Command are as follows.

Application Service
Application Service will send the data to IBM Cloud, which is configured in the configuration.toml file. Application Service logs when data is sent to Cloud are captured below.
level=DEBUG ts=2021-03-21T14:35:48.355521757Z app=AppService- source=runtime.go:59 msg=”Processing message: 5 Transforms”
level=DEBUG ts=2021-03-21T14:35:48.36118818Z app=AppService- source=filter.go:44 msg=”Filtering by DeviceID”
level=DEBUG ts=2021-03-21T14:35:48.364375438Z app=AppService- source=filter.go:86 msg=”Filtering by ValueDescriptor”
level=DEBUG ts=2021-03-21T14:35:48.367788325Z app=AppService- source=conversion.go:62 msg=”Transforming to JSON”
level=DEBUG ts=2021-03-21T14:35:48.371520359Z app=AppService- source=mqtt.go:138 msg=”Sent data to MQTT Broker”
level=DEBUG ts=2021-03-21T14:35:48.37480595Z app=AppService- source=context.go:80 msg=”Marking event as pushed”
Snapshots of Sensor data from IBM Cloud portal, are below.

Rules Engine
Another Application Service will send the data to Rules Engine. Kuiper, which is Rules Engine, will actuate the LEDs by triggering the corresponding GPIO Core Commands, when configured temperature thresholds are crossed. Kuiper receives the sensor data sent by the Application Service and applies the rules which are preconfigured for actuation.
For the case study, following are the steps to configure rules in Kuiper.
bin/kuiper drop stream edgex_data
bin/kuiper create stream edgex_data”() WITH(FORMAT=\”JSON\”, TYPE=\”edgex\”)”
bin/kuiper create rule red_led_on -f rule1.txt
bin/kuiper create rule red_led_off -f rule2.txt
bin/kuiper create rule blue_led_off -f rule3.txt
bin/kuiper create rule blue_led_on -f rule4.txt
From the above list, rule1.txt will actuate red LED on when temperature value goes more than 30 degrees, rule2.txt will actuate red LED off when temperature value is less than 30 degrees. Similarly, rule3.txt will actuate blue LED off when temperature value goes more than 28 degrees, rule4.txt will actuate blue LED to on when temperature value is less than 28 degrees. Logs when red LED is actuated are below.
[email protected]:/home/ubuntu/new_testing/kuiper/kuiper/_build/kuiper-1.1.1-4-g24892eb-linux-aarch64# tail -f ./log/stream.log
time=”2021-03-02 14:35:21″ level=info msg=”sink result for rule blue_led_off: [{\”TemperatureDegC\”:33.6}]” file=”sinks/log_sink.go:16″ rule=blue_led_off
time=”2021-03-02 14:35:21″ level=info msg=”sink result for rule red_led_on: [{\”TemperatureDegC\”:33.6}]” file=”sinks/log_sink.go:16″ rule=red_led_on
Instead of LED actuation, necessary actions can be taken for Industrial use case.
GPIO Device Service
GPIO device service will make the LED ON/OFF when Core Command of corresponding GPIO pin is triggered by Kuiper. Snapshots of LED actuation along with live values in IBM Cloud portal are below.

I have decreased the temperature of the Sensor by wrapping it with an icepack.

Issues faced during Integration
Migrating from Snapcraft EdgeX to running microservices from GitHub code
Snap way of installing EdgeX micro services is easy. But the microservice is in read-only filesystem of snap. If there is an issue to debug in any of the microservice, say EdgeX device service, it won’t help with snap installed microservice as we cannot modify the configuration to enable debugs or modify code to add additional logs.
To overcome the read-only problem of snap installed EdgeX microservices and add more debugs in the code, we can pull the code from GitHub, then build and run.
Sensor precision value is lost during conversion
Sensor SHT20 sends the values as multiple of 10 with Modbus protocol. When we use the type as INT16 for the device resource two bytes of sensor data is received but while applying scale factor of 0.1 precision value is lost. For example, 30.3 degree Celsius is sent by the sensor as 303. After applying scale factor in Modbus Device Service, temperature value is 30 instead of 30.3
Raised issue with EdgeX forum at Issue fixed with rawType and documented at
6.3 Kuiper is unable to parse the sensor data value while applying rules
While applying rules for actuation, Kuiper is unable to parse the sensor data when rawType is used in device resource. Logs for the same are below.
time=”2021-03-09 12:33:32″ level=warning msg=”fail to get value for TemperatureDegC: strconv.Atoi: parsing “3.220000e+01″: invalid syntax” file=”extensions/edgex_source.go:153″ rule=led_off
time=”2021-03-09 12:33:32″ level=warning msg=”No readings are processed for the event, so ignore it.”
Raised issue with EmqX forum. After debugging with EmqX team, understood that issue is with Core Service where old data types for device resources are not updated with new data types when device profile is modified.
Raised another issue with EdgeX forum. Issue is accepted by EdgeX team and will be addressed as part of v2 (/api/v2). For now, workaround is to delete the Modbus device profile, manually remove value descriptor entries from Core Data and register the Modbus device profile again.
Vijay Kumar Gopu, working as a Technical Specialist with HCL technologies. I have working experience in the area of Virtualization and Wireless Core Network.