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: lock object to synchronize Modbus memory access between the user program and the Modbus RTU slave process.
  • 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 *
 
OUTPUT_PINS = (25, 16, 18, 20)
INPUT_PINS  = (6,  8,  10)
ADC_CHANS   = (0,  1,  2)
 
coils           = bytearray(1)
discrete_inputs = bytearray(1)
input_regs      = bytearray(6)
holding_regs    = bytearray(2)
mem_lock        = _thread.allocate_lock()
 
for pin in OUTPUT_PINS:
    Output(pin)
    Low(pin)
for pin in INPUT_PINS:
    Input(pin)
 
SetModbus(0, 1, coils, discrete_inputs, input_regs, holding_regs, mem_lock)
 
while True:
    # Read coils snapshot under lock
    mem_lock.acquire()
    try:
        coils_byte = coils[0]
    finally:
        mem_lock.release()
 
    # Drive outputs from that snapshot
    for i, pin in enumerate(OUTPUT_PINS):
        if coils_byte & (1 << i):
            High(pin)
        else:
            Low(pin)
 
    # Sample physical inputs outside the lock
    din_byte = 0
    for i, pin in enumerate(INPUT_PINS):
        if In(pin):
            din_byte |= (1 << i)
 
    adc_vals = [ADIn(ch) for ch in ADC_CHANS]
 
    # Publish a coherent snapshot and read setpoint atomically
    mem_lock.acquire()
    try:
        discrete_inputs[0] = din_byte
 
        for i, val in enumerate(adc_vals):
            struct.pack_into('>H', input_regs, i * 2, val)
 
        setpoint = struct.unpack_from('>H', holding_regs, 0)[0]
    finally:
        mem_lock.release()
 
    time.sleep(0.010)
logicpython/cubloc_api/setmodbus.1776142082.txt.gz · Last modified: by mfranklin