Страница 1 из 1

ModBus RTU групповое чтение

Добавлено: 24 дек 2020, 16:57
Sancho
Вариант для группового чтения, т.е. несколько регистров, идущих подряд, за один запрос.
Адреса слэйвов и номер первого регистра задаются на входах блоков.
В основном задаётся общее число используемых блоков и скорость порта.
На выходе основного блока битовая маска, в которой 1 соответствуют о том, что последнее чтение было удачным.
Для теста удобно использовать программу Mod-RsSim , mod_RSsim.exe, тут есть тоже, которая имитирует несколько слэйвов с возможностью вкл/откл, внизу панели квадратики, если зелёный доступен, в жёлтой рамке - опрашивается, красный - недоступен. Да много чего.
Пока только чтение.
Код основан на flprog, почти.
Можно, при желании, изменить на флоат, а byte получить вообще не проблема, т.к. в этой версии данные хранятся именно в них.
Количество слэйвов можно увеличить, изменив блок и сохранив его под новым именем, также количество регистров можно увеличить/уменьшит.
Заготовка - одним словом, для экспериментов . И для понимания алгоритма.
Идея описана в этой теме.

ModBus RTU групповое чтение

Добавлено: 24 дек 2020, 17:45
Ingwar
Вот бы "групповуху" добавить в саму программу... (машинка есть) :yes:

ModBus RTU групповое чтение

Добавлено: 10 май 2021, 18:01
Serg_Grn
Блоки оказались очень в нужное время в нужном месте :)
Sancho, спасибо.

Для полного счастья не хватает блоков записи. И для input registers тоже.
А так получается что либо читаешь группой, но не можешь писать, либо пишешь встроенным модбасом, но вынужден читать порегистрово, а это иногда оказывается плохо - теряются короткие во времени сигналы при слишком долгом обмене...

ModBus RTU групповое чтение

Добавлено: 24 май 2021, 20:17
Velis
прошу прощения, можно объяснить все для пионеров, как работать с данными блоками. нужно в одном запросе отправить температуру и влажность. заранее спасибо

ModBus RTU групповое чтение

Добавлено: 25 май 2021, 08:49
Sancho
Velis писал(а): 24 май 2021, 20:17 прошу прощения, можно объяснить все для пионеров, как работать с данными блоками. нужно в одном запросе отправить температуру и влажность. заранее спасибо
Напрямую в модбасе отправить можно только от мастера к слэйву.
Из слэйва можно считать.
Поэтому не совсем понятна затея... :)

ModBus RTU групповое чтение

Добавлено: 25 май 2021, 19:19
Velis
благодарю

ModBus RTU групповое чтение

Добавлено: 07 июн 2021, 18:06
Serg_Grn
Добавил вариант блоков (основной и один слейв) для чтения 9 регистров.
Основной_МВ_01_9_(Code_-_Basic).ubi
Устройство_0_9int_(Code_-_Basic).ubi

ModBus RTU групповое чтение

Добавлено: 07 июн 2021, 18:26
support
Sancho писал(а): 24 дек 2020, 16:57 Вариант для группового чтения, т.е. несколько регистров, идущих подряд, за один запрос.
Реализованно в версии 7.3.6. Подряд идущие регистры теперь читаются одним запросом.

ModBus RTU групповое чтение

