ModBus master & PHP

Обсуждение статей, технологий домашней автоматизации, программных и аппаратных решений
Ответить
THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

ModBus master & PHP

Сообщение THK » 24 дек 2011, 20:53

Столкнулся с проблемой - прикрутить модуль входов/выходов Momentum с коммуникационным модулем 170ETH11002 к своей системе. Модуль совсем не бюджетный, но мне кажется решение проблемы может быть интересно участникам форума.

А именно, в теме:

Элементы "умного дома" на Beckhoff рассказывается о контроллере Beckhoff BC9000 и каплере BK9000, поддерживающем протокол ModBus TCP и в теме

Открытая система MajorDoMo упоминается о использовании платы Arduino (в подробности я не вдавался), для которой тоже есть реализация протокола ModBus, а когда есть все исходники лучше выбрать проверенное временем, промышленное решение, чем изобретать свой протокол (ИМХО).

Вот, что я накопал (копия с моей странички):
Утилита Modpoll.

* http://www.focus-sw.com/fieldtalk/modpoll.html Версия 2.4
* http://www.modbusdriver.com/modpoll.html Версия 3.1

Эта утилитка работает как под Windows, так и под Linux. Пользоваться ей крайне просто, копируете исполняемый файл из архива на диск и в командной строке набираете (пример для win):

Отключить WD-таймер
C:\>modpoll.exe -m tcp -r 61441 192.168.100.120 0

Записать выходы
C:\>modpoll.exe -m tcp -r 1 192.168.100.120 8888

Надо обратить внимение на то, что адрес регистра WD, по описанию модуля Momentum 461441 в десятичном виде, а для работы Modpoll необходимо указвать 61441. Почему так не знаю, но тоже относится и к другим регистрам. Единственный недостаток Modpoll, на мой взгляд, это закрытость кода.

Так-как планировалось писать скрипт управления на PHP, я счел не совсем удобным пользоваться функцией exec и решил поискать готовые решения на PHP.

Нашлось две реализации протокола Modbus на PHP:

* PhpModbus - http://code.google.com/p/phpmodbus/ , но этот проект не поддерживает Modbus TCP/IP
* Class: ModbusTcp - http://www.phpclasses.org/package/377-P ... kage-.html , этот проект удовлетворил все мои потребности.

Для примера, вот небольшой скриптик (на 99% это пример из проекта):

Код: Выделить всё

<?php
require_once "Class_ModbusTcp.inc";
$Plc = new ModbusArray;
$Plc->SetAdIpPLC ("192.168.100.120");

/********************************************************/
$Adr = 400001;
$Values = array(3333);
// Записать значение $Values по адресу $Adr
$result = $Plc->WriteModbus($Adr,$Values) ;   
/********************************************************/

$Plc->print_r_log($result) ;
$Plc->ModClose();
unset($Plc);
?>
И еще ресурсы по Modbus'у: http://www.modbus.org/tech.php Именно там я встречал реализацию для Arduino.
Последний раз редактировалось THK 27 дек 2011, 20:40, всего редактировалось 1 раз.

sergejey
Сообщения: 131
Зарегистрирован: 03 окт 2011, 17:38

Re: ModBus & PHP

Сообщение sergejey » 26 дек 2011, 14:03

Если будет интерес в использовании MajorDoMo в качестве общего контроллера и интерфейса, то всячески готов помочь в скрещивании :) Система написана на PHP, так что добавить "мост" для управления этим протоколом большого труда не должно составить. Как мне видится, могут быть заведены объекты в MajorDoMo, а этот мост может обращаться с железом, чтобы связывать свойства и события от этих девайсов с объектами в системе, а дальше эти объекты могут использоваться в общем интерфейсе, сценариях и т.п.

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: ModBus & PHP

Сообщение THK » 26 дек 2011, 19:03

Я понимаю, что добавить эту реализацию протокола к Вашей системе не составит большого труда, только вот никак не соберусь поставить ее, себе на сервер. Пользуюсь своим интерфейсом. А ваш интерфейс можно засунуть не в корень WEB-сервера, а в отдельную папку?

