Modbus Slave TCP/IP

kip100
Offline
Зарегистрирован: 22.04.2012

Доброго времени суток!

 Есть у кого-нибудь рабочий пример Modbus Slave TCP/IP для arduino+ethernet_shield?

 

ypo
Offline
Зарегистрирован: 15.02.2013

kip100 пишет:

Доброго времени суток!

 Есть у кого-нибудь рабочий пример Modbus Slave TCP/IP для arduino+ethernet_shield?

 

Есть ли новости по теме????

Очень актуальный вопрос...

kip100
Offline
Зарегистрирован: 22.04.2012

Да, все нашел и работает с WinCC flexible

ypo
Offline
Зарегистрирован: 15.02.2013

Найдена рабочая библиотека. коммуникация с LabView на ПК налажена. Сейчас мучаю PDA Module 

andy-k
Offline
Зарегистрирован: 14.05.2012

Друзья, а не поможите примерчиком, или хотя бы именем библиотеки?

kip100
Offline
Зарегистрирован: 22.04.2012

andy-k, куда примерчики-то кидать?

andy-k
Offline
Зарегистрирован: 14.05.2012

на cyberfrag@mail.ru заранее благодарен ;)

ypo
Offline
Зарегистрирован: 15.02.2013

а не подскажет ли кто чайнику по Modbus есть ли возможность обратиться не к физическим входам выходам, а к переменным ардуины?

из ардуины достаю по сети все аналоговые входы.

На ББ пользую LabView

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так код покажите.

ypo
Offline
Зарегистрирован: 15.02.2013

если это ко мне ....

то показывать то нечего.

В ардуине вот такой скетч

#include <SPI.h>

#include <Ethernet.h>

#include "Mudbus.h"

Mudbus Mb;
//Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register)
//signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C
//Port 502 (defined in Mudbus.h) MB_PORT

void setup()
{
  uint8_t mac[]     = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
  uint8_t ip[]      = { 192, 168, 1, 8 };
  uint8_t gateway[] = { 192, 168, 1, 1 };
  uint8_t subnet[]  = { 255, 255, 255, 0 };
  Ethernet.begin(mac, ip, gateway, subnet);
  //Avoid pins 4,10,11,12,13 when using ethernet shield

  delay(5000);
  Serial.begin(9600);
  
  pinMode(7, INPUT);
  pinMode(8, OUTPUT); 
}

void loop()
{
  Mb.Run();
  
  //Analog inputs 0-1023
  Mb.R[0] = analogRead(A0); //pin A0 to Mb.R[0]
  Mb.R[1] = analogRead(A1);
  Mb.R[2] = analogRead(A2);
  Mb.R[3] = analogRead(A3);
  Mb.R[4] = analogRead(A4);
  Mb.R[5] = analogRead(A5);

  //Analog outputs 0-255
  analogWrite(6, Mb.R[6]); //pin ~6 from Mb.R[6]

  //Digital inputs
  Mb.C[7] = digitalRead(7); //pin 7 to Mb.C[7]

  //Digital outputs
  digitalWrite(8, Mb.C[8]); //pin 8 from Mb.C[8]
}
 
со стороны LabView запущен i/o  сервер.
прописаны 6 переменных s40001-s40006 - вижу их как чепез FrontPanel так и в NI Disributed System Manager
На этом наступил полный ступор, тк нужнен  доступ как к  цифровым i/o ардуины так и к ее переменным.
Чувствую что нужно эти переменые както "расшарить" в дуине, а вот как не понимаю.
Также из-за незнания самого протакола, не совсем понятно как обращаться ....
 
 
maksim
Offline
Зарегистрирован: 12.02.2012

Вставка программного кода в тему/комментарий

Так в чем проблема? 7 и 8 выводы вы видите у себя? Или нет?

//Digital inputs
  Mb.C[7] = digitalRead(7); //pin 7 to Mb.C[7]
 
  //Digital outputs
  digitalWrite(8, Mb.C[8]); //pin 8 from Mb.C[8]

Если нет, то по какой-то причине у вас в программе не видно массива Mb.C[128]. Но зато видно массив Mb.R[125] , попробуйте через него:

#include <SPI.h>
#include <Ethernet.h>
#include "Mudbus.h"

Mudbus Mb;
//Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register)
//signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C
//Port 502 (defined in Mudbus.h) MB_PORT

void setup()
{
  uint8_t mac[]     = { 
    0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06   };
  uint8_t ip[]      = { 
    192, 168, 1, 8   };
  uint8_t gateway[] = { 
    192, 168, 1, 1   };
  uint8_t subnet[]  = { 
    255, 255, 255, 0   };
  Ethernet.begin(mac, ip, gateway, subnet);
  //Avoid pins 4,10,11,12,13 when using ethernet shield 
  delay(5000);
  Serial.begin(9600);
  pinMode(13, OUTPUT); 
}

