Теория
Modbus — коммуникационный протокол, основанный на архитектуре ведущий-ведомый (master-slave). Использует для передачи данных интерфейсы RS-485, RS-422, RS-232, а также Ethernet сети TCP/IP.
NModbus – большая библиотека на C#, включающая в себя реализацию всех режимов работы с протоколом. Модель реализации классов этой библиотеки позволяет работать с любым Modbus-устройством, но только с одним, поскольку классы библиотеки инкапсулируют в себе порт, не позволяя реализовать синхронизацию между несколькими Modbus-объектами. Данный протокол достаточно популярен при разработке разной периферии для умного дома, а так же интернета вещей.
Команды
Руководство, с перечнем всех команд можно найти в официальном мануале, там так же есть примеры кода для TCP/IP соединений.
Итак: для того, чтобы управлять чем-либо, нам необходимо знать, что и куда отправлять. Значит нам нужна карта регистров.
Уточню, что ячейки регистра бывают:
1. Только для чтения
2. Для чтения и записи
3. Только для записи(подтверждение записи допустимо выдавать кодом ошибки)
Самая простая карта, выглядит примерно таким образом:
Скриншот


Практика
Я пользуюсь пробной версией симулятора Modbus Tools и COM портами от MOXA с RS-485 интерфейсом.
COM порт


После того, как Вы создали проект, необходимо интегрировать в него библиотеки NModbus. Я рекомендую использовать VisualStudio, поскольку сделать это в нем достаточно просто с помощью NuGet:
Шаг 1-й


Шаг 2-й


В Modbus Tools нам необходимо задать параметры соединения.
Параметры открываются на F3, либо по вкладке «Connection».
Для демонстрации я использую следующие настройки Slave устройства:
Параметры порта


После того, как устройства подключились друг к другу можно идти дальше.
В случае если Вам не удается подключить устройства: проверьте настройки, убедитесь в том, что драйвера для COM портов установлены и настроены верно.
Пример простой программы
using Modbus.Device;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus
{
class Program
{
static void Main(string[] args)
{
SerialPort serialPort = new SerialPort(); //Create a new SerialPort object.
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.Open();
ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);
byte slaveID = 1;
ushort startAddress = 0;
ushort numOfPoints = 1;
ushort[] holding_register = master.ReadHoldingRegisters(slaveID, startAddress,
numOfPoints);
Console.WriteLine(holding_register);
Console.ReadKey();
}
}
}
Скриншот


Важно: если Вы разрабатываете, что то сложнее, чем пример выше — необходимо следить за тем, чтобы пакеты не терялись. Возникает необходимость подсчета контрольных сумм, об этом можно почитать здесь.