sergejey
Сообщения: 131
Зарегистрирован: 03 окт 2011, 17:38

Re: ModBus & PHP

Сообщение sergejey » 26 дек 2011, 20:27

THK писал(а):Я понимаю, что добавить эту реализацию протокола к Вашей системе не составит большого труда, только вот никак не соберусь поставить ее, себе на сервер. Пользуюсь своим интерфейсом. А ваш интерфейс можно засунуть не в корень WEB-сервера, а в отдельную папку?
Теоретически да, но, признаться, не пробовал сам :) Скорее всего, нужно будет обновлять пути. Но может быть проще сделать виртуальный хост и в него поставить систему для вызова от корня. Может и из папки проблем не составит особых, но, повторюсь, не пробовал :)

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: ModBus master & PHP

Сообщение THK » 02 янв 2012, 23:29

Вышла новая версия Phpmodbus 0.5.r70.
Добавлена поддержка протокола ModbusTCP.
Пока не тестировал... Проверю, отпишусь.

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: ModBus master & PHP

Сообщение THK » 03 янв 2012, 11:22

Проверил работу библиотеки, работает :).
Единственная загвоздка оказалась с адресацией регистров.
Оказалось, что библиотека использует не адресацию Modbus, а использует адресацию контроллеров Telemecanique TSX.
Для лучшего понимания адресации советую почитать https://sites.google.com/site/fieldbusb ... modbus-rus У меня "просветление" настало после прочтения "Пример 6.3. MODBUS. Модель данных для различных типов устройств".
Вкратце: для регистра 461441 адрес будет равен 461441-400001=61440, а для 400001 адрес 400001-400001=0, но это действительно только для десятичного представления адресов регистров, т.к. четверка в начале не является частью адреса, а указывает на способ адресации (16-битные слова) и ее надо просто откинуть и из адреса вычесть 1 (адреса Modbus начинаются с 1).

PS Для себя решил использовать эту библиотеку по следующим причинам:
1. Проект живой и в случае каких-то проблем можно связаться с разработчиками.
2. Есть поддержка Modbus UDP. (В дальнейшем планирую использовать)
3. Качество кода Class: ModbusTcp оставляет желать лучшего (сужу по примерам, т.к. до самого класса добраться не успел)

PPS В примерах к PhpModbus есть пример обмена с WAGO 750-841

select
Сообщения: 55
Зарегистрирован: 15 дек 2012, 20:06

Re: ModBus master & PHP

Сообщение select » 27 сен 2017, 08:32

Убился уже с этой библиотекой!
Прошу помочь. Итак, есть библиотека Phpmodbus_0.8. Впрочем и с версией 0.7 все симптомы те же самые.
ПЛК Beckhoff BC9000. PHP5 на armbian:

Код: Выделить всё

Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
Пакет php-net-socket установлен.
Пытаюсь запустить пример example_750841_Mmemory.php, естественно установив IPадрес BC9000.
При выборе UDP протокола в ответ получаю:

Код: Выделить всё

<pre>readMultipleRegisters: START
Connected
Packet: 405000000006000340180001
Send
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
Wait data ...
</pre>exception 'Exception' with message 'Watchdog time expired [ 5 sec]!!! Connection to 192.192.3.43 is not established.' in /home/smarthouse/php/Phpmodbus/ModbusMaster.php:166
Stack trace:
#0 /home/smarthouse/php/Phpmodbus/ModbusMaster.php(442): ModbusMaster->rec()
#1 /home/smarthouse/php/example_750841_Mmemory.php(16): ModbusMaster->readMultipleRegisters(0, 16408, 1)
Если же выбрать протокол TCP, то получаю тайм-аут:

Код: Выделить всё

