Уважаемые пользователи! Наш сайт и форум содержится на средства полученные от рекламы. Если вы хотите и дальше продолжать общаться, скачивать, и т.п. пожалуйста отключите блокировку рекламы для нашего сайта/форума. Мы не обязываем Вас переходить по рекламным ссылкам, просто она должна отображаться у вас в браузере. Реклама размещена ненавязчиво, сверху и снизу страницы, на прочтение основного материала никак не влияет! Спасибо за понимание!

Работа ModBus в проектах FLProg

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

Работа ModBus в проектах FLProg

#1

Сообщение Sancho » 28.11.2019{, 12:40}

Как часто замечаю, иногда пользователи не до конца понимают как устроена работа обмена по модбас, и, соответственно, требуют не реализуемые задачи.
ilusha писал(а):
24.11.2019{, 01:04}
Почему работает Очень медленно modbus?
Очень медленно.
Это так медленно, если я делаю
не правильно..
Синхронизация включена на 1 миллисекунду
И для общего понимания. Не спеша.
Слэйв модбас rtu. Slave ModBus RTU.
При создании кода для IDE FLProg перед первой платой вставляет дополнительные, необходимые для работы, переменные, функции.
Одной из них является функция, отвечающая за обмен по модбас. Выполняется она, как Вы догадались, один раз в цикле.
Сама по себе состоит из других, вложенных функций, отвечающих за разные задачи.
В примере - минимальный вариант - значение из регистра на выход ШИМ. Время цикла - минимальное.

Итак, вначале проверяется, есть ли что либо, а именно байты, в буфере serial( или Softserial - не принципиально).
1-й цикл. Если ответ пусто, 0, функция прерывается, программа выполняется дальше.
2-й цикл. Если есть, запоминается текущее количество доступных для считывания байт( в _modbusSlaveLastRec),
запоминается текущее время( в _modbusSlaveTime), функция прерывается, программа выполняется дальше.
3-й цикл. Если значение количества последних и сейчас доступных для считывания байт не совпадает, значит данные всё еще поступают в буфер serial.
Запоминается текущее количество доступных для считывания байт(_modbusSlaveLastRec),
запоминается текущее время(_modbusSlaveTime), функция прерывается, программа выполняется дальше.
N-й цикл. Значение количества доступных для считывания из буфера serial байт и старое значение одинаковы, то проверяем, сколько прошло времени,
между последним изменением, вдруг байт где-то заплутал. Если время ожидания получения байта ещё не вышло - прерываем функцию.
N+n цикл. Время вышло, больше байтов нет, начинаем обрабатывать полученное.
Замечу - время ожидания приёма байта зависит от скорости(раньше), у Автора сейчас составляем 5 мс....
обнуляем _modbusSlaveLastRec.
Загружаем все данные из буфера serial в буфер программы, попутно подсчитывая количество байт и следя за переполнением.
/*
Здесь у Автора нет защиты от переполнения буфера и получения нежданчиков:
если в моей библиотеке serial размер буфера больше стандартного, буфер модбаса переполнится,
выставится только флаг - bBuffOverflow, но данные продолжат записываться в ячейки, которые буферу не принадлежат...
Я в таких случаях просто вызываю read(), опустошая буфер serial. Легко чинится в коде перестановкой строк....
*/
Если количество полученных байт >= минимальной посылки, проверяем, нам ли она адресована. Если нет - функция прерывается, программа выполняется дальше.
Проверяем контрольную сумму, если не правильная - функция прерывается, программа выполняется дальше.
Далее, исходя из номера функции, делаем необходимые действия - записываем данные при необходимости и готовим ответ.
Передаём ответ мастеру.
Функция закончена, обмен проведён, программа выполняется дальше.

Как видно из моей мисанины, выполнения кода модбас при малом времени цикла занимает несколько циклов,
а при программе, напичканой выводами на дисплей по I2C и другими тяжело-временными блоками, минимум два.
Если не получится на контроллере - сделаю на тразисторах и 155/176...Научился, немного.
Поможем проекту вместе!

ecoins
Лейтенант
Сообщения: 457
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 54
Откуда: Шатура
Имя: Энвер

Работа ModBus в проектах FLProg

#2

Сообщение ecoins » 28.11.2019{, 18:34}

