User Tools

Site Tools

한국어

logicpython:cubloc_api:setmodbus

SetModbus

Configure UART settings and start the LogicPython Modbus RTU slave process.

Syntax

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

Parameters

  • channel: Serial channel number. Channel 0 maps to UART0 (GP0/GP1) and channel 1 maps to UART1 (GP4/GP5).
  • baudRate: Serial baud rate (2400 to 921600).
  • protocol: Encoded bit field for data bits, parity, and stop bits. See the tables below.
  • recvSize: Receive buffer size in bytes (1 to 4096).
  • sendSize: Send buffer size in bytes (1 to 4096).
  • 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: Delay in microseconds before replying to a Modbus query from the Modbus master (default 0).

protocol bit layout:

Field Bits Meaning
Data bits 1..0 00=5 bits, 01=6 bits, 10=7 bits, 11=8 bits
Stop bits 2 0=1 stop bit, 1=2 stop bits
Parity 4..3 00=None, 10=Even, 11=Odd (01 is reserved and raises ValueError)

Common protocol values:

protocol Frame format
3 8N1
11 8E1
19 8O1
7 8N2

Exceptions

  • TypeError: An argument has an invalid type.
  • ValueError: baudRate, protocol, recvSize, sendSize, or slaveAddress is outside the supported range.
  • RuntimeError: Modbus startup failed.

Example

import _thread
from cubloc import *
from machine import *
import os
from time import sleep
 
machine = os.uname().machine
print(machine)
 
if "LP126T" in machine:
    OUTPUT_PINS = (3, 16, 17, 18, 19)
    INPUT_PINS  = (32, 33, 34, 35, 36, 37, 38, 39)
    ADC_CHANS   = (40, 41, 42, 43, 44, 45)
else:
    OUTPUT_PINS = (25, 16, 17, 18)
    INPUT_PINS  = (19, 20, 21)
    ADC_CHANS   = (26, 27, 28)
 
OUTPUT_COUNT = len(OUTPUT_PINS)
INPUT_COUNT  = len(INPUT_PINS)
ADC_COUNT    = len(ADC_CHANS)
ADC_BYTES    = ADC_COUNT << 1
 
# Initialize the physical IO
for pin in OUTPUT_PINS:
    Output(pin)
    Low(pin)
 
for pin in INPUT_PINS:
    Input(pin, 1)
 
# Configure and start the Modbus RTU slave process
UART_CHANNEL = 0
BAUD_RATE = 460800
PROTOCOL = 3        # 8N1
BUFFER_SIZE = 64
SLAVE_ADDRESS = 1
 
# Configure the Modbus memory
coils           = bytearray(1)
discrete_inputs = bytearray(2)
input_regs      = bytearray(16)
holding_regs    = bytearray(16)
mem_lock        = _thread.allocate_lock()
adc_shadow      = bytearray(ADC_BYTES)
setpoint        = 0
 
# Start the Modbus slave
print("Starting Modbus")
SetModbus(
    UART_CHANNEL,
    BAUD_RATE,
    PROTOCOL,
    BUFFER_SIZE,
    BUFFER_SIZE,
    SLAVE_ADDRESS,
    coils,
    discrete_inputs,
    input_regs,
    holding_regs,
    mem_lock
)
 
# Run in an infinite loop synchronizing Modbus memory with the physical IO
print("Starting the main loop")
while True:
    # Read the coil memory
    mem_lock.acquire()
    coils_byte = coils[0]
    mem_lock.release()
 
    # Drive digital outputs from the coil memory
    i = 0
    while i < OUTPUT_COUNT:
        Out(OUTPUT_PINS[i], (coils_byte >> i) & 1)
        i += 1
 
    # Read digital inputs
    din_byte = 0
    i = 0
    while i < INPUT_COUNT:
        if In(INPUT_PINS[i]):
            din_byte |= 1 << i
        i += 1
 
    # Transfer digital inputs to discrete input memory
    mem_lock.acquire()
    discrete_inputs[0] = din_byte
    mem_lock.release()
 
    # Read analog inputs
    i = 0
    j = 0
    while i < ADC_COUNT:
        val = ADIn(ADC_CHANS[i])
 
        adc_shadow[j]     = (val >> 8) & 0xFF
        adc_shadow[j + 1] = val & 0xFF
 
        i += 1
        j += 2
 
    # Transfer analog inputs to input register memory
    mem_lock.acquire()
    i = 0
    while i < ADC_BYTES:
        input_regs[i] = adc_shadow[i]
        i += 1
    mem_lock.release()
 
    # Transfer holding register memory to the setpoint variable
    mem_lock.acquire()
    setpoint = (holding_regs[0] << 8) | holding_regs[1]
    mem_lock.release()
logicpython/cubloc_api/setmodbus.txt · Last modified: by mfranklin