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