Show / Hide Table of Contents

    Modbus


    Modbus RTU

    Modbus is an asynchronous serial communications protocol that uses RS485 as its physical layer. It was developed for communicating with programmable logic controllers and is widely used for industrial applications. Modbus uses the a server/client relationship. With one server and up to 32 connections for Modbus RTU.

    The following sample is written for the SC20100S Dev Board and uses UART5 for communication:

    Tip

    Needed NuGets: GHIElectronics.TinyCLR.Devices.Uart, GHIElectronics.TinyCLR.Pins, GHIElectronics.TinyCLR.Devices.Modbus

    var serial = UartController.FromName(SC20100.UartPort.Uart5);
    
    var uartSetting = new UartSetting(){
            BaudRate = 19200,
            DataBits = 8,
            Parity = UartParity.None,
            StopBits = UartStopBitCount.One,
            Handshaking = UartHandshake.None,
        };
    
    serial.SetActiveSettings(uartSetting);
    
    serial.Enable();
    
    IModbusInterface mbInterface;
    mbInterface = ModbusRtuInterface(
        serial,
        19200,
        8,
        UartStopBitCount.One,
        UartParity.None);
    
    ModbusMaster mbMaster;
    mbMaster = new ModbusMaster(mbInterface);
    
    var mbTimeout = false;
    
    ushort[] reply = null;
    int count = 0;
    
    while (true) {
        try {
            mbTimeout = false;
    
            reply = mbMaster.ReadHoldingRegisters(10, 0, 1, 3333);
            count++;
    
            if (count == 5)
                break;
        }
        catch (System.Exception error) {
            Debug.WriteLine("Modbus Timeout");
            mbTimeout = true;
        }
    
        if (!mbTimeout) {
            Debug.WriteLine("Modbus : " + (object)reply[0].ToString());
        }
    
        Thread.Sleep(1000);
    }
    

    Modbus IP

    Modbus IP is Ethernet based Modbus that transfers data over standard Ethernet packets and devices. Modbus IP offers greater distances than Modbus RTU.

    In the example below setup the hardware as Modbus IP client. First create a ModbusClient class that is derived from ModbusDevice. `Modbus ID

    public class ModbusClient : ModbusDevice{
        public ModbusSlave(byte deviceAddress, object syncObject = null)
           : base(deviceAddress, syncObject) { }
    
    protected override string OnGetDeviceIdentification(ModbusObjectId objectId) {
        switch (objectId) {
            case ModbusObjectId.VendorName:
                return "GHI Electronics";
            case ModbusObjectId.ProductCode:
                return "101";
            case ModbusObjectId.MajorMinorRevision:
                return "1.0";
            case ModbusObjectId.VendorUrl:
                return "ghielectronics.com";
            case ModbusObjectId.ProductName:
                return "SitCore";
            case ModbusObjectId.ModelName:
                return "SCM20260D";
            case ModbusObjectId.UserApplicationName:
                return "Modbus Slave Test";
        }
        return null;
    }
    
    protected override ModbusConformityLevel GetConformityLevel() {
        return ModbusConformityLevel.Regular;
    }
    
    protected override ModbusErrorCode OnReadCoils(bool isBroadcast, ushort startAddress, ushort coilCount, byte[] coils) {
        try {
            for (int n = 0; n < coilCount; ++n) {
                    coils[n] = 1;
            }
            Debug.WriteLine("Master read coils");
            return ModbusErrorCode.NoError;
        } catch {
            Debug.WriteLine("error in on read coils registers");
            return base.OnReadCoils(isBroadcast, startAddress, coilCount, coils);
        }
    }
    
    protected override ModbusErrorCode OnReadHoldingRegisters(bool isBroadcast, ushort startAddress, ushort[] registers) {
        for (int n = 0; n < registers.Length; ++n) {
            registers[n] = 65530; // set number in each register for testing               
        }           
            Debug.WriteLine("Master Read Holding Registers - " + registers[0].ToString());
            return ModbusErrorCode.NoError;
        } catch {
            Debug.WriteLine("error in on read holding registers");
            return base.OnReadHoldingRegisters(isBroadcast, startAddress, registers);
        }
    
    
    // override On<ModusFunction> methods here
    

    Now, we can set up the instantiate the Modbus client device inside our code.

    
    ModbusDevice ModbusTCP_Device;
    ModbusTCP_Device = new ModbusSlave(248);
    ModbusTcpListener mbListner;
    mbListner = new ModbusTcpListener(ModbusTCP_Device, 502, 5, 1000);
    Thread.Sleep(100);
    ModbusTCP_Device.Start();
    
    • Improve this Doc
    ☀
    ☾

    Back to top

    Back to top Copyright © 2022 GHI Electronics, LLC
    Generated by DocFX