ModBus TCP Master, неразбериха со значениями переменных...

Данные, получаемые от слейва, хаотично меняются местами

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#1

Сообщение Serg_Grn » 13.09.2020{, 08:44}

Добрый день.
Есть плата (NodeMCU, Wemos, ESP32 - пробовал все варианты, итог везде один), которая является ModBus TCP Master, по wifi через роутер опрашивает ПЛК-slave. Сам ПЛК включён в роутер кабелем Ethernet. Опрашиваются данные Input registers, которые затем выводятся на дисплей.
Суть проблемы: данные в мастер прилетают без ошибок, но значения переменных хаотично меняются местами, т.е. отправленное значение в первом адресе вдруг начинает отображаться во втором, второй - в третьем и т.д., а последний - оказывается в первом... Затем через несколько секунд всё становится на свои места, потом проходит еще несколько секунд и опять чехарда со значениями переменных...
Я пробовал вместо ПЛК использовать OPC - итог один - отправляешь с компа значения переменных в одних адресах, они прилетают хаотично, то в правильных, то в неправильных... Соответственно, проблема точно не в ПЛК, проблема где-то в плате или коде, но где не представляю...
Прошу, у кого есть возможность и желание, взять любую из используемых мной плат (NodeMCU, Wemos, ESP32) и попробовать ею как мастером опросить слэйв устройство - либо такую же плату, либо OPC, или любой ПЛК.
Проект прилагаю, там кроме ModBus TCP Master ничего другого нет.
Спасибо!
Вложения
телтест.flp
(246.28 КБ) 48 скачиваний

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#2

Сообщение Sancho » 13.09.2020{, 09:28}

Serg_Grn писал(а):
13.09.2020{, 08:44}
Прошу, у кого есть возможность и желание
Завтра сделаю!
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#3

Сообщение Serg_Grn » 14.09.2020{, 20:22}

Я снял видео, где показано происходящее..
Контроллер ModBus TCP master - NodeMcu. Рядом с дисплеем табличка, где указаны значения адресов регистров в том виде, в каком их отправляет слейв устройство. На видео видно, как спустя несколько секунд или минут (когда как) происходит смещение значений и дальше контроллер так работает до тех пор, пока его не перезагрузишь. После перезагрузки некоторое время всё читается правильно, потом опять смещение.
СпойлерПоказать
Проект:
опять телтест.flp
(172.37 КБ) 47 скачиваний
Отправлено спустя 11 часов 17 минут 33 секунды:
Sancho, подскажите, пробовали работу ModBus? А то я уже голову себе сломал :smile37: надо мне его наладить, а как пока не представляю...

Аватара пользователя
Dev1
Майор
Сообщения: 1026
Зарегистрирован: 12.07.2016{, 18:04}
Репутация: 59
Откуда: Гондурас

ModBus TCP Master, неразбериха со значениями переменных...

#4

Сообщение Dev1 » 15.09.2020{, 08:53}

В программировании главное последовательность. Сначала получаем данные по модбас. Склеиваем в строку, выводим в уарт!!! Все отлично? Едем дальше. И мы уже знаем что с модбасом все ок. При дальнейших надстройках-пристройках из блоков к модбасу все время сравниваем результат с уартом(не отключать до окончания наладки). В готовом проекте, который уже оброс блоками, правильной работе могут мешать встроеныые библиотеки различных блоков. Поэтому, что бы выявить виновника ошибок проект делается аналогичный с 0.
Win10-64 FLProg v7.5.2 Portable :fie:

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#5

Сообщение Sancho » 15.09.2020{, 10:55}

Serg_Grn писал(а):
15.09.2020{, 07:40}
Sancho, подскажите, пробовали работу ModBus? А то я уже голову себе сломал надо мне его наладить, а как пока не представляю...
Проблема есть.
Пробую изменить код, т.к. запросы к слэйву идут на каждый регистр свой.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#6

Сообщение Serg_Grn » 15.09.2020{, 12:26}

Dev1, спасибо, про uart - дельный совет.
Попробовал отправлять значения регистров в uart - они тоже со временем смещаются, как и при выводе на дисплей. Следовательно, проблема именно в Modbus.

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#7

Сообщение Sancho » 16.09.2020{, 09:07}

