PymateIO-HMI-numeric-input: Difference between revisions
| (6 intermediate revisions by the same user not shown) | |||
| Line 8: | Line 8: | ||
This example will show how Pymate script will grab the integer value sent by the HMI display. | 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 == | == HMI Example Project == | ||
| Line 24: | Line 26: | ||
[[File:PymateIO-HMI-01-03.png]] | [[File: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. | |||
<nowiki>Modbus: HREGS READ <Request fct=3 qty=2 addr=0 data=None> | <nowiki>Modbus: HREGS READ <Request fct=3 qty=2 addr=0 data=None> | ||
| Line 35: | Line 37: | ||
Modbus: HREGS READ <Request fct=3 qty=2 addr=0 data=None> | Modbus: HREGS READ <Request fct=3 qty=2 addr=0 data=None> | ||
</nowiki> | </nowiki> | ||
The Pymate script just need to declare the '''on_set_cb''' for the '''HREGS''' register definition to catch the call. | |||
<syntaxhighlight lang="python" line> | |||
# 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": { | |||
} | |||
} | |||
</syntaxhighlight> | |||
The following section remind the {{fname|get_counters}} callback returning the {{fname|_counter}} variable value. | |||
The interest lies in the implementation of the {{fname|set_counter()}} function receiving the value from the HMI Display then store it for future usage | |||
<syntaxhighlight lang="python" line> | |||
_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] | |||
</syntaxhighlight> | |||
As simple as thats!!! | |||
== Full script == | |||
<syntaxhighlight lang="python" line> | |||
# 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) | |||
</syntaxhighlight> | |||
{{PYMATE-TRAILER}} | {{PYMATE-TRAILER}} | ||
Latest revision as of 19:30, 14 June 2026
Abstract
After our first example with the HMI Display and PymateIO it is time to look for some advanced feature.
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.
With the following field definition
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