void loop()
{
  Mb.Run();

  //Analog inputs 0-1023
  Mb.R[0] = analogRead(A0); //pin A0 to Mb.R[0]
  Mb.R[1] = analogRead(A1);
  Mb.R[2] = analogRead(A2);
  Mb.R[3] = analogRead(A3);
  Mb.R[4] = analogRead(A4);
  Mb.R[5] = analogRead(A5);

  Mb.R[6] = digitalRead(2); 
  Mb.R[7] = digitalRead(3); 
  Mb.R[8] = digitalRead(4); 
  Mb.R[9] = digitalRead(5); 
  Mb.R[10] = digitalRead(6); 
  Mb.R[11] = digitalRead(7); 
  Mb.R[12] = digitalRead(8); 
  Mb.R[13] = digitalRead(9); 
  Mb.R[14] = digitalRead(10); 
  Mb.R[15] = digitalRead(11); 
  Mb.R[16] = digitalRead(12); 
  
  int a = 100;
  Mb.R[17] = a; 
  int b = 200;
  Mb.R[18] = b; 
  int c = 300;
  Mb.R[19] = c; 
  
  digitalWrite(13, Mb.R[20]);
}

 

ypo
Offline
Зарегистрирован: 15.02.2013

Спасибо.

Переменные а,b,c достал.

Думаю что и цифровые входы выходы также через

Mb.R[6] = digitalRead(2);
Mb.R[7] = digitalRead(3);
Mb.R[8] = digitalRead(4);
Mb.R[9] = digitalRead(5);

увижу.

только вот переменная для чтения Mb.R[х] обьявлена как int16, и чтото мне подсказывает что не совсем правильно читать бинарные значения через неё.

Буду разбираться как прочитать  Mb.C[x]

Как я понял R - Registr, C - Coils - читаю дальше про ModBus....

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

В ардуине нет битового формата данных. digitalRead() возвращает BYTE, так что было бы корректно использовать int8

maksim
Offline
Зарегистрирован: 12.02.2012

Вы о чем? Причем тут битовые форматы?
Чем в данном случае корректнее использовать char вместо byte. 

kristow
kristow аватар
Offline
Зарегистрирован: 08.08.2013

У меня есть arduino UNO и ethernet шилд.

Хочу читать с второго контакта на ардуино два подключенных датчика температуры DS1B20. И управлять выходом 3.

Получать данные с двух датчиков DS18B20 я научился, и по адресам датчиков распределять полученные ответы с порта.

Бибилиотеку нашел, код вроде простой в примере... Хочу подключиться к ардуине с OPC сервера modbus.

Помимо ip и порта я указал:

адрес устройства 1 dec.

Функция чтения 03 dec.

Функция записи 16 dec.

 

kristow
kristow аватар
Offline
Зарегистрирован: 08.08.2013

Вроде все просто. Рано панику поднял... 

Но вопрос все же есть... Я читаю значения без проблем на opc сервере типданных WORD, но у меня значения с датчика идут в формате float. Я их и хочу получать... Чтобы значения с сотыми были... И вот если указываю в OPC сервере читать float могу только single float и double float. Значения на выходе совсем не совпадают... 

Подскажите как правильно вывести полученные значения в opc сервер.

ilya_turlo
Offline
Зарегистрирован: 14.10.2013

1

ilya_turlo
Offline
Зарегистрирован: 14.10.2013

[quote=ypo]

отправьте пожалуйста пример и библиотеку на m0ps1k93@gmail.com

Arsbond
Offline
Зарегистрирован: 25.02.2014

если не составит труда, отправьте мне тоже

arsbond@gmail.com

спасибо заранее

нашел пример в интернете но пишет следующее при компиляции

Mb.cpp.o: In function `__static_initialization_and_destruction_0':
Z:\arduino-1.0.5-r2/Mb.pde:6: undefined reference to `Mudbus::Mudbus()'
Mb.cpp.o: In function `loop':
Z:\arduino-1.0.5-r2/Mb.pde:29: undefined reference to `Mudbus::Run()'
forewardground
Offline
Зарегистрирован: 25.02.2014

Arsbond пишет:

если не составит труда, отправьте мне тоже

arsbond@gmail.com

спасибо заранее

нашел пример в интернете но пишет следующее при компиляции

Mb.cpp.o: In function `__static_initialization_and_destruction_0':
Z:\arduino-1.0.5-r2/Mb.pde:6: undefined reference to `Mudbus::Mudbus()'
Mb.cpp.o: In function `loop':
Z:\arduino-1.0.5-r2/Mb.pde:29: undefined reference to `Mudbus::Run()'
 