Какая-то засада ещё и с модулем, который остался в наличии. Дешёвый, но вроде как работает, инвертирую выход в каждом цикле - не останавливается, практически, но от роутера отваливается через 5-10 сек, включил переподключение. Ёмкости запаяны.
Залил в него пример с NTP - работает, не отваливается.
Буду начинать разбираться с WiFi.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#8

Сообщение Serg_Grn » 16.09.2020{, 17:15}

Sancho, не совсем понял, причину этого смещения пока не удалось найти?
Я вчера наблюдал еще несколько часов, странная картина - после того, как регистры сместились на один, модбас так и продолжает работать сколь угодно долго, т.е. больше смещений у меня не происходило. Отправляешь в нулевом регистре число - оно приходит в первом, в первом отправляешь - приходит во втором, последний - в нулевом. Странно...

Аватара пользователя
Dev1
Майор
Сообщения: 1026
Зарегистрирован: 12.07.2016{, 18:04}
Репутация: 59
Откуда: Гондурас

ModBus TCP Master, неразбериха со значениями переменных...

#9

Сообщение Dev1 » 16.09.2020{, 17:30}

Попробуйте создать мелкий проект модбаса на 6.3.1, там вроде все норм и на последней версии. В иде получите код(можно файлами .ino) и сравните. Удобная прога для сравнения кода CompareIt!.
Win10-64 FLProg v7.5.2 Portable :fie:

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#10

Сообщение Sancho » 16.09.2020{, 17:48}

Все тесты на 6.3.1.
Даже самый мелкий проект отваливается от ТД в режиме клиента.
Код переправлял раз 100500.
Добавил реконект, море выводов в сериал и т.д.
Для полноты теста нужно норм железо, коего нет.

Отправлено спустя 8 минут 21 секунду:
Крайний код испытуемого, сомпорт на 115200, сервер 11502, и т.д. в тексте
СпойлерПоказать

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

#include <ESP8266WiFi.h>

int _modbusMasterDataTable_3_reg_1_server1[5];

byte _modbusMasterBufferSize = 0;
byte _modbusMasterState = 1;
long _modbusMasterSendTime;
byte _modbusMasterBuffer[64];

struct _modbusMasterTelegramm {
  byte slaveId;        
  byte function;        
  int startAddres;   
  int numbeRegs;   
  int valueIndex;
IPAddress ip;
int port;
int serverId;
int answerId;
};
_modbusMasterTelegramm _modbusTelegramm;
long _startTimeMasterRegs[1];
long _updateTimeMasterRegsArray[] = {1000};
const unsigned char _modbusMaster_fctsupported[] = {4};
IPAddress SlaveInMasterTCPServer_1(192, 168, 3, 33);
WiFiClient _ModbsTCPMasterClient;

char ESPControllerWifiClient_SSID[40] = "Avtomatik";
char ESPControllerWifiClient_password[40] = "1029384756";

String _gtv1;
int _gtv2;
int _gtv3;
int _gtv4;
int _gtv5;
int _gtv6;
String _stou1;
bool abc;
bool connnect;
long time_recon;