root@smarthouse:/home/smarthouse/php# ./example_750841_Mmemory.php
<pre>readMultipleRegisters: START
</pre>exception 'Exception' with message 'socket_connect() failed.</br>Reason: ()Operation now in progress' in /home/smarthouse/php/Phpmodbus/ModbusMaster.php:108
Stack trace:
#0 /home/smarthouse/php/Phpmodbus/ModbusMaster.php(436): ModbusMaster->connect()
#1 /home/smarthouse/php/example_750841_Mmemory.php(16): ModbusMaster->readMultipleRegisters(0, 16408, 1)
При этом, виндовый монитор Modbus Master Tool спокойно по TCP все значения отображает.
Есть подозрение, что Beckhoff BC9000 не умеет modbus UDP, а я - не умею modbus TCP.
Прошу помощи - дайте пожалуйста примеры рабочих скриптов и окружения.

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: ModBus master & PHP

Сообщение THK » 27 сен 2017, 10:11

Похоже Вы ошибаетесь с адресом регистра, выложите свой скрипт, будет понятнее.
Вот здесь viewtopic.php?p=1923#p1923 я писал как формируется адрес регистра.
Здесь viewtopic.php?p=1865#p1865 100% рабочий пример - записывает 3333 в регистр 1 (протокол TCP)

PS Сейчас эти библиотеки не использую, по modbus'у работает только Wago с удаленными I/O минуя сервер.

select
Сообщения: 55
Зарегистрирован: 15 дек 2012, 20:06

Re: ModBus master & PHP

Сообщение select » 27 сен 2017, 18:53

Мой скрипт:

Код: Выделить всё

#!/usr/bin/php
<?php

require_once dirname(__FILE__) . '/Phpmodbus/ModbusMaster.php';

// Create Modbus object
$ip = "192.192.3.43";
$modbus = new ModbusMaster($ip, "TCP");

try {
    // FC 3
    $moduleId = 0;
    $reference = 16408;
    $mw0address = 16408;
    $quantity = 1;
    $recData = $modbus->readMultipleRegisters($moduleId, $reference, $quantity);
}
catch (Exception $e) {
    echo $modbus;
    echo $e;
    exit;
}

?>
При этом читаю и пишу с windows машины:

Код: Выделить всё

D:\>c:\temp\modpoll -m tcp -t 3 -r 16407 -1 192.168.3.43
modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2013 proconX Pty Ltd
Visit http://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: MODBUS/TCP
Slave configuration...: address = 1, start reference = 16407, count = 1
Communication.........: 192.168.3.43, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table

-- Polling slave...
[16407]: 2

D:\>c:\temp\modpoll -m tcp -t 4 -r 16407  192.168.3.43 1
modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2013 proconX Pty Ltd
Visit http://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: MODBUS/TCP
Slave configuration...: address = 1, start reference = 16407, count = 1
Communication.........: 192.168.3.43, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

Written 1 reference.
Или так:
psc2.jpg
psc2.jpg (77.53 КБ) 6743 просмотра
psc1.jpg
psc1.jpg (35.03 КБ) 6743 просмотра
Полозреваю, что я наступаю на общественные грабли. Но в упор их не вижу.
Адреса, кстати пробовал и 0 и из примера.

select
Сообщения: 55
Зарегистрирован: 15 дек 2012, 20:06

Re: ModBus master & PHP

Сообщение select » 27 сен 2017, 18:58

THK писал(а):Похоже Вы ошибаетесь с адресом регистра, выложите свой скрипт, будет понятнее.
Вот здесь viewtopic.php?p=1923#p1923 я писал как формируется адрес регистра.
Здесь viewtopic.php?p=1865#p1865 100% рабочий пример - записывает 3333 в регистр 1 (протокол TCP)

PS Сейчас эти библиотеки не использую, по modbus'у работает только Wago с удаленными I/O минуя сервер.
Кстати! Может это важно: я использую php-cli, запускаю скрипты из консоли, не из апача.
И ваш 100% рабочий пример (вторая ссылка выше) выдает вот что:
root@smarthouse:/home/smarthouse/php/modbustcp# ./2

Код: Выделить всё