дайте пожалуйста ссылку, вместе разберемся с программой 
но по-моему  Mudbus не для TCP  а для 485, 422, 232 ?
----------------------
forewardground
Arsbond
Offline
Зарегистрирован: 25.02.2014

я разобрался

1. скачиваем отсюда  https://code.google.com/p/mudbus/downloads/list архив Modbus 1_0

2. копируем папку Modbus из архива в \arduino-1.0.5-r2\libraries

3. запускаем arduino-1.0.5-r2.exe идем Файл >> Примеры >> Modbus >> Mb

Вуаля открывается пример с модбасом компилим заливаем юзаем.

 

Но обнаружилась нехорошая особенность шилда ETHERNET.

При длительном опросе 1 раз в секунду длиной 10 минут нагревается микроконтроллер на шилде и перестает нормально работать связь по ethernet. я покупал его из китая может в этом дело. выход нашел следующий приклеил на термоклей небольшой радиатор.

KamovEugeniy
Offline
Зарегистрирован: 24.02.2014

Arsbond пишет:

Но обнаружилась нехорошая особенность шилда ETHERNET.

При длительном опросе 1 раз в секунду длиной 10 минут нагревается микроконтроллер на шилде и перестает нормально работать связь по ethernet. я покупал его из китая может в этом дело. выход нашел следующий приклеил на термоклей небольшой радиатор.

какая модель шилда?

быть можт они хотели продать вам до кучи кулер с неоновой подстветкой?

Arsbond
Offline
Зарегистрирован: 25.02.2014

Шилд вот такой Ethernet Shield W5100 For Arduino 2009 UNO Mega 1280 2560 high quality GOOD

Я думаю такие штуки не стоит использовать скажем на атомных станциях, а для бытовых нужд в вполне нормалек. 

edfs
Offline
Зарегистрирован: 09.05.2014

Подскажите, пожалуйста, каким образом вы идентифицируете OneWire датчики со стороны ModBus мастера?

Адреса DS18B20 у вас в коде мк прописаны?

Kaspiysk
Offline
Зарегистрирован: 17.06.2015

Скиньте пожалуйста на kaspiysk@bk.ru библиотеки и рабочий пример с выводом внутренних переменных.

Все ссылки устарели. Спасибо. 

cmp
Offline
Зарегистрирован: 26.09.2015

Если не сложно, скиньте пожалуйста на cmp@ua.fm библиотеки и рабочий пример с выводом внутренних переменных. Ссылки действительно устарели.

ypo
Offline
Зарегистрирован: 15.02.2013

Друзья жду вашего совета. Работает такая связка: Уно+Ethernet+modbus opc+opc клиент(пробовал разные). Все это крутиться в локалке предприятия. Шлюзы и днс прописаны. Проблема в том что все нормально только если дуина и комп с сервером и клиентом подключены в один свитч. Ставлю сервер с клиентом на другую машину в той же сети только далеко, получаю тугое чтение сервером дуины. Пингуется все нормально. Временами даже читает, но уж больно туго...иногда обновляется по 40 секунд. Взялся за модббас тк со связкой ArduinoOpc при разнесении сервера и железа за пределы одного свитча такая же проблема.

Чувствую что где-то что-то с таймаутами или сетевыми настройками. Что именно понять не могу.....help my please...

Ps. Кстати вместо дуины ставил модбас эмулятор на пк..так вот с ним все нормально опс сервер читает нормально без задержек. А клиент естественно видит сервер нормально. Те делаю вывод что дело в железе. Пробовал и Уно и мегу. Результат тот же.шилд менять нечем. Да и нужно ли? В одном свитче все работает сказочно.....

ypo
Offline
Зарегистрирован: 15.02.2013

ypo пишет:

 Работает такая связка: Уно+Ethernet+modbus opc+opc клиент(пробовал разные). Все это крутиться в локалке предприятия. 

Ух....заработало с другим сервером...

Fastwel Modbus OPC... Может подскажете сервера не жадные еще...)))

 

 

 

 

 

Kaspiysk
Offline
Зарегистрирован: 17.06.2015

Скиньте пожалуйста на kaspiysk@bk.ru библиотеки и рабочий пример с выводом внутренних переменных.

Все ссылки устарели. Спасибо.

ypo
Offline
Зарегистрирован: 15.02.2013

ypo пишет:

Ух....заработало с другим сервером...

Может кому пригодитья....готового решения не нашел.

Накодил две функции для сборки 2х 16битных слов из флоат переменной для отправки мастеру.

 