Добавлено: 07 июн 2021, 18:31
Serg_Grn
[ref=#00aa00]support[/ref], ничего себе! А я и не знал, спасибо огромное!

ModBus RTU групповое чтение

Добавлено: 08 июн 2021, 16:24
Serg_Grn
support писал(а): 07 июн 2021, 18:26 Реализованно в версии 7.3.6.
[ref=#00aa00]support[/ref], подскажите пожалуйста, проблема обрисованная по ссылке ниже решена или нет?
viewtopic.php?t=6709&start=20#p94137

ModBus RTU групповое чтение

Добавлено: 26 июл 2021, 21:50
Wadim77
support писал(а): 07 июн 2021, 18:26
Sancho писал(а): 24 дек 2020, 16:57 Вариант для группового чтения, т.е. несколько регистров, идущих подряд, за один запрос.
Реализованно в версии 7.3.6. Подряд идущие регистры теперь читаются одним запросом.
Уточните, пож, что вы имели ввиду?

ModBus RTU групповое чтение

Добавлено: 28 июл 2021, 06:50
support
Wadim77 писал(а): 26 июл 2021, 21:50
support писал(а): 07 июн 2021, 18:26
Реализованно в версии 7.3.6. Подряд идущие регистры теперь читаются одним запросом.
Уточните, пож, что вы имели ввиду?
вот смотри, регистры идут с номерами 5,6,7,8,9 11,12,13,14
одним запросом прочитаются с 5 по 9, и вторым с 11 по 14. если они будут идти подряд 5,6,7,8,9 ,10,11,12,13,14 то они прочитаются одним запросом

ModBus RTU групповое чтение

Добавлено: 10 окт 2021, 12:01
Serg_Grn
[ref=#00aa00]support[/ref], обратите пожалуйста внимание на ещё одну проблему в Modbus RTU master, она давно есть, я столкнулся с ней опять сейчас. Суть проблемы: некоторые слейв устройства (ПЛК) не отвечают на часть запросов мастера, т.е. то отвечают, то нет... Я смотрел осциллографом и видел что пакеты запросов идут, а ответов нет, точнее чаще их нет, чем они есть.
В итоге обнаружено следующее: в Modbus RTU master функция _modbusMasterSendTxBuffer() имеет строку delay(10), эта строка расположена после строки Serial2.write.
Я перемещаю delay(10) до Serial2.write, в результате у меня формируется задержка перед отправкой следующего запроса слейву, таким образом проблема решается и слейв начинает нормально отвечать в каждом запросе.
Спасибо!

ModBus RTU групповое чтение

Добавлено: 10 окт 2021, 13:10
Ingwar
Serg_Grn писал(а): 10 окт 2021, 12:01 В итоге обнаружено следующее: в Modbus RTU master функция _modbusMasterSendTxBuffer() имеет строку delay(10), эта строка расположена после строки Serial2.write.
Я перемещаю delay(10) до Serial2.write, в результате у меня формируется задержка перед отправкой следующего запроса слейву, таким образом проблема решается и слейв начинает нормально отвечать в каждом запросе.
У меня в проекте вот такая картина
[spoiler]void _modbusMasterSendTxBuffer()
{
byte i = 0;
int crc = modbusCalcCRC(_modbusMasterBufferSize, _modbusMasterBuffer);
_modbusMasterBuffer[ _modbusMasterBufferSize ] = crc >> 8;
_modbusMasterBufferSize++;
_modbusMasterBuffer[ _modbusMasterBufferSize ] = crc & 0x00ff;
_modbusMasterBufferSize++;
UCSR0A=UCSR0A |(1 << TXC0);
delay(10);
digitalWrite(16, 1);
delay(1);
Serial.write(_modbusMasterBuffer, _modbusMasterBufferSize);
while (!(UCSR0A & (1 << TXC0)));
digitalWrite(16, 0);
Serial.flush();
_modbusMasterBufferSize = 0;
_modbusMasterSendTime = millis();
}[/spoiler]
Вроде строка delay раньше, но это никак не помогает... Не могу нормально читать более 4 int из ПР200 ( Допускаю, что виновником может быть MAX485. Но у меня сейчас только такие...

ModBus RTU групповое чтение

Добавлено: 10 окт 2021, 13:26
Sancho
Serg_Grn писал(а): 10 окт 2021, 12:01 Я перемещаю delay(10) до Serial2.write, в результате у меня формируется задержка перед отправкой следующего запроса слейву, таким образом проблема решается и слейв начинает нормально отвечать в каждом запросе.
Не смотрел, но я так, через delay, не делал.
У меня после обработки предыдущего запроса, с учётом ожидания приёма последнего символа, время 20 + 5 + время обработки ответа.
После опроса последнего слэйва 800 +5 + ..
void _nextStep(bool rez)
{
_MB_Send_Time = millis();
if(rez)_allStatus|=1<<nomer;
else _allStatus&= ~(1<<nomer);
if(nomer == 3-1){_MB_Next_send= 800;} // смотреть 3....
else {_MB_Next_send=20;}
_MB_Mode = 1; //3
}
В курсе проблем некоторых ПЛК и общих правил.

ModBus RTU групповое чтение

Добавлено: 10 окт 2021, 15:18
Serg_Grn
Sancho писал(а): 10 окт 2021, 13:26 Не смотрел, но я так, через delay, не делал.
Да, я знаю что в Ваших блоках не так. Просто хотел бы чтоб в штатных блоках это решилось тоже, тем более, что там теперь есть групповое чтение. Хотя тут тема не совсем об этом, но я надеюсь меня простят за офтоп :)

Отправлено спустя 14 минут 1 секунду:
Ingwar писал(а): 10 окт 2021, 13:10 У меня в проекте вот такая картина
Может у Вас контроллер другой, у меня ESP32, картина такая:
[spoiler] _modbusMasterSendTxBuffer();
_modbusMasterState = 2;
}
void _modbusMasterSendTxBuffer()
{
byte i = 0;
int crc = modbusCalcCRC(_modbusMasterBufferSize, _modbusMasterBuffer);
_modbusMasterBuffer[ _modbusMasterBufferSize ] = crc >> 8;
_modbusMasterBufferSize++;
_modbusMasterBuffer[ _modbusMasterBufferSize ] = crc & 0x00ff;
_modbusMasterBufferSize++;
Serial2.write(_modbusMasterBuffer, _modbusMasterBufferSize);
delay(10);
Serial2.flush();
_modbusMasterBufferSize = 0;
_modbusMasterSendTime = millis();
}[/spoiler]
И вот переместив delay(10); на одну строку вверх я решаю проблему обмена со слейвом.

ModBus RTU групповое чтение

Добавлено: 11 янв 2024, 19:27
Serg_Grn
support писал(а): 28 июл 2021, 06:50 вот смотри, регистры идут с номерами 5,6,7,8,9 11,12,13,14
одним запросом прочитаются с 5 по 9, и вторым с 11 по 14. если они будут идти подряд 5,6,7,8,9 ,10,11,12,13,14 то они прочитаются одним запросом
[ref=#00aa00]support[/ref], несколько раз я сталкивался с тем, что некоторые ПЛК и частотники не поддерживают групповое чтение. И если нужные регистры идут подряд, то возникает проблема - их нельзя прочитать.
Было бы полезно, чтоб в программе групповое чтение можно было отключать.
Или может быть добавить выбор кода функции modbus, хотя это наверно сложнее и дольше делать...

ModBus RTU групповое чтение

Добавлено: 30 янв 2024, 07:28
vlad1451
Sancho писал(а): 24 дек 2020, 16:57 Можно, при желании, изменить на флоат...
Хотелось бы иметь такой, у меня как раз датчик температуры лежит для проекта. И ещё, выбор порта как производится? У меня просто Мега2560, там несколько портов.

ModBus RTU групповое чтение

Добавлено: 30 июн 2024, 22:19
millerboy
Serg_Grn писал(а): 11 янв 2024, 19:27
support писал(а): 28 июл 2021, 06:50 вот смотри, регистры идут с номерами 5,6,7,8,9 11,12,13,14
одним запросом прочитаются с 5 по 9, и вторым с 11 по 14. если они будут идти подряд 5,6,7,8,9 ,10,11,12,13,14 то они прочитаются одним запросом
[ref=#00aa00]support[/ref], несколько раз я сталкивался с тем, что некоторые ПЛК и частотники не поддерживают групповое чтение. И если нужные регистры идут подряд, то возникает проблема - их нельзя прочитать.
Было бы полезно, чтоб в программе групповое чтение можно было отключать.
Или может быть добавить выбор кода функции modbus, хотя это наверно сложнее и дольше делать...
Чтобы не создавать новую тему, приобщаюсь к вопросу, как можно реализовать чтение отдельно по регистристрам, панель которую читаю при групповом считывании просто выдает данные с первого регистра во все остальные, а если читать отдельно (через тот же modbus poll) – все ок, данные для адресов отображаются правильно.