Table of Contents

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

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

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()