Sancho писал(а):
28.11.2019{, 12:40}
Далее, исходя из номера функции, делаем необходимые действия - записываем данные при необходимости и готовим ответ.
Передаём ответ мастеру.
Функция закончена, обмен проведён, программа выполняется дальше.
-----
И здесь реализация ModBus в FLProg сама становится "тяжело-временным блоком", особенно если скорость обмене не высокая (например 9600) и кол-во переменных больше 10.
Это происходит из-за того, что функция Serialx.write() "тормозит" выполнение всей программы до момента, пока не будет завершен вывод всего сообщения.
Это недостаток Arduino IDE (библиотек) - почему так сделано, не очень ясно. Аппаратно контроллеры UART поддерживают вывод по прерываниям.
Когда-нибудь функцию вывода буфера UART с выставлением флага завершения вывода кем-нибудь будет написана.
Или самим придется написать. :smile453:
-----
Временные диаграммы при обмене через ModBus FLProg можно исследовать логическим анализатором на пинах RX,TX.

mafckz
Рядовой
Сообщения: 6
Зарегистрирован: 31.10.2019{, 06:57}
Репутация: 0
Имя: Роман

Работа ModBus в проектах FLProg

#3

Сообщение mafckz » 01.12.2019{, 23:07}

Прошу подтвердить мой вывод, что FLProg не поддерживает работу с адресами регистров (тегов) больше максимального значения типа integer ("по плюсу" = 32767), т.е. работа с адресом 40969 невозможна?

Arduino IDE при компиляции выдает:
C:\Users\PC_Home10\AppData\Local\Temp\flprog\pr10\pr10.ino:4:42:
warning: narrowing conversion of '40969l' from 'long int' to 'int' inside { } [-Wnarrowing]

И при проверке через MasterOPC Universal Modbus Server выдает ошибки связи

******** Update:
А нет, у меня проблемы в другой причине - не понимаю почему - в MasterOPC при указании тегов отличных от Coils выдает ошибки
Вложения
2019-12-02_014437.png
Последний раз редактировалось mafckz 01.12.2019{, 23:52}, всего редактировалось 2 раза.

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

Работа ModBus в проектах FLProg

#4

Сообщение Rovki » 01.12.2019{, 23:31}

так 4 или 3 в переди слева это номер функции(области) и при указании адреса отбрасывается
Электронщик до мозга костей и не только

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

Работа ModBus в проектах FLProg

#5

Сообщение Sancho » 02.12.2019{, 10:11}

mafckz, А зачем Вы такие номера прописываете? Для чего?
Но Вы правы - адреса регистров в флпрог имеют тип int, а не word, почему - незнаю:
int _modbusSlaveAddresTable_4[10]....
Если не получится на контроллере - сделаю на тразисторах и 155/176...Научился, немного.
Поможем проекту вместе!

mafckz
Рядовой
Сообщения: 6
Зарегистрирован: 31.10.2019{, 06:57}
Репутация: 0
Имя: Роман

Работа ModBus в проектах FLProg

#6

Сообщение mafckz » 02.12.2019{, 10:22}

Извиняюсь за предыдущий пост - совсем не в тему.
Оказывается, если использовать регистры в MasterOPC, которых нет в слейве - то будут ошибки как на скрине выше.
А зачем Вы такие номера прописываете? Для чего?
Такой адрес регистра использует nсерийный контроллер Pixel для передачи значения аварий приточно-вытяжной установки.
Думаю, если не получится, то на стороне HMI макросами передам значение в более меньший регистр (пустой)

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

Работа ModBus в проектах FLProg

#7

Сообщение Sancho » 05.12.2019{, 17:56}

ecoins писал(а):
28.11.2019{, 18:34}
И здесь реализация ModBus в FLProg сама становится "тяжело-временным блоком", особенно если скорость обмене не высокая (например 9600) и кол-во переменных больше 10.
Это происходит из-за того, что функция Serialx.write() "тормозит" выполнение всей программы до момента, пока не будет завершен вывод всего сообщения.
Это недостаток Arduino IDE (библиотек) - почему так сделано, не очень ясно. Аппаратно контроллеры UART поддерживают вывод по прерываниям.
Когда-нибудь функцию вывода буфера UART с выставлением флага завершения вывода кем-нибудь будет написана.
Или самим придется написать.
Энвер, как я убедился, Вы доверяете только фактам.
Для Вас провёл специальный эксперимент, простой.
Всё нормально.
Вопрос в реализации в флпрог-модбас: Автор скорее всего намеренно сделал так, используя функцию flush (), и прицепив к этому делу пин включения передатчика.
Вы можете запросто переделать под свои нужды, заменив указанную функцию на другую, availableForWrite с небольшими доработками кода.
По скринам - пауза в тактах - скорее всего загрузка буфера
СпойлерПоказать
screenshot_19-12-05_17-43-10 - копия.png
screenshot_19-12-05_17-44-32 - копия.png
СпойлерПоказать

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

