Setting up Atmocube

Modbus Setup Guide

This guide explains how to set up Atmocube for Modbus connectivity. 

Modbus is a serial communication protocol, used widely throughout many industries.

Known for its easy deployment and maintenance, Modbus is used widely throughout many sectors because it is relatively easy to deploy and maintain compared to other standards. 

There are two Atmocube-supported Modbus realizations: 

• Modbus TCP/IP runs on Ethernet cables or via Wi-Fi. 

• Modbus RTU which runs typically on RS-485.

Atmocube provides Modbus TCP/IP support via Wi-Fi or the Ethernet port on the device. 

Atmocube provides Modbus RTU support via the dry contact input module on the back of the device.

1. Using the Atmocube configuration tool to enable Modbus on Atmocube

The Modbus feature is turned off by default. The feature can be enabled using the Atmocube configuration tool.

Enabling Modbus RTU

To enable Modbus RTU, open the configuration menu by clicking on the RS-485 tab. 

Check the “Enabled” option and enter/select the details including 

  • Device ID - please customize the Device ID, and make sure each device in the same line has a unique Device ID. The range of allowed Device ID is 1 to 247.
  • Baud Rate 
  • Data Bits 
  • Parity - it can be configured to be odd, even, or none by selecting from the drop-down menu in the Atmocube Configuration Tool. The default setting for Parity is “none”. If the Modbus network does not use parity checking, select “none”. The Modbus network admin or BMS admin should be consulted to confirm the parity type of your local network. Please note that all devices in the same network should have the same parity type set. 
  • Stop bits 

All parameters, except Device ID, should be the same for all Atmocubes on the RS-485 line.

Enabling Modbus TCP/IP

To enable Modbus TCP/IP, open the configuration menu by clicking on the Modbus IP tab. Check the Enabled option and enter the Modbus IP (TCP) port. The default port number is 503. The range allowed is 0 to 65535.

Note: If you want to use Modbus on a local network without an internet connection, disable the MQTT connection by going to the MQTT tab and unchecking the Enabled option as seen below. 

After Modbus has been enabled, follow the steps below to generate a configuration file:

  1. Select the model code (SKU) for the Atmocube from the drop-down selection menu on the Atmocube configuration tool page.
  1. After all details have been entered, click on the “Generate config” button to generate the configuration file. 
  1. Save the generated config.json file to the root of a USB flash drive formatted with the FAT file system.
  1. Disconnect Atmocube from the power source (if powered on).
  1. Insert the USB flash drive into the USB-A slot in Atmocube.
  1. Re-connect Atmocube to the power source.
  1. Once the Atmocube is turned on, Atmocube will access the config.json file from the USB flash drive. The power status LED will turn a solid purple color to indicate that the USB flash drive has been detected.
  1. After the configuration is successful, remove the USB flash drive from Atmocube.

Atmocube is ready for the Modbus connection. 

2. Input Register Formats

Analog input registers show sensor output data:

3. Testing the Modbus connection via Python Script (All Platforms) 

3.1 Modbus TCP/IP 

pip3 install pymodbus
python3 modbus_ip.py

modbus_ip.py

from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
from pymodbus.client.sync import ModbusTcpClient
 
client = ModbusTcpClient('192.168.1.110', port=502)
result = client.read_input_registers(0x0040, 20)
available = client.read_discrete_inputs(0x0040, 20)
 
if (available.bits[0] == 1):
	print("TVOC = {:.2f} ppm".format(result.registers[0] / 1000))
print("PM1 = {:.1f} ug/m3".format(result.registers[1] / 10))
print("PM2.5 = {:.1f} ug/m3".format(result.registers[2] / 10))
print("PM4 = {:.1f} ug/m3".format(result.registers[3] / 10))
print("PM10 = {:.1f} ug/m3".format(result.registers[4] / 10))
print("CO2 = {:d} ppm".format(result.registers[5]))
print("t = {:.2f} C".format(result.registers[6] / 100))
print("h = {:.2f} %".format(result.registers[7] / 100))
print("abs_h = {:d} g/m3".format(result.registers[8]))
print("p = {:.1f} mbar".format(result.registers[9] / 10))
print("noise = {:d} dBa".format(result.registers[10]))
print("light = {:d} Lux".format(result.registers[11]))
if (available.bits[12] == 1):
	print("no2 = {:.1f} ppm".format(result.registers[12] / 1000))
if (available.bits[13] == 1):
	print("co = {:.1f} ppm".format(result.registers[13] / 1000))
if (available.bits[14] == 1):
	print("o3 = {:.1f} ppm".format(result.registers[14] / 1000))
if (available.bits[15] == 1):
	print("ch2o = {:.1f} ppm".format(result.registers[15] / 1000))
print("ct = {:d} K".format(result.registers[16]))
if (available.bits[17] == 1):
	print("people = {:d}".format(result.registers[17]))
if (available.bits[18] == 1):
	print("VOC index = {:d}".format(result.registers[18]))
if (available.bits[19] == 1):
	print("NOx index = {:d}".format(result.registers[19]))
client.close()

3.2 Modbus RTU

pip3 install pymodbus
python3 modbus_rtu.py

modbus_rtu.py


from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
from pymodbus.client.sync import ModbusSerialClient
 
DEVICE_ID = 10
 
PORT = 'COM4'
BAUDRATE = 115200
DATA_BITS = 8
PARITY = 'N'   # 'E' - Even, 'O' - Odd, 'N' - None
STOP_BITS = 1
 
client = ModbusSerialClient(method='rtu',
                            port=PORT,
                            baudrate=BAUDRATE,
                            bytesize=DATA_BITS,
                            parity=PARITY,
                            stopbits=STOP_BITS,
                            timeout=1)
 
result = client.read_input_registers(0x0040, 20, unit=DEVICE_ID)
available = client.read_discrete_inputs(0x0040, 20, unit=DEVICE_ID)
 
if (available.bits[0] == 1):
    print("TVOC = {:.2f} ppm".format(result.registers[0] / 1000))
print("PM1 = {:.1f} ug/m3".format(result.registers[1] / 10))
print("PM2.5 = {:.1f} ug/m3".format(result.registers[2] / 10))
print("PM4 = {:.1f} ug/m3".format(result.registers[3] / 10))
print("PM10 = {:.1f} ug/m3".format(result.registers[4] / 10))
print("CO2 = {:d} ppm".format(result.registers[5]))
print("t = {:.2f} C".format(result.registers[6] / 100))
print("h = {:.2f} %".format(result.registers[7] / 100))
print("abs_h = {:d} g/m3".format(result.registers[8]))
print("p = {:.1f} mbar".format(result.registers[9] / 10))
print("noise = {:d} dBa".format(result.registers[10]))
print("light = {:d} Lux".format(result.registers[11]))
if (available.bits[12] == 1):
    print("no2 = {:.1f} ppm".format(result.registers[12] / 1000))
if (available.bits[13] == 1):
    print("co = {:.1f} ppm".format(result.registers[13] / 1000))
if (available.bits[14] == 1):
    print("o3 = {:.1f} ppm".format(result.registers[14] / 1000))
if (available.bits[15] == 1):
    print("ch2o = {:.1f} ppm".format(result.registers[15] / 1000))
print("ct = {:d} K".format(result.registers[16]))
if (available.bits[17] == 1):
    print("people = {:d}".format(result.registers[17]))
if (available.bits[18] == 1):
    print("VOC index = {:d}".format(result.registers[18]))
if (available.bits[19] == 1):
    print("NOx index = {:d}".format(result.registers[19]))
client.close()

4. Testing the Modbus connection via Modbus Poll (Windows only)

Download and install Modbus Poll.

4.1 Modbus TCP/IP connection settings

Open the Connection menu and choose Connect from the submenu. Configure the Modbus TCP/IP connection in the following way:

4.2 Modbus RTU connection settings

Open the Connection menu and choose Connect from the submenu. Configure the Modbus RTU connection in the following way:

4.3 Reading data

Download the template file here for setup and open it by going to the File menu and choosing Open from the submenu. Or set up registers manually.

For manual setup, open the Setup menu and choose Read/Write Definition… from the submenu. 

All data will be fetched in raw format:

The user manual for Modbus Poll is available here.