//функция сборки младшего слова для переменной флоат модбаса
int WORD_LOW_FUNC  (float dt ) {
  int WORD_LOW;
  byte* ptrdt;  // указатель на тип byte
  ptrdt =  (byte*)(& dt);  // получаем адрес переменной dt
  byte byte1 = * ptrdt + 0;    // считываем байты
  byte byte2 = * (ptrdt + 1);
  WORD_LOW = (byte2 << 8) | (byte1);
  //int WORD_LOW = word(byte2, byte1);
  return  WORD_LOW;
};
//функция сборки старшего слова для переменной флоат модбаса
int WORD_HIG_FUNC  (float dt ) {
  int WORD_HIG;
  byte* ptrdt;  // указатель на тип byte
  ptrdt =  (byte*)(& dt);  // получаем адрес переменной dt
  byte byte3 = * (ptrdt + 2);
  byte byte4 = * (ptrdt + 3);
  // int WORD_HIG = word(byte4, byte3);
  WORD_HIG = (byte4 << 8) | (byte3);
  //(hi<<8) | low;

  return WORD_HIG;
};

Для примера вызов функций...и расстановка по регистрам. Теперь пересылаются 32 битные FloatЫ))

Mb.R[0] = WORD_LOW_FUNC (sensors.getTempC(Thermometer1));
  Mb.R[1] = WORD_HIG_FUNC (sensors.getTempC(Thermometer1));
  Mb.R[2] = WORD_LOW_FUNC (sensors.getTempC(Thermometer2));
  Mb.R[3] = WORD_HIG_FUNC (sensors.getTempC(Thermometer2));

Мастером пока стоят OPC серевер, и WinCCFlex с настроеным каналом коммуникации по модбас.

SIR
SIR аватар
Offline
Зарегистрирован: 07.11.2016

В примере выше был вопрос, в котором не шли на сервер данные с дискретных входов:

  //Analog outputs 0-255
  analogWrite(6, Mb.R[6]); //pin ~6 from Mb.R[6]

  //Digital inputs
  Mb.C[7] = digitalRead(7); //pin 7 to Mb.C[7]

  //Digital outputs
  digitalWrite(8, Mb.C[8]); //pin 8 from Mb.C[8]

Действительно не идут данные. Не получается получить-отправить на сервер.

Кто-нибудь решил вопрос с отправкой дискретных данных на сервер? Может библиотека не рабочая?

Аналоговые идут отлично.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Надо помнить, что в модбасе дискретные данные имеют размерность 1 бит, а в ардуине 1 байт! То есть нужно применять конструкцию

//Digital inputs
Mb.C[7] = digitalRead(7); //pin 7 to Mb.C[7] - неправильно, нужно
bitWrite(Mb.C, 7, digitalRead(7));

Аналогично обратно через bitRead()

SIR
SIR аватар
Offline
Зарегистрирован: 07.11.2016

Благодарю за совет, но заработало именно по моему варианту. Ваш оказался не рабочим. Добавил в код дублирование данных, посылаемых сервером на дискретные каналы, чтобы видеть их в сканере CAS Modbus TCP. Таким образом проверкой различного кода убедился, когда данные приходят. Изначально OPC сервер не посылал данные по моей причине записи не в ту колонку.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

У меня работало именно через битовые операции, был только нюанс, что в модбасе дискретные входа и выхода имеют сквозную нумерацию, поэтому нужно следить, когда вычитать 16 из номера канала.

SIR
SIR аватар
Offline
Зарегистрирован: 07.11.2016

Всем доброго времени суток!

Прошу прощения, что задаю вопрос в разных темах. За неделю поисков не нашел на просторах интернета на него даже намека на ответ.

Такой вопрос. Кто-нибудь использовал протокол передачи ModbusTCP в связке с шилдом SIM900 + Mega2560?

Подскажите рабочие библиотеки, которые можно использовать для такой связки. SIM900 соединяю с сервером без библиотек, через команды AT, даже могу опять же в ручном режиме закинуть заранее сформированный пакет ModbusTCP и сервер его обработает, но получить данные с сервера никак не получается. Например запрос по состоянию дискретных переменных на сервере присылает непонятную кучу непонятной длины байт, всегда разную, хотя тот же запрос через Ethernet выдает правильный, понятный ответ. Возможно, это какая-то информация из SIM900, или шилд трансформирует присылаемые данные каким-то образом, понять логику пока не представляется возможным. Возможно в буфере находятся какие-либо данные (хотя перед каждым запросом я "чищу" буфер).

Возможно, использование библиотеки для шилда SIM900 поможет в фильтрации ненужной информации из буфера SIM900. Или есть библиотека ModbusTCP для шилда SIM900, как в примере вверху темы, для Ethernet.

Возможно, надо учесть какие-либо нюансы, танцы с бубном, для корректного приема ответа с сервера через SIM900, как-то подготовить шилд? Может кто работал с шилдом SIM900 в формате ModbusTCP?

Кто в курсе?

p/s/

Все, вопрос решил. Все написал без библиотек, нюансов море, понимаю, почему молчали. Примеров и подсказок на просторах интернета не нашел. Вопрос закрыт.