unsigned long _stou1 = 0UL;
void setup()
{
Serial.begin(19200);
_stou1 = millis();
DDRB |=B00000100;
}
void loop()
{
//Плата:1
if (!(0)){ if (_isTimer(_stou1, 200 )) {Serial.println(String("0123456789")); _stou1 = millis();}} else {_stou1 = millis();}

PORTB^=B00000100;// инвертируем пин, зелёная линия на скринах
}
bool _isTimer(unsigned long startTime, unsigned long period )
  {
  return (period <=millis() - startTime);
  }
Отправлено спустя 2 минуты 33 секунды:
Да, кстати, как смотрится новая функция таймера?
Если не получится на контроллере - сделаю на тразисторах и 155/176...Научился, немного.
Поможем проекту вместе!

ecoins
Лейтенант
Сообщения: 457
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 54
Откуда: Шатура
Имя: Энвер

Работа ModBus в проектах FLProg

#8

Сообщение ecoins » 12.12.2019{, 20:39}

Sancho писал(а):
05.12.2019{, 17:59}
Энвер, как я убедился, Вы доверяете только фактам.
Для Вас провёл специальный эксперимент, простой.
Всё нормально.
Вопрос в реализации в флпрог-модбас: Автор скорее всего намеренно сделал так, используя функцию flush (), и прицепив к этому делу пин включения передатчика.
Вы можете запросто переделать под свои нужды, заменив указанную функцию на другую, availableForWrite с небольшими доработками кода.
По скринам - пауза в тактах - скорее всего загрузка буфера
Функция availableForWrite возвращает количество байтов (символов), доступных для записи в последовательный буфер, не блокируя операцию записи.
Но функции Serial.println() и Serial.write() выполняются без прерывания и выход из них происходит только после передачи всего буфера в линию. То есть процессор в это время кроме вывода в буфер ничем не занят ( только обработчиками аппаратных прерываний).
Осциллограммы не показывают загруженность процессора.
-------------------------
По таймеру. Хорошо написан. Но проблема переполнения регистра millis() через 71 582мин (49 дней) остается (... по моему мнению).

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

Работа ModBus в проектах FLProg

#9

Сообщение Sancho » 13.12.2019{, 08:39}

ecoins писал(а):
12.12.2019{, 20:39}
То есть процессор в это время кроме вывода в буфер ничем не занят ( только обработчиками аппаратных прерываний).
Осциллограммы не показывают загруженность процессора.
Я прошу прощения - Вам сложно увидеть в коде, что в момент передачи происходит инверсия выхода, как указанно в цикле loop ? Строка 13. Увы. Думал осциллограммы Вам помогут. Там, кстати, видно, как выполнение loop приостанавливается в момент загрузки байта из буфера в выходной регистр.

Отправлено спустя 25 минут 30 секунд:
По поводу Ваших сомнений с таймером - файл.
Вложения
Заготовка Atmel_02_uint32 .flp
(112.94 КБ) 10 скачиваний
Если не получится на контроллере - сделаю на тразисторах и 155/176...Научился, немного.
Поможем проекту вместе!

ecoins
Лейтенант
Сообщения: 457
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 54
Откуда: Шатура
Имя: Энвер

Работа ModBus в проектах FLProg

#10

Сообщение ecoins » 13.12.2019{, 16:24}

Sancho писал(а):
13.12.2019{, 09:05}
Я прошу прощения - Вам сложно увидеть в коде, что в момент передачи происходит инверсия выхода, как указанно в цикле loop ? Строка 13. Увы. Думал осциллограммы Вам помогут. Там, кстати, видно, как выполнение loop приостанавливается в момент загрузки байта из буфера в выходной регистр.
Посмотрел повнимательнее и после проверил на логическом анализаторе.
Тест_Sancho.JPG
Тест_Sancho_2.JPG
Тест_Sancho_3.JPG
----
Действительно функция Serial.println(и видимо Serial.write) выдают в линию из буфера по прерываниям.
Любопытно, в явной форме это вроде нигде не описано - не видел.
Отлично, Sancho - спасибо большое.
Теперь проще будет работать с UART, с реализацией ModBus FLProg надо будет что-то подумать.
Попозже займемся, может и автор поправит...
---Спасибо.

Аватара пользователя
Nikan
Капитан
Сообщения: 985
Зарегистрирован: 29.12.2016{, 00:49}
Репутация: 66
Откуда: москва

Работа ModBus в проектах FLProg

#11

Сообщение Nikan » 14.12.2019{, 01:53}