<?
/*
 -------------- VERSION 1.4 du 28/11/2007 ---------
        Fiabilisation fonction ecriture des registres (Fonctions 16)

 -------------- VERSION 1.3 du 17/04/2003 ---------
        Rajout Ecriture d'une Bobine  ( Fct 5 )

 -------------- VERSION 1.2 du 17/11/2002 ---------
        Rajout d'un mode Simulation ( retourne des valeurs aleatoires sans connexions )

 -------------- VERSION 1.1 du 01/07/2002 ---------
        Rajout du routage dynamique avec passerelle 174 CEV 200 30 MB+ / ModBusTcp

 -------------- VERSION 1.0 du 30/10/2001 ---------
        Creation de la classe

------------------------------------------------------------------
--                       EXEMPLES                               --
------------------------------------------------------------------

------ Lecture d'un tableau de registres ou bits contigus  --------

        ...
        include "class_ModbusTcp.inc";

        $Plc = new ModbusTcp;
        $Plc->SetAdIpPLC ("xx.xx.xx.xx");

        $Plc->Unit = 5;  // Sans routage dynamique
        $Plc->BridgeRoute = array( 52, 11, 0, 0, 0 );  // Avec routage dynamique si passerelle 174CEV20030

        $valeurs = $Plc->ReadModbus( "400001", 50 ); // Lecture de 50 mots a partir de 400001
        print_r ($valeurs); echo "<br>";

        $valeurs = $Plc->ReadModbus( "300001", 15 ); // Lecture de 15 mots d'entree a partir de 300001
        print_r ($valeurs); echo "<br>";

        $valeurs = $Plc->ReadModbus( "000001", 200 ); // Lecture de 200 bits de sortie a partir de 000001
        print_r ($valeurs); echo "<br>";

        $valeurs = $Plc->ReadModbus( "100001", 125 ); // Lecture de 125 bits d'entr▒e a partir de 100001
        print_r ($valeurs); echo "<br>";
        ...

        $Plc->ModClose();


------- Lecture d'un tableau de registres aleatoires -------------
Дальше я порезал вывод. Что я делаю не так?
p.s. спасибо за терпение!

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: ModBus master & PHP

Сообщение THK » 01 окт 2017, 12:51

select, не вижу смысла копипастить текст из поста выше viewtopic.php?p=1923&sid=d6eb7e4d10156e ... f57c#p1923
Попробуйте вместо адреса 16408 указать 400001+16408=416409 - должно помочь. Возможно надо указать адрес 416408, если у Вас адресация регистров начинается не с 0, а с 1...

PS Посмотрите "Пример 6.3. MODBUS. Модель данных для различных типов устройств."

select
Сообщения: 55
Зарегистрирован: 15 дек 2012, 20:06

Re: ModBus master & PHP

Сообщение select » 05 окт 2017, 08:54

Разобрался. Было два момента:
1. Не был установлен пакет для работы с сокетами в php.
2. При работе по UDP библиотека некорректно считает контрольную сумму (видно в tcpdump), видимо поээтому контроллер игнорирует такие обращения.
После установки пакета при работе по TCP все заработало.
Кстати у Beckhoff BC9000 адресация рабтает немного по другому:
$recData = $modbus->readMultipleRegisters(0, 16414, 1); - происходит обращение именно к 16414 регистру. Вычислять адрес не нужно.

Спасибо большое за помощь!

THK
Модератор
Сообщения: 588
Зарегистрирован: 18 мар 2011, 19:00
Откуда: Серпухов, МО

Re: ModBus master & PHP

Сообщение THK » 07 окт 2017, 17:42

select писал(а):Кстати у Beckhoff BC9000 адресация рабтает немного по другому:
$recData = $modbus->readMultipleRegisters(0, 16414, 1); - происходит обращение именно к 16414 регистру. Вычислять адрес не нужно.
Рад, что все получилось и спасибо за информацию по адресации - закролась идея обращаться к контроллеру Wago по Modbus, а не с помощью хака на SSI. Буду иметь в виду. :)

Ответить