Introduction to the microsoft/azureiotedge-modbus-tcp IoTEdge Module

The newest version of the Azure IoTEdge solution is a very promising platform. The combination of remote provisioning the modules, the power of twin configuration and the new routing is interesting. But the learning curve is pretty steep.

The first version was based on programming an application. The new version is based on docker images, each being a separate application, which has to be stored in the container registry of your choice (like Docker Hub or your own container registry in Azure.

So once you have learned how to build and deploy your own modules, you can check out the modules Microsoft already supplies.

One of these modules is a Modbus module. It’s available at the Docker Hub of Microsoft. Modbus is a great protocol for highspeed communication over TCP and I have already blogged about it, using the previous IoTEdge SDK version.

Let’s check out how we get some telemetry from it.

You will need to have an actual device which talks the Modbus protocol. I use the Advantech Wise 4012E module which is advertised as a 6-channel Input/Output IoT Wireless I/O Module for IoT Developers. I love this device, it is an actual industrial device but it is scaled down to run on 5V (using a MicroUSB connector). The functionality of the is not scaled down!

This Microsoft Modbus module comes with documentation so let’s get started.

Deployment of the module

In my case, I have already deployed a heartbeat module to my Edge device of my own making. So I already defined an IoT Edge device n the Azure Portal and it’s connected to my Edge device.

Now I add the Microsoft Modbus module to the client Edge device using the Azure Portal. I use the “Set Modules” button of the IoT Edge device in the portal:

Adding and deleting IoTEdge modules is done in batches using a wizard in the Azure Portal.

Let’s check out that wizard.

Just add the new module on the first wizard page:

Here we have to fill in the reference to the Microsoft Modbus Module. I have experienced problems deploying modules without a specific version indicator. So I combine the name of the module and the name of the (newest) version

You can see different versions registered at the ‘tag’ page. I go for the ‘1.0.1-preview’:

So the full name would be: microsoft/azureiotedgemodbustcp:1.0.1-preview

Fill it in, into the IotEdge module details:

Also, put in the unique name of your choice and save this:

Note: I have seen issues with properties when I reused the same name over multiple deployments. Property changes became mixed up with module changes. Alter the name just a bit when you deploy the same module another time…

You now see two modules with the desired “running” state.

Select Next to check out the routing:

The routing tells use that all messages from all modules are passed on to the IoTHub. We just leave it like this, we do need to alter the routing.

Select Next to go to the last step of the wizard.

Here we can review the final update to all modules and the routing:

Submit the update. The Azure portal will show a notification when ready.

Check out the Edge

Now the already connected Edge device get’s the update.

Check out the Edge with the command “docker ps”. We get a list of all active module on the device. The Modbus module will be added:

Note: sometimes it needs a few seconds before all modules are available in this list. Rerun the same command a few times to be sure you see the correct list.

The module is now running on the Edge device. And this is done without touching the device 🙂

We can also see this in the portal. All modules are having the ‘Running’ state:


But still, we are nothing receive telemetry at this moment actually. Why? We have not added any configuration yet.

We can check out the docker logs of the Modbus module (using: docker logs -f msftmodbus > log.txt) for confirmation:

Added Cert: /mnt/edgemodule/edge-device-ca.cert.pem
IoT Hub module client initialized.
Desired property change:
No configuration found in desired properties.

So we need to provide some desired properties. Nice, I just showed how to do that on my own code!

So we need two things:

  1. Documentation for the Modbus coils and registers of our Wise module so we can read the telemetry
  2. explanation of the configuration of the desired properties to actually send the telemetry

The Wise 4012E module has two knobs which can be turned using a screwdriver. The is a good example of telemetry coming in. According to the documentation, the first (Analog, In) knob is available on register 40001:

So let’s read this value using the following properties Note: the documentation on Github is not that clear about the ‘Configuration’ but as seen from the logs, the Twin configuration with desired properties has to be changed!

I read the telemetry every two seconds and report it back to the IoTHub in an array:

"properties": {
  "desired": {
    "PublishInterval": "20000",
    "SlaveConfigs": {
      "Slave01": {
        "SlaveConnection": "",
        "HwId": "PowerMeter-0a:01:01:01:01:01",
        "Operations": {
          "Op01": {
            "PollingInterval": "2000",
            "UnitId": "1",
            "StartAddress": "40001",
            "Count": "1",
            "DisplayName": "KnobOne"
  "reported": {

The properties will look like this in the portal (select the module to see the see the Module details, push the Module Twin module to see and change the properties):

And once the properties are updated, we see the data flowing in, using the Device Explorer:

The array of telemetry is arriving. We can even see the heartbeat coming in, next to it.

If you want to extract this data, check out the property ”content-type’: ‘application/edge-modbus-json” in the IoTHub route.

See the module documentation for more examples of how to read and write Modbus values.


This Microsoft Modbus Module example is a nice example of how IoTEdge modules are deployed. It’s both simple to deploy and simple to use.