...
using System.Net;
using System.Net.Sockets;
...
string hostString = "...тут IP контроллера или его DNS-имя...";
Socket client;
IPHostEntry host = Dns.Resolve(hostString);
IPEndPoint endPoint = new IPEndPoint(host.AddressList[0], 502);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(endPoint);
Modbus протокол для полного идиота.
вот такие MPPT(Maximum Power Point Tracking Charge Controller) контроллеры. Стоит задача читать с них данные (вольт, ватт, температура и т.д.) через протокол Modbus.
В сетевой программировании я полный идиот. Пните пожалуйста в нужном направлении, как и с чего начать. В сети очень много инфа про работу с протоколом Modbus. Но для каждого девайса своя имплементация протокола и по этому я не смог ни один бит прочитать с моего контроллера.
Или нужно ли укреплять базу (научиться работать с протоколами) ? :confused::facepalm:
Есть
В сетевой программировании я полный идиот. Пните пожалуйста в нужном направлении, как и с чего начать. В сети очень много инфа про работу с протоколом Modbus. Но для каждого девайса своя имплементация протокола и по этому я не смог ни один бит прочитать с моего контроллера.
Или нужно ли укреплять базу (научиться работать с протоколами) ? :confused::facepalm:
Так там же есть я смотрю и документация и руководства какие-то..
примерчик нашел на Visual Basic.
Почитал справку, на первый взгляд никаких сложностей нет. Организовывается TCP соединение к хосту по 502 порту. Формируется ADU-пакет в соответствии со спецификацией протокола. Вот даже
Цитата: REmindER
Организовывается TCP соединение к хосту по 502 порту. Формируется ADU-пакет в соответствии со спецификацией протокола.
Можно чуточку поподробнее ? Потому что как я уже упоминал в работе с сокетами я полный идиот.
Цитата: mikhalych
я уже упоминал в работе с сокетами я полный идиот.
Тогда может вам вообще не стоит заниматься программированием?
Цитата: hardcase
Тогда может вам вообще не стоит заниматься программированием?
Просто мы пишем одинакого рода программы и как бы с сокетами на прямую нету опыта. Согласен, всему нужно учиться самому, что я сейчас и делаю.
Цитата: mikhalych
Можно чуточку поподробнее ? Потому что как я уже упоминал в работе с сокетами я полный идиот.
Если под .NET, то что-то подобное:
Код:
Дальше смотрим описание протокола Modbus TCP:
Цитата:
Для протокола Modbus TCP ADU выглядит следующим образом:
ид транзакции | ид протокола | длина пакета | адрес slave | код функции | данные
где
ид транзакции - два байта, обычно нули
ид протокола - два байта, нули
длина пакета - два байта - длина следующей за этим полем части пакета
адрес slave - адрес подчинённого устройства, к которому адресован запрос. Обычно игнорируется, если соединение установлено с конкретным устройством. Может использоваться, если соединение установлено с бриджом, который выводит нас, например, в сеть RS485.
К примеру, функция 17 (11 Hex) Чтение идентификатора подчиненного - http://www.musidora.ru/STANDARTS/Modbus_Rus.doc
Код:
if (client.Connected)
{
// пакет запроса
byte[] buf = new byte[64];
// длина - данных нет, только код функции
int dataLength = 1;
// ид транзакции
buf[0] = 0;
buf[1] = 0;
// ид протокола - зарезервировано по спецификации
buf[2] = 0;
buf[3] = 0;
// длина
byte[] dl = BitConverter.GetBytes(dataLength + 1);
buf[4] = dl[0];
buf[5] = dl[1];
// адрес slave
buf[6] = 0;
// код функции
buf[7] = 17;
client.Send(buf, dataLength + 7, SocketFlags.None);
// пакет ответа
byte[] response = new byte[1024];
client.Receive(response);
// response[9] - идентификатор устройства
// response[10] - статус (00 - OFF, FF - ON)
// ...
client.Shutdown(SocketShutdown.Both);
client.Close();
}
{
// пакет запроса
byte[] buf = new byte[64];
// длина - данных нет, только код функции
int dataLength = 1;
// ид транзакции
buf[0] = 0;
buf[1] = 0;
// ид протокола - зарезервировано по спецификации
buf[2] = 0;
buf[3] = 0;
// длина
byte[] dl = BitConverter.GetBytes(dataLength + 1);
buf[4] = dl[0];
buf[5] = dl[1];
// адрес slave
buf[6] = 0;
// код функции
buf[7] = 17;
client.Send(buf, dataLength + 7, SocketFlags.None);
// пакет ответа
byte[] response = new byte[1024];
client.Receive(response);
// response[9] - идентификатор устройства
// response[10] - статус (00 - OFF, FF - ON)
// ...
client.Shutdown(SocketShutdown.Both);
client.Close();
}
.NET никогда не использовал, так что не гарантирую правильность кода.
Спасибо. Оказывается ни так уж и трудно, открывай посылай/принимай и закрывай сокет.
P.S. socket.Connected бесполезное свойство, для детекта отключения другой стороны нужно ловить SocketException.
Это уже детали. Никто данный пример за основу брать не предлагает, а приведен он лишь с целью максимально просто показать последовательность действий.
Спасибо.