void setup()
{

  WiFi.mode(WIFI_STA);
  WiFi.begin(ESPControllerWifiClient_SSID, ESPControllerWifiClient_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  Serial.begin(115200, SERIAL_8N1);
  pinMode(LED_BUILTIN, OUTPUT);
  time_recon = millis();
}
void loop()
{





/* if (!connnect){
  if ((millis() - time_recon)> 10000){time_recon = millis();ESPControllerWifiClient_IsNeedReconect = 1;}
  else{time_recon = millis();}
} */


  digitalWrite(LED_BUILTIN, abc);   // turn the LED on (HIGH is the voltage level)



//Плата:1
_gtv2 = (_modbusMasterDataTable_3_reg_1_server1[0]);
_gtv3 = (_modbusMasterDataTable_3_reg_1_server1[1]);
_gtv4 = (_modbusMasterDataTable_3_reg_1_server1[2]);
_gtv5 = (_modbusMasterDataTable_3_reg_1_server1[3]);
_gtv6 = (_modbusMasterDataTable_3_reg_1_server1[4]);

//Плата:2
_gtv1 = (((String(_gtv2, DEC))) + (String("  ")) + ((String(_gtv3, DEC))) + (String("  ")) + ((String(_gtv4, DEC))) + (String("  ")) + ((String(_gtv5, DEC))) + (String("  ")) + ((String(_gtv6, DEC))) + (String(".")));
if (1){if(!(( _gtv1)==(_stou1))){Serial.println(_gtv1);}} _stou1 = _gtv1; //




switch ( _modbusMasterState ) {
    case 1:
      _nextModbusMasterQuery();// передача
      break;
    case 2:
      pollModbusMaster(); // приём
      break;
  }


}

bool _isTimer(unsigned long startTime, unsigned long period )
{
  unsigned long currentTime = millis();
  return (period <=(currentTime - startTime));  
}
  
void _nextModbusMasterQuery()
{
if (!(_isTimer(_modbusMasterSendTime, 2000)))   return; // новое
//abc = !abc;
_modbusTelegramm.ip = SlaveInMasterTCPServer_1;
_modbusTelegramm.port = 11502;
_modbusTelegramm.slaveId = 1;
_modbusTelegramm.function = 4;
_modbusTelegramm.startAddres = 0; // с какого адреса
_modbusTelegramm.numbeRegs = 5;   // сколько штук читать
_modbusTelegramm.serverId = 1;
  //_modbusTelegramm.answerId = _modbusTelegramm.answerId + 1;
_modbusMasterSendQuery();
}


void _modbusMasterSendQuery()
{
  if ( ! _ModbsTCPMasterClient.connected()) {abc = !abc;_esp8266WifiModuleClientReconnect();/*_ModbsTCPMasterClient.connect(_modbusTelegramm.ip,_modbusTelegramm.port);Serial.print("");Serial.print("Reconect"); */}
else{
  _modbusMasterBufferSize = 6;
  _modbusMasterBuffer[0]=highByte(_modbusTelegramm.answerId);
  _modbusMasterBuffer[1]=lowByte(_modbusTelegramm.answerId);
  _modbusMasterBuffer[2]=0;
  _modbusMasterBuffer[3]=0;
  _modbusMasterBuffer[4]=highByte(_modbusMasterBufferSize);
  _modbusMasterBuffer[5]=lowByte(_modbusMasterBufferSize);
  _modbusMasterBuffer[6]  = _modbusTelegramm.slaveId;
  _modbusMasterBuffer[7] = _modbusTelegramm.function;
  _modbusMasterBuffer[8] = highByte(_modbusTelegramm.startAddres);
  _modbusMasterBuffer[9] = lowByte( _modbusTelegramm.startAddres );
  _modbusMasterBuffer[10] = highByte(_modbusTelegramm.numbeRegs );
  _modbusMasterBuffer[11] = lowByte( _modbusTelegramm.numbeRegs );
  

  _ModbsTCPMasterClient.write(_modbusMasterBuffer, 12);
  //_modbusTelegramm.answerId = _modbusTelegramm.answerId + 1;  // новое
 _modbusMasterSendTime = millis();
 _modbusMasterState = 2;}
}


void pollModbusMaster()
 {  
    if (_isTimer(_modbusMasterSendTime, 900)) {  _modbusMasterState = 1;  return;}
  _modbusMasterGetRxBuffer();
  
  if(_modbusMasterBufferSize == 0) {return;}
  Serial.println("Send= " + String(_modbusMasterBufferSize, DEC));
  byte exeption = validateAnswer();
  _modbusMasterSendTime = millis();
  if (exeption != 0) {
    _modbusMasterState = 1;_ModbsTCPMasterClient.stop(); return; }
    switch ( _modbusMasterBuffer[1] ) {
      case 4:
      get_FC3(3);
  
      break;
    }
  _modbusMasterState = 1;
  _modbusTelegramm.answerId = _modbusTelegramm.answerId + 1;
  
  return;
}
byte _modbusMasterGetRxBuffer()
{
  int qwe;
 _modbusMasterBufferSize = 0;
byte currentByte = 0;
byte currentByteIndex = 0;
while (_ModbsTCPMasterClient.available() ) {currentByte = _ModbsTCPMasterClient.read();
if (currentByteIndex  ==0)qwe = currentByte;
if (currentByteIndex  ==1)qwe = (qwe<<8) | currentByte;
if (currentByteIndex  ==3)Serial.println("ID= "+String(qwe, HEX));
if (currentByteIndex  > 5) {
  _modbusMasterBuffer[ _modbusMasterBufferSize ] = currentByte;  _modbusMasterBufferSize ++;
}
 currentByteIndex++;
}

return _modbusMasterBufferSize;

}
byte validateAnswer()
{
  if ((_modbusMasterBuffer[1] & 0x80) != 0) {return _modbusMasterBuffer[2] ;}
 boolean isSupported = false;
for (byte i = 0; i < sizeof( _modbusMaster_fctsupported ); i++) {
if (_modbusMaster_fctsupported[i] == _modbusMasterBuffer[1]) {
 isSupported = 1;
  break;
 }
 }
 if (!isSupported) {return 1;}
   return 0;
}
void get_FC3(byte table)
{
  
  
  int currentIndex = _modbusTelegramm.startAddres;
  byte currentByte = 3;
  int value;
  byte mmm = _modbusMasterBuffer[2] / 2;  // получено байт, делим на 2 - получено регистров.
  for (int i = 0; i < mmm; i++) {
  value = word( _modbusMasterBuffer[ currentByte],   _modbusMasterBuffer[ currentByte + 1 ]);
  if(table == 3) {_modbusMasterDataTable_3_reg_1_server1[currentIndex + i] =value;}
    currentByte += 2;
  } 
}

 void _esp8266WifiModuleClientReconnect()
{


  WiFi.begin(ESPControllerWifiClient_SSID, ESPControllerWifiClient_password);
  while (WiFi.status() != WL_CONNECTED) {
    //Serial.print(".");
    delay(500);
  }
  //Serial.println();
  _ModbsTCPMasterClient.connect(_modbusTelegramm.ip,_modbusTelegramm.port);
   _modbusMasterSendTime = millis();
}


Отправлено спустя 4 минуты 20 секунд:
скрин
СпойлерПоказать
2020-09-16_17-59-18.png
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#11

Сообщение Serg_Grn » 16.09.2020{, 18:34}

Dev1, я изначально именно на 6.3.1 и обнаружил проблему.

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#12

Сообщение Serg_Grn » 17.09.2020{, 09:59}

Sancho, докладываю по железу: я купил ещё одну плату ESP32 Devkit V1, залил только модбас и отправка uart, спустя минуты три произошло смещение - последний в нулевом, нулевой в первом и т.д., дальше, спустя минуту примерно, всё само стало на свои места и дальше обмен шёл правильно. Т.е. самопроизвольно адреса смещаются аккурат на один вверх, потом так же самопроизвольно возвращаются назад и так оно работает - туда-сюда...

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#13

Сообщение Sancho » 18.09.2020{, 16:57}

Тест переделанного опроса, пакетного, на новой плате с модулем ESP-12E показал свою полную работоспособность.
Указанные в ссылке поста 7 платы годятся разве-что как отдельный контролер с много памяти, а лучше мимо них.
Смещение данных возможно при по-регисторном считывании( даже адресов подряд) и отсутствии проверки номера полученного пакета, что пока присутствует в проге, функция validateAnswer(), и отсутствия какой либо обработки/анализа заголовка, первых 6-ти байт.
При корректировке функций всё будет Ок. Проверенно считывание пяти регистров подряд пакетом за час 1 раз/сек - потерь нет. Слэйв - инсатовский орс на 32т.

Отправлено спустя 13 минут 4 секунды:
Скрин орс
СпойлерПоказать
2020-09-18_17-09-07.png
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Serg_Grn
Лейтенант
Сообщения: 333
Зарегистрирован: 11.02.2018{, 13:07}
Репутация: 36
Имя: Сергей

ModBus TCP Master, неразбериха со значениями переменных...

#14

Сообщение Serg_Grn » 18.09.2020{, 19:54}

Sancho писал(а):
18.09.2020{, 17:10}
При корректировке функций всё будет Ок
Осталось откорректировать функции, счастье близко :)