ecoins писал(а):
13.12.2019{, 16:24}
Любопытно, в явной форме это вроде нигде не описано - не видел.
а даташит на MK слабо прочитать? там работа приемо-передатчика ясно описана, что как и какие прерывания...

Аватара пользователя
Alias
Лейтенант
Сообщения: 415
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 31
Откуда: Rus44
Имя: Michael
Контактная информация:

Работа ModBus в проектах FLProg

#12

Сообщение Alias » 08.02.2020{, 17:50}

Все так интересно! Давно хотел уточнить, но думал, что закидаете тапками. Ладно, кидайте!..
Почти уже ввожу в эксплуатацию свой второй проект. Тоже на Меге2560. Собираюсь теперь дома построить сеть на Modbus, но вот именно некоторого понимания нет.
Например, насколько критично для надёжного выполнения основной программы большое количество передаваемых тегов?
Сейчас у меня 14 переменных byte ужаты в 7 регистров int16, и еще в одном - 14 переменных bool. Под КаСкаду. Хотелось бы и еще добавить, но максимальный период опроса в ней не может быть больше секунды, если я опять ничего не путаю.
Понимаю, что процессор не переключается на Modbus полностью и машинное время под основную программу остается, но вот много ли? Стоит ли стараться увеличивать период опроса, скажем, до 5 секунд, если реально ничего там критичного нет, или Modbus фоновая подпрограмма и не зацикливаться на этом? И скорость лучше поднять, да?
Мне уже отвечали, что у кого-то и под сотню тегов гуляет, но хочется несколько большего понимания.
Если что - порт железный, не софт.
PS Наверное, я еще сокращу количество тегов, "динамической" упаковкой: в регистр int в младшей "половинке" прописывать одну из 8 переменных byte, а в старшей - бит на соответствующем ей месте.

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

Работа ModBus в проектах FLProg

#13

Сообщение Rovki » 08.02.2020{, 18:25}

Немного путаете- период опроса это не тайм аут и не пауза . Тайм аут это время отклика слейва на команду мастера , пауза в каскаде - это задежка на отправку посылки слейву .Обычно на отправку пакета уходит 30-60мс , умножим на 100 и получим ЗАДЕРЖКУ 3-6сек
которая визуально воспринимается как- нажал кнопку ,а лампа от нее загорелась через 3-6сек. Но это при обмене с устройством регистрами - одна переменная \одна посылка ,если использовать групповое чтение\запись то время сократиться . Это то что касается каскады . При этом в контроллере все процессы должны быть организованы правильно - это работа по прерываниям с учетом их важности(приоритета) итд..итп. Например при работе с контроллерами ПР200 и использованием Овенлоджик (FBD) , нет необходимости думать пользователю о прерываниях при работе с аналоговыми входами,таймерами и модбасом , там конфликты исключены на программном уровне , да ценой быстродействия - быстродействие по входам не более 500гц (мин.время цикла 1мс)...
Электронщик до мозга костей и не только

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

Работа ModBus в проектах FLProg

#14

Сообщение Sancho » 08.02.2020{, 22:06}

Alias, тут, немного выше, писал.
Если не получится на контроллере - сделаю на тразисторах и 155/176...Научился, немного.
Поможем проекту вместе!

Аватара пользователя
Alias
Лейтенант
Сообщения: 415
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 31
Откуда: Rus44
Имя: Michael
Контактная информация:

Работа ModBus в проектах FLProg

#15

Сообщение Alias » 09.02.2020{, 00:07}

