====== 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 =====
* [[https://docs.micropython.org/en/latest/library/builtins.html#TypeError|TypeError]]: An argument has an invalid type.
* [[https://docs.micropython.org/en/latest/library/builtins.html#ValueError|ValueError]]: ''baudRate'', ''protocol'', ''recvSize'', ''sendSize'', or ''slaveAddress'' is outside the supported range.
* [[https://docs.micropython.org/en/latest/library/builtins.html#RuntimeError|RuntimeError]]: 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)
for pin in OUTPUT_PINS:
Output(pin)
Low(pin)
for pin in INPUT_PINS:
Input(pin)
# Configure and start the Modbus RTU slave process
UART_CHANNEL = 0
BAUD_RATE = 115200
PROTOCOL = 3 # 8N1
BUFFER_SIZE = 64
SLAVE_ADDRESS = 1
coils = bytearray(1)
discrete_inputs = bytearray(1)
input_regs = bytearray(6)
holding_regs = bytearray(2)
mem_lock = _thread.allocate_lock()
SetModbus(UART_CHANNEL,
BAUD_RATE,
PROTOCOL,
BUFFER_SIZE,
BUFFER_SIZE,
SLAVE_ADDRESS,
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)