Pelletizer
Рядовой
Сообщения: 91
Зарегистрирован: 12.09.2019{, 07:10}
Репутация: 5
Имя: Дмитрий

ModBus TCP Master, неразбериха со значениями переменных...

#15

Сообщение Pelletizer » 18.09.2020{, 23:47}

Sancho писал(а):
18.09.2020{, 17:10}
Тест переделанного опроса, пакетного, на новой плате с модулем ESP-12E показал свою полную работоспособность.
Указанные в ссылке поста 7 платы годятся разве-что как отдельный контролер с много памяти, а лучше мимо них.
Смещение данных возможно при по-регисторном считывании( даже адресов подряд) и отсутствии проверки номера полученного пакета, что пока присутствует в проге, функция validateAnswer(), и отсутствия какой либо обработки/анализа заголовка, первых 6-ти байт.
При корректировке функций всё будет Ок. Проверенно считывание пяти регистров подряд пакетом за час 1 раз/сек - потерь нет. Слэйв - инсатовский орс на 32т.

Отправлено спустя 13 минут 4 секунды:
Скрин орс
СпойлерПоказать
2020-09-18_17-09-07.png
Я так понимаю такое же может происходит при использовании шлюза в каскаде, сталкивался с таким...

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#16

Сообщение Sancho » 19.09.2020{, 08:33}