Да, я все это видел и неоднократно возвращался сюда снова. Мне не нужны детали, понимай я в них, сам бы себе и ответил. Мне бы понять происходящее на пальцах, можно тремя фразами. Понимаю, опираясь на первое сообщение, примерно так, по-непрограммистски:
Начиная с 1 по N+n цикл основная программа успевает отрабатывать в полном объеме, причем в зависимости от сложности вычислений по несколько циклов и вероятность пропустить что-то важное, например, превышение контролируемого значения тока, невелика. То есть мы в любом случае полный цикл пройдем вместе с тем самым блоком слежения за током.
Затем начинается перегрузка из буфера в буфер, отработка команды, ответ мастеру. Это понятно. И вот тут немного бы уточнить, как это происходит.
Если все ресурсы отдаются этой процедуре сразу, то есть по входу в какую-то библиотеку, из которой пока все не выполнится, не выйти и наш пользовательский код не выполняется, то сколько времени на это уходит? Мне ведь нужно смотреть за током постоянно, ну хотя бы 1-2 раза в секунду, боюсь пропустить превышение и не отреагировать. Зависит ли это время "невыхода" из "библиотеки" от количества тегов, передаваемых по Модбас? Или между передаваемыми тегами пользовательская программа тоже исполняется?
От этого зависит моя тактика:
Если моя программа не исполняется, пока передаются данные, я буду изыскивать все возможности по сокращению тегов, чтобы гарантированно не проспать событие.
Если во время передачи тегов мастеру моя программа тоже будет исполняться, хотя бы пару циклов в секунду, я буду перегонять больше данных и не скупиться, а работать комфортно. Естественно, тоже упаковывая, как только смогу.
Вот, собственно, что меня беспокоит.
Ну и вопрос, почему при количестве тегов больше 10 Ардуино начинает тормозить и есть ли разница, что это - Nano или Mega?
И еще: а если в программе очень большие формулы и сложные расчёты стыковки с МКС, Модбас не пропустит поступление очередного байта или бита?Программа ведь может не успеть передать управление к блокам Модбас, тем, что до первой платы.
Rovki писал(а):
08.02.2020{, 18:25}
Немного путаете- период опроса это не тайм аут и не пауза
Да, Вы говорили это в Экспрессе, но я имею в виду период опроса, вернее, период синхронизации в терминологии FlProg, там у Мастера в настройках этот период можно выбирать. Далеко не все мои слейвы будут работать на КаСкаду, скорее всего только один, поэтому я и хочу разобраться, как часто я могу их опрашивать без потери контроля над ключевыми параметрами. В некоторых случаях мне достаточно даже 10 и более секунд между опросами.
Если я правильно понимаю термин "Период", означающий отрезок времени, в течение которого циклический процесс совершает полный цикл, Мастер запрашивает данные от слейва не по отсчету времени от предыдущего ответа, а по своим часам, иначе этот период может плавать. То есть без умножения на 100. Кстати, а что это? Это только в КаСкаде, а где почитать? Хотелось бы заранее все понять и не наступать на грабли. Но это уже другая тема.

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

Работа ModBus в проектах FLProg

#16

Сообщение Rovki » 09.02.2020{, 00:36}

Передача \прием это асинхронный процесс в модбасе , поэтому исполнение всех команд (запись\чтение тэгов) идет не по часам ,а последовательно- дал команду одному слейву ,прочитал (записал) данные , переходит к другому регистру идт по кругу (период) . Но время периода в каскаде влияет только на задержку ...Ответ от слейва всегда плавает и стало бы и весь период так же . А плавает ответ ,потому что слейв занят еще и вычислительными задачами и работу по другим интерфесам и все эти процессы асинхронны.
Электронщик до мозга костей и не только

Аватара пользователя
Alias
Лейтенант
Сообщения: 415
Зарегистрирован: 27.11.2017{, 13:15}
Репутация: 31
Откуда: Rus44
Имя: Michael
Контактная информация:

Работа ModBus в проектах FLProg

#17

Сообщение Alias » 09.02.2020{, 00:44}

То есть период синхронизации в flp это тоже пауза по факту?
А что такое 100?

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

Работа ModBus в проектах FLProg

#18

Сообщение Rovki » 09.02.2020{, 08:52}

Alias писал(а):
09.02.2020{, 00:44}
То есть период синхронизации в flp это тоже пауза по факту?
А что такое 100?
100- это 100 регистров (сетевых регистров в примере). Умножаю на 100 исходя из последовательной обработки их...
Электронщик до мозга костей и не только

tolochko
Рядовой
Сообщения: 77
Зарегистрирован: 30.11.2016{, 16:58}
Репутация: 0
Откуда: Днепропетровск

Работа ModBus в проектах FLProg

#19

Сообщение tolochko » 14.02.2020{, 12:10}

Здравствуйте уважаемые
Прошу помочь с проектом знатоков МОДБАС
Есть проект на 30 тегов инт. Работает с ОПС сервером При скорости 9600 не хочет
Почитал здесь что пишут но к сожалению много незнакомых слов
Буду благодарен если подскажите как правильно настроить МОДБАС
Проект прикрепил
Вложения
Счетчики1.flp
(1.65 МБ) 4 скачивания

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

Работа ModBus в проектах FLProg

#20

Сообщение Sancho » 14.02.2020{, 13:10}

tolochko писал(а):
14.02.2020{, 12:10}
При скорости 9600 не хочет
На какой работает?
Индикаторы пробовали убирать, которые счётчики показывают?
Если не получится на контроллере - сделаю на тразисторах и 155/176...Научился, немного.
Поможем проекту вместе!

Ответить

Вернуться в «Букварь»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость