PymateIO-HMI-numeric-input

From pymate.io wiki
Jump to navigation Jump to search


Abstract

After our first example with the HMI Display and PymateIO it is time to look for some advanced feature.

02-edit-value.jpg

This example will show how Pymate script will grab the integer value sent by the HMI display.

Just press the field on the HMI Display to encode the new value

HMI Example Project

The demonstration script is still based on the "HMI_PyMateIO_Modbus_MASTER.skm" project introduced in HMI Display and PymateIO tutorial.

Attentive reader would have noticed a slightly difference between the numeric fields:

  • The 4x1 field is a "Numeric display" only
  • The 4x0 field is a "Numeric Input" field where the user can encode some value.

02-01.png

With the following field definition

PymateIO-HMI-01-03.png

Pymate Script

Entering a value on the HMI display will issue a function 6 ModBus request.

Capturing the modbus_slave debug message put this in evidence.

Modbus: HREGS READ <Request fct=3 qty=2 addr=0 data=None>
Modbus: COILS READ <Request fct=1 qty=8 addr=0 data=None>
Modbus: HREGS WRITE <Request fct=6 qty=None addr=0 data=bytearray(b'\x01,')>
Modbus: HREGS READ <Request fct=3 qty=2 addr=0 data=None>

The Pymate script just need to declare the on_set_cb for the HREGS register definition to catch the call.

# Registers and their default values
slave_registers = {
    "COILS": {
        ....
    },
    "HREGS": {
        "4x fields": {
            "register": 0,
            "len": 2,
            # 1st-> 4x0 field = 65280 ; 2nd-> 4x1 field = 1 
            # Values must be uint16 0-65535
            "val": [0xFF00,1 ], 
            "on_get_cb" : get_counters,
            "on_set_cb" : set_counter
        }
    },
    "ISTS": {        
    },
    "IREGS": {
    }
}

The following section remind the get_counters callback returning the _counter variable value.

The interest lies in the implementation of the set_counter() function receiving the value from the HMI Display then store it for future usage

_counter = 0 # Call counter
def get_counters( reg_type, address, val ):
	# reg_type (eg: HREGS)
	# addr     (eg: 0)
	# val      (eg: LSBF [255,0] for initial value = 0x00FF)
	
	# Call Counter : Increment and limit to uint16
	global _counter 
	_counter += 1
	if _counter>65535:
		_counter=0
	# Elapse time: limit value to uint16
	_ms = time.ticks_ms()%65535

	val[0] = _counter # 4x0 field
	val[1] = _ms      # 4x1 field 
	modbus_slave.set_hreg(0, val)
	
def set_counter( reg_type, address, val ):
	# reg_type (eg: HREGS)
	# addr     (eg: 0)
	# val      (eg: [300] )
	global _counter
	# print( reg_type, address, val )
	_counter = val[0]

As simple as thats!!!

Full script

# Pymate Modbus Slave examples for HMI-043U2S 
#
# This example demonstrate capture of value encoded on the HMI display
#
from pymate.board import Board
import time, struct

SLAVE_ADDR = 0x01 # Slave Addr 1-127 of this instance 
print( 'Create Modbus Slave at addr', SLAVE_ADDR )
brd = Board()
modbus_slave = brd.modbus( master=False, addr=SLAVE_ADDR, baudrate=9600 )

# Active Modbus debugging messages
# modbus_slave.debug = True


_counter = 0 # Call counter
def get_counters( reg_type, address, val ):
	# reg_type (eg: HREGS)
	# addr     (eg: 0)
	# val      (eg: LSBF [255,0] for initial value = 0x00FF)
	
	# Call Counter : Increment and limit to uint16
	global _counter 
	_counter += 1
	if _counter>65535:
		_counter=0
	# Elapse time: limit value to uint16
	_ms = time.ticks_ms()%65535

	val[0] = _counter # 4x0 field
	val[1] = _ms      # 4x1 field 
	modbus_slave.set_hreg(0, val)
	
def set_counter( reg_type, address, val ):
	# reg_type (eg: HREGS)
	# addr     (eg: 0)
	# val      (eg: [300] )
	global _counter
	# print( reg_type, address, val )
	_counter = val[0]


# Registers and their default values
slave_registers = {
    "COILS": {
        "0x bits": {
            "register": 0,
            "len": 8,
            # WARNING: Bit 7 on left, Bit 0 on right
            # bit 1 = LED; bit 0 = Btn LED
            "val": [False,False,False,False,False,False,False,False]
        }
    },
    "HREGS": {
        "4x fields": {
            "register": 0,
            "len": 2,
            # 1st-> 4x0 field = 65280 ; 2nd-> 4x1 field = 1 
            # Values must be uint16 0-65535
            "val": [0xFF00,1 ], 
            "on_get_cb" : get_counters,
            "on_set_cb" : set_counter
        }
    },
    "ISTS": {        
    },
    "IREGS": {
    }
}

print( 'Setup slave registers...' )
modbus_slave.setup_registers( registers=slave_registers )

print( 'Start slave processing...' )
while True:
	# Process incoming request
	result = modbus_slave.process()

	# Place your processing code here
	time.sleep_ms(500)

PymateIO all right reserved © 2026 - Written by MCHobby for PymateIO