Pelletizer писал(а):
18.09.2020{, 23:47}
в каскаде
В каскаде, при использовании облака, номер пакета в заголовке вообще не инкриминируется. Поэтому в то, что Вы получили ответ на тот пакет запроса, на который ждёте, уверенности 100% нет совсем.
Для максимальной уверенности при опросе:
номер принятого пакета соответствует номеру отправленного;
Количество байт в заголовке, 6-й байт( редко 5 и 6), равен количеству байт после него( сейчас _modbusMasterBufferSize, не сложно, для макс уверенности);
проверка на отсутствии в ответе данных об ошибке или её интерпретации.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Pelletizer
Рядовой
Сообщения: 91
Зарегистрирован: 12.09.2019{, 07:10}
Репутация: 5
Имя: Дмитрий

ModBus TCP Master, неразбериха со значениями переменных...

#17

Сообщение Pelletizer » 19.09.2020{, 11:33}

Sancho,
А как сделать так называемую проверку не подскажите?

Аватара пользователя
Rovki
Полковник
Сообщения: 4872
Зарегистрирован: 22.04.2016{, 17:25}
Репутация: 269
Откуда: Чехов
Имя: Анатолий
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#18

Сообщение Rovki » 19.09.2020{, 11:38}

Sancho писал(а):
19.09.2020{, 08:33}
Pelletizer писал(а):
18.09.2020{, 23:47}
в каскаде
В каскаде, при использовании облака, номер пакета в заголовке вообще не инкриминируется. Поэтому в то, что Вы получили ответ на тот пакет запроса, на который ждёте, уверенности 100% нет совсем.
Для максимальной уверенности при опросе:
номер принятого пакета соответствует номеру отправленного;
Количество байт в заголовке, 6-й байт( редко 5 и 6), равен количеству байт после него( сейчас _modbusMasterBufferSize, не сложно, для макс уверенности);
проверка на отсутствии в ответе данных об ошибке или её интерпретации.
На сколько я понял вопрос про функции модбас и работе в локальной сети ,а не то как сделана работа через облако ..Тут только программист каскады может пояснить.
Электронщик до мозга костей и не только

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

ModBus TCP Master, неразбериха со значениями переменных...

#19

Сообщение Sancho » 19.09.2020{, 11:51}

Rovki писал(а):
19.09.2020{, 11:38}
На сколько я понял вопрос про функции модбас и работе в локальной сети ,а не то как сделана работа через облако .
Как я думаю, облако у Вас - это просто надстройка над той реализацией ТСР, которая была изначально. Соответственно, номер пакета не увеличивается и не проверяется.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Pelletizer
Рядовой
Сообщения: 91
Зарегистрирован: 12.09.2019{, 07:10}
Репутация: 5
Имя: Дмитрий

ModBus TCP Master, неразбериха со значениями переменных...

#20

Сообщение Pelletizer » 19.09.2020{, 11:58}

Rovki, да, так точно, я имел ввиду шлюз для объединения передачи переменных

Ответить

Вернуться в «Помогите, а то я "нимагу"»