User Tools

Site Tools

한국어

logicpython:cubloc_api:setmodbus

This is an old revision of the document!


SetModbus

Start the LogicPython Modbus RTU slave worker using a pre-opened UART channel.

Syntax

from cubloc import SetModbus
 
SetModbus(channel: int, 
    slaveAddress: int,
    coils: object,
    discreteInputs: object,
    inputRegisters: object,
    holdingRegisters: object,
    memoryLock: object,
    returnInterval: int = 0)

Parameters

  • channel: RS-232 channel number. OpenCom must already be called for this channel.
  • slaveAddress: Modbus unit ID (1 to 247).
  • coils: Writable bit-packed coil buffer (8 coils per byte).
  • discreteInputs: Writable bit-packed discrete-input buffer (8 inputs per byte).
  • inputRegisters: Writable input-register byte buffer (2 bytes per register).
  • holdingRegisters: Writable holding-register byte buffer (2 bytes per register).
  • memoryLock: User-created lock object passed through to logic_python.modbus.start_modbus.
  • returnInterval: Non-blocking delay in microseconds before sending a response (default 0).

Exceptions

  • TypeError: An argument has an invalid type.
  • ValueError: slaveAddress is outside the supported range.
  • RuntimeError: OpenCom has not been called for this channel or Modbus startup failed.

Example

import struct
import time
import _thread
from cubloc import *
 
# Coils 0-3           -> digital outputs on GP14, GP16, GP18, GP20
# Discrete inputs 0-2 <- digital inputs  on GP6, GP8, GP10
# Input registers 0-2 <- ADC readings    on ADC0 (GP26), ADC1 (GP27), ADC2 (GP28)
# Holding register 0  -> setpoint value written by the Modbus master
 
OUTPUT_PINS = (14, 16, 18, 20)
INPUT_PINS  = (6,  8,  10)
ADC_CHANS   = (0,  1,  2)
 
# Allocate Modbus memory regions
coils           = bytearray(1)   # 8 coils (1 byte, bits 0-3 used)
discrete_inputs = bytearray(1)   # 8 discrete inputs (1 byte, bits 0-2 used)
input_regs      = bytearray(6)   # 3 input registers x 2 bytes each
holding_regs    = bytearray(2)   # 1 holding register x 2 bytes
mem_lock        = _thread.allocate_lock()
 
# Configure physical I/O
for pin in OUTPUT_PINS:
    Output(pin)
    Low(pin)
for pin in INPUT_PINS:
    Input(pin)
 
# Open UART1 (GP4 = TX, GP5 = RX) at 9600 baud, 8N1
OpenCom(1, 9600, 0, 1024, 1024)
 
# Start Modbus RTU slave, address 1
SetModbus(1, 1, coils, discrete_inputs, input_regs, holding_regs, mem_lock)
 
# Main loop: mirror Modbus memory to/from physical I/O every 10 ms
while True:
    with mem_lock:
        # Drive output pins from coil bits (master writes coils 0-3)
        for i, pin in enumerate(OUTPUT_PINS):
            if coils[0] & (1 << i):
                High(pin)
            else:
                Low(pin)
 
        # Capture digital inputs and store as discrete-input bits (master reads)
        din_byte = 0
        for i, pin in enumerate(INPUT_PINS):
            if In(pin):
                din_byte |= (1 << i)
        discrete_inputs[0] = din_byte
 
        # Capture ADC readings and store in input registers (big-endian, master reads)
        for i, ch in enumerate(ADC_CHANS):
            struct.pack_into('>H', input_regs, i * 2, ADIn(ch))
 
        # Read setpoint value from holding register 0 (master writes)
        setpoint = struct.unpack_from('>H', holding_regs, 0)[0]
 
    time.sleep(0.010)
logicpython/cubloc_api/setmodbus.1775802947.txt.gz · Last modified: by mfranklin