Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Modbus протокол для полного идиота.

976
01 декабря 2011 года
mikhalych
198 / / 04.01.2009
Есть вот такие MPPT(Maximum Power Point Tracking Charge Controller) контроллеры. Стоит задача читать с них данные (вольт, ватт, температура и т.д.) через протокол Modbus.
В сетевой программировании я полный идиот. Пните пожалуйста в нужном направлении, как и с чего начать. В сети очень много инфа про работу с протоколом Modbus. Но для каждого девайса своя имплементация протокола и по этому я не смог ни один бит прочитать с моего контроллера.
Или нужно ли укреплять базу (научиться работать с протоколами) ? :confused::facepalm:
14
01 декабря 2011 года
Phodopus
3.3K / / 19.06.2008
Так там же есть я смотрю и документация и руководства какие-то..
443
02 декабря 2011 года
REmindER
292 / / 23.03.2003
Почитал справку, на первый взгляд никаких сложностей нет. Организовывается TCP соединение к хосту по 502 порту. Формируется ADU-пакет в соответствии со спецификацией протокола. Вот даже примерчик нашел на Visual Basic.
976
02 декабря 2011 года
mikhalych
198 / / 04.01.2009
Цитата: REmindER
Организовывается TCP соединение к хосту по 502 порту. Формируется ADU-пакет в соответствии со спецификацией протокола.


Можно чуточку поподробнее ? Потому что как я уже упоминал в работе с сокетами я полный идиот.

5
02 декабря 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: mikhalych
я уже упоминал в работе с сокетами я полный идиот.

Тогда может вам вообще не стоит заниматься программированием?

976
02 декабря 2011 года
mikhalych
198 / / 04.01.2009
Цитата: hardcase
Тогда может вам вообще не стоит заниматься программированием?



Просто мы пишем одинакого рода программы и как бы с сокетами на прямую нету опыта. Согласен, всему нужно учиться самому, что я сейчас и делаю.

443
02 декабря 2011 года
REmindER
292 / / 23.03.2003
Цитата: mikhalych
Можно чуточку поподробнее ? Потому что как я уже упоминал в работе с сокетами я полный идиот.


Если под .NET, то что-то подобное:

Код:
...
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 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();
    }


.NET никогда не использовал, так что не гарантирую правильность кода.
976
02 декабря 2011 года
mikhalych
198 / / 04.01.2009
REmindER

Спасибо. Оказывается ни так уж и трудно, открывай посылай/принимай и закрывай сокет.
5
03 декабря 2011 года
hardcase
4.5K / / 09.08.2005
Вот только для работы с пакетами данных лучше объявить отдельные классы, иначе в смещениях можно сильно запутаться.

P.S. socket.Connected бесполезное свойство, для детекта отключения другой стороны нужно ловить SocketException.
443
03 декабря 2011 года
REmindER
292 / / 23.03.2003
Это уже детали. Никто данный пример за основу брать не предлагает, а приведен он лишь с целью максимально просто показать последовательность действий.
976
04 декабря 2011 года
mikhalych
198 / / 04.01.2009
Спасибо.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог