add server for realtime monitoring and parameters changing

This commit is contained in:
Edward Emelianov 2025-07-15 17:37:45 +03:00
parent c35f38ccd6
commit 0074eac5d8
8 changed files with 312 additions and 125 deletions

View File

@ -33,12 +33,12 @@ F01.11 61707 0 0 # Постоянный ток торможения во вр
F01.12 61708 0 0 # Время торможения пост. током во время остановки х10, сек.
F01.13 61709 0 0 # Время бездействия между сменой направлений вращения х10, сек.
F01.14 61710 50 0 # Частота остановки х10, Гц
F01.15 61711 0 0 # Зарезервировано
F01.16 61712 0 0 # Зарезервировано
F01.15 61711 0 1 # Зарезервировано
F01.16 61712 0 1 # Зарезервировано
F01.17 61713 0 0 # Перезапуск с клемм после включения [0 — не действ. 1 - действует]
F01.18 61714 0 0 # Перезапуск после потери напряжения [0 — запрет; 1 - перезапуск]
F01.19 61715 10 0 # Задержка перезапуска х10, сек. [0.0 до 6000.0] (Только если F1.18 = 1)
F01.20 61716 0 0 # Зарезервировано
F01.20 61716 0 1 # Зарезервировано
F01.21 61717 0 0 # Действие, если выходная частота меньше минимальной; 0 — работа на мин.частоте; 1 - остановка; 2 - работа на нулевой скорости вращения.
F01.22 61718 5000 0 # Задание частоты при работе в пожарном режиме (х100), Гц.
F02.00 61952 0 0 # Тип нагрузки [0 — тип G; 1 тип P;]
@ -53,19 +53,19 @@ F02.08 61960 1264 0 # Сопротивление ротора х100, Ом (З
F02.09 61961 67 0 # Индуктивность рассеивания х10, мГн (Значение после автонастройки!)
F02.10 61962 956 0 # Индуктивность двигателя х10, мГн (Значение после автонастройки!)
F02.11 61963 33 0 # Ток холостого хода х10, А (Значение после автонастройки!)
F02.12 61964 880 0 # Зарезервировано
F02.13 61965 810 0 # Зарезервировано
F02.14 61966 750 0 # Зарезервировано
F02.12 61964 880 1 # Зарезервировано
F02.13 61965 810 1 # Зарезервировано
F02.14 61966 750 1 # Зарезервировано
F02.15 61967 0 0 # Выбор типа энкодера
F02.16 61968 1024 0 # Число импульсов энкодера на оборот
F02.17 61969 0 0 # Последовательность фаз энкодера ABZ
F02.18 61970 1 0 # Количество пар полюсов резольвера
F02.19 61971 1 0 # Зарезервировано
F02.20 61972 3 0 # Зарезервировано
F02.21 61973 3 0 # Зарезервировано
F02.22 61974 10 0 # Зарезервировано
F02.23 61975 10 0 # Зарезервировано
F02.24 61976 1000 0 # Зарезервировано
F02.19 61971 1 1 # Зарезервировано
F02.20 61972 3 1 # Зарезервировано
F02.21 61973 3 1 # Зарезервировано
F02.22 61974 10 1 # Зарезервировано
F02.23 61975 10 1 # Зарезервировано
F02.24 61976 1000 1 # Зарезервировано
F02.25 61977 1 0 # Защита от перегрузки [0 — не действует; 1 — действует;]
F02.26 61978 1000 0 # Коэффициент защиты от перегрузки х10, % [F02.26 x F02.04]
F03.00 62208 30 0 # Пропорциональный коэффициент контура скорости 1
@ -119,7 +119,7 @@ F04.30 62494 50 0 # Время понижения напряжения х10,
F04.31 62495 1000 0 # Максимальное выходное напряжение х10, %
F04.32 62496 0 0 # Минимальное выходное напряжение х10, %
F04.33 62497 1 0 # Выбор функции АВР
F04.34 62498 400 0 # Зарезервировано
F04.34 62498 400 1 # Зарезервировано
F05.00 62720 0 0 # Выбор клеммы DI5
F05.01 62721 1 0 # Клемма DI1
F05.02 62722 4 0 # Клемма DI2
@ -149,7 +149,7 @@ F05.25 62745 0 0 # Задержка включения клеммы DI7 х100
F05.26 62746 0 0 # Задержка выключения клеммы DI7 х1000, сек.
F05.27 62747 0 0 # Задержка включения клеммы DI8 х1000, сек.
F05.28 62748 0 0 # Задержка выключения клеммы DI8 х1000, сек.
F05.29 62749 0 0 # Зарезервировано
F05.29 62749 0 1 # Зарезервировано
F05.30 62750 0 0 # Нижний предел частоты DI5 х100, КГц
F05.31 62751 0 0 # Настройка нижнего предела частоты DI5 х10, %
F05.32 62752 5000 0 # Верхний предел частоты DI5 х100, КГц
@ -212,46 +212,46 @@ F07.04 63236 255 0 # Параметры состояния при остан
F07.05 63237 100 0 # Коэффициент частоты х100
F07.06 63238 1000 0 # Скорость вращения х10, %
F07.07 63239 10 0 # Коэффициент линейной скорости х10, %
F07.08 63240 36 0 # Температура выпрямителя, С
F07.09 63241 36 0 # Температура инвертора, С
F07.10 63242 60770 0 # Версия ПО
F07.11 63243 0 0 # Время наработки, час.
F07.12 63244 0 0 # Нижний предел сигнализации AI1, В
F07.13 63245 680 0 # Верхний предел сигнализации AI1, В
F07.14 63246 0 0 # Выбор канала ограничения верхнего предела выхода ПИД-регулятора
F07.15 63247 15 0 # Номинальная мощность ПЧ х10, КВт
F07.16 63248 380 0 # Номинальное напряжение, В
F07.17 63249 75 0 # Номинальный ток х10, А
F07.18 63250 0 0 # Текущая ошибка
F07.19 63251 0 0 # Ошибка при предыдущем отключении
F07.20 63252 0 0 # Ошибка при 2-м отключении
F07.21 63253 0 0 # Ошибка при 3-м отключении
F07.22 63254 0 0 # Ошибка при 4-м отключении
F07.23 63255 0 0 # Ошибка при 5-м отключении
F07.24 63256 0 0 # Частота в момент текущей аварии х100, Гц
F07.25 63257 0 0 # Опорная частота в момент текущей аварии х100, Гц
F07.26 63258 0 0 # Выходное напряжение в момент текущей аварии, В
F07.27 63259 0 0 # Выходной ток в момент текущей аварии х10, В
F07.28 63260 0 0 # Напряжение звена постоянного тока в момент текущей аварии х10, В
F07.29 63261 0 0 # Максимальная температура ПЧ в момент текущей аварии х10, С
F07.30 63262 0 0 # Состояние входных клемм в момент текущей аварии
F07.31 63263 0 0 # Состояние выходных клемм в момент текущей аварии
F07.32 63264 0 0 # Выходная частота в момент предыдущей аварии х100, Гц
F07.33 63265 0 0 # Опорная частота в момент предыдущей аварии х100, Гц
F07.34 63266 0 0 # Выходное напряжение в момент предыдущей аварии, В
F07.35 63267 0 0 # Выходной ток в момент предыдущей аварии х10, А
F07.36 63268 0 0 # Напряжение звена постоянного тока в момент предыдущей аварии х10, В
F07.37 63269 0 0 # Максимальная температура ПЧ в момент предыдущей аварии х10, С
F07.38 63270 0 0 # Состояние входных клемм в момент предыдущей аварии
F07.39 63271 0 0 # Состояние выходных клемм в момент предыдущей аварии
F07.40 63272 0 0 # Частота в момент 2-й аварии х100, Гц
F07.41 63273 0 0 # Опорная частота в момент 2-й аварии х100, Гц
F07.42 63274 0 0 # Выходное напряжение в момент 2-й аварии, В
F07.43 63275 0 0 # Выходной ток в момент 2-й аварии х10, А
F07.44 63276 0 0 # Напряжение звена постоянного тока в момент 2-й аварии, В
F07.45 63277 0 0 # Максимальная температура ПЧ в момент 2-й аварии х10, С
F07.46 63278 0 0 # Состояние входных клемм в момент 2-й аварии
F07.47 63279 0 0 # Состояние выходных клемм в момент 2-й аварии
F07.08 63240 36 1 # Температура выпрямителя, С
F07.09 63241 36 1 # Температура инвертора, С
F07.10 63242 60770 1 # Версия ПО
F07.11 63243 0 1 # Время наработки, час.
F07.12 63244 0 1 # Нижний предел сигнализации AI1, В
F07.13 63245 680 1 # Верхний предел сигнализации AI1, В
F07.14 63246 0 1 # Выбор канала ограничения верхнего предела выхода ПИД-регулятора
F07.15 63247 15 1 # Номинальная мощность ПЧ х10, КВт
F07.16 63248 380 1 # Номинальное напряжение, В
F07.17 63249 75 1 # Номинальный ток х10, А
F07.18 63250 0 1 # Текущая ошибка
F07.19 63251 0 1 # Ошибка при предыдущем отключении
F07.20 63252 0 1 # Ошибка при 2-м отключении
F07.21 63253 0 1 # Ошибка при 3-м отключении
F07.22 63254 0 1 # Ошибка при 4-м отключении
F07.23 63255 0 1 # Ошибка при 5-м отключении
F07.24 63256 0 1 # Частота в момент текущей аварии х100, Гц
F07.25 63257 0 1 # Опорная частота в момент текущей аварии х100, Гц
F07.26 63258 0 1 # Выходное напряжение в момент текущей аварии, В
F07.27 63259 0 1 # Выходной ток в момент текущей аварии х10, В
F07.28 63260 0 1 # Напряжение звена постоянного тока в момент текущей аварии х10, В
F07.29 63261 0 1 # Максимальная температура ПЧ в момент текущей аварии х10, С
F07.30 63262 0 1 # Состояние входных клемм в момент текущей аварии
F07.31 63263 0 1 # Состояние выходных клемм в момент текущей аварии
F07.32 63264 0 1 # Выходная частота в момент предыдущей аварии х100, Гц
F07.33 63265 0 1 # Опорная частота в момент предыдущей аварии х100, Гц
F07.34 63266 0 1 # Выходное напряжение в момент предыдущей аварии, В
F07.35 63267 0 1 # Выходной ток в момент предыдущей аварии х10, А
F07.36 63268 0 1 # Напряжение звена постоянного тока в момент предыдущей аварии х10, В
F07.37 63269 0 1 # Максимальная температура ПЧ в момент предыдущей аварии х10, С
F07.38 63270 0 1 # Состояние входных клемм в момент предыдущей аварии
F07.39 63271 0 1 # Состояние выходных клемм в момент предыдущей аварии
F07.40 63272 0 1 # Частота в момент 2-й аварии х100, Гц
F07.41 63273 0 1 # Опорная частота в момент 2-й аварии х100, Гц
F07.42 63274 0 1 # Выходное напряжение в момент 2-й аварии, В
F07.43 63275 0 1 # Выходной ток в момент 2-й аварии х10, А
F07.44 63276 0 1 # Напряжение звена постоянного тока в момент 2-й аварии, В
F07.45 63277 0 1 # Максимальная температура ПЧ в момент 2-й аварии х10, С
F07.46 63278 0 1 # Состояние входных клемм в момент 2-й аварии
F07.47 63279 0 1 # Состояние выходных клемм в момент 2-й аварии
F08.00 63488 100 0 # Время разгона 2 х10, сек.
F08.01 63489 100 0 # Время торможения 2 х10, сек.
F08.02 63490 100 0 # Время разгона 3 х10, сек.
@ -304,7 +304,7 @@ F09.09 63753 1000 0 # Верхний предел ПИД х10, %
F09.10 63754 0 0 # Нижний предел ПИД х10, %
F09.11 63755 0 0 # Величина сигнала обратной связи, активирущая ошибку пропажи сигнала х10, %
F09.12 63756 10 0 # Задержка включения ошибки пропажи сигнала х10, сек.
F09.13 63757 0 0 # Зарезервировано
F09.13 63757 0 1 # Зарезервировано
F09.14 63758 50 0 # Пропорциональная составляющая 2 (Кр2) х100
F09.15 63759 20 0 # Интегральная составляющая 2 (Ti2) х100
F09.16 63760 0 0 # Дифференциальная составляющая 2 (Td2) х100
@ -321,7 +321,7 @@ F0A.01 64001 0 0 # Амплитуда частоты толчка х10, се
F0A.02 64002 0 0 # Время увеличения частоты колебаний х10, сек.
F0A.03 64003 0 0 # Время снижения частоты колебаний х10, сек.
F0A.04 64004 0 0 # Установка длины, м
F0A.05 64005 0 0 # Заданная длина, м
F0A.05 64005 0 1 # Заданная длина, м
F0A.06 64006 1 0 # Количество импульсов на оборот
F0A.07 64007 1000 0 # Длина окружности вала х100, м
F0A.08 64008 1000 0 # Множитель х1000
@ -330,7 +330,7 @@ F0A.10 64010 0 0 # Установленное значение счетчик
F0A.11 64011 0 0 # Определяемое значение счетчика
F0A.12 64012 0 0 # Время работы, мин.
F0A.13 64013 0 0 # Метод остановки
F0A.14 64014 0 0 # Зарезервировано
F0A.14 64014 0 1 # Зарезервировано
F0B.00 64256 0 0 # Режим простого ПЛК
F0B.01 64257 0 0 # Режим работы ПЛК при перебое с питанием
F0B.02 64258 0 0 # Многоскоростной режим 0 х10, %
@ -387,7 +387,7 @@ F0C.14 64526 0 0 # Режимы оповещения при обнаруже
F0C.15 64527 0 0 # Выбор регулировки несущей частоты
F0C.16 64528 1 0 # Режим ШИМ
F0C.17 64529 1 0 # Фильтр низких частот
F0C.18 64530 1 0 # Зарезервирован
F0C.18 64530 1 1 # Зарезервирован
F0D.00 64768 1 0 # Метод управления вторым двигателем
F0D.01 64769 1 0 # Тип нагрузки
F0D.02 64770 1 0 # Тип второго двигателя
@ -401,19 +401,19 @@ F0D.09 64777 1264 0 # Сопротивление ротора двигате
F0D.10 64778 67 0 # Индуктивность рассеяния двигателя 2 х10
F0D.11 64779 956 0 # Индуктивность двигателя 2 х10
F0D.12 64780 33 0 # Ток холостого хода двигателя 2 х10, А
F0D.13 64781 1 0 # Зарезервировано
F0D.14 64782 1 0 # Зарезервировано
F0D.15 64783 1 0 # Зарезервировано
F0D.16 64784 1 0 # Зарезервировано
F0D.17 64785 1 0 # Зарезервировано
F0D.18 64786 1 0 # Зарезервировано
F0D.19 64787 1 0 # Зарезервировано
F0D.20 64788 1 0 # Зарезервировано
F0D.21 64789 1 0 # Зарезервировано
F0D.22 64790 1 0 # Зарезервировано
F0D.23 64791 1 0 # Зарезервировано
F0D.24 64792 1 0 # Зарезервировано
F0D.25 64793 1 0 # Зарезервировано
F0D.13 64781 1 1 # Зарезервировано
F0D.14 64782 1 1 # Зарезервировано
F0D.15 64783 1 1 # Зарезервировано
F0D.16 64784 1 1 # Зарезервировано
F0D.17 64785 1 1 # Зарезервировано
F0D.18 64786 1 1 # Зарезервировано
F0D.19 64787 1 1 # Зарезервировано
F0D.20 64788 1 1 # Зарезервировано
F0D.21 64789 1 1 # Зарезервировано
F0D.22 64790 1 1 # Зарезервировано
F0D.23 64791 1 1 # Зарезервировано
F0D.24 64792 1 1 # Зарезервировано
F0D.25 64793 1 1 # Зарезервировано
F0D.26 64794 1 0 # Защита от перегрузки для двигателя 2
F0D.27 64795 1000 0 # Обнаружение перегрузки двигателя 2 х10, %
F0E.00 65024 1 0 # Сетевой адрес
@ -457,43 +457,43 @@ A01.16 41232 500 0 # Среднее значение входа AI3 х100, В
A01.17 41233 500 0 # Соответствие среднему значению входа AI3 х10, %
A01.18 41234 100 0 # Фильтр входа AI3 х1000, сек
A01.19 41235 50 0 # Фильтр дребезга контактов х1000, сек.
A02.00 41472 0 0 # Заданная частота х100, Гц
A02.01 41473 0 0 # Выходная частота х100, Гц
A02.02 41474 0 0 # Опорная частота разгона х100, Гц
A02.03 41475 0 0 # Выходное напряжение, В
A02.04 41476 0 0 # Выходной ток х10, А
A02.05 41477 0 0 # Обороты двигателя, об/мин
A02.06 41478 0 0 # Зарезервировано
A02.07 41479 0 0 # Зарезервировано
A02.08 41480 0 0 # Выходная мощность х10, %
A02.09 41481 0 0 # Выходной момент х10, %
A02.10 41482 0 0 # Оценка частоты двигателя х100, Гц
A02.11 41483 0 0 # Напряжение звена постоянного тока, В
A02.12 41484 0 0 # Состояние дискретных входов
A02.13 41485 0 0 # Состояние дискретных выходов
A02.14 41486 0 0 # Цифровое задание частоты х100, Гц
A02.15 41487 0 0 # Зарезервировано
A02.16 41488 0 0 # Линейная скорость
A02.17 41489 0 0 # Длина импульсов
A02.18 41490 0 0 # Счетчик значения
A02.19 41491 0 0 # Напряжение на входе AI1 х100, В
A02.20 41492 0 0 # Напряжение на входе AI2 х100, В
A02.21 41493 0 0 # Напряжение на входе AI3 х100, В
A02.22 41494 0 0 # Частота на входе HDI1 х100, КГц
A02.23 41495 0 0 # Уставка ПИД х10, %
A02.24 41496 0 0 # Обратная связь ПИД х10, %
A02.25 41497 0 0 # Выходной сигнал ПИД х100, %
A02.26 41498 0 0 # Коэффициент мощности х10, %
A02.27 41499 0 0 # Время работы, мин.
A02.28 41500 0 0 # Шаг работы ПЛК
A02.29 41501 0 0 # Выходной сигнал регулятора ASR х10, %
A02.30 41502 0 0 # Напряжение на выходе A01 х100, В
A02.31 41503 0 0 # Напряжение на выходе A02 х100, В
A02.32 41504 0 0 # Ток ПЧ х10, А
A02.33 41505 0 0 # Момент х10
A02.34 41506 0 0 # Счетчик перегрузок двигателя
A02.35 41507 0 0 # Зарезервировано
A02.36 41508 1 0 # Текущий выбор двигателя
A02.00 41472 0 1 # Заданная частота х100, Гц
A02.01 41473 0 1 # Выходная частота х100, Гц
A02.02 41474 0 1 # Опорная частота разгона х100, Гц
A02.03 41475 0 1 # Выходное напряжение, В
A02.04 41476 0 1 # Выходной ток х10, А
A02.05 41477 0 1 # Обороты двигателя, об/мин
A02.06 41478 0 1 # Зарезервировано
A02.07 41479 0 1 # Зарезервировано
A02.08 41480 0 1 # Выходная мощность х10, %
A02.09 41481 0 1 # Выходной момент х10, %
A02.10 41482 0 1 # Оценка частоты двигателя х100, Гц
A02.11 41483 0 1 # Напряжение звена постоянного тока, В
A02.12 41484 0 1 # Состояние дискретных входов
A02.13 41485 0 1 # Состояние дискретных выходов
A02.14 41486 0 1 # Цифровое задание частоты х100, Гц
A02.15 41487 0 1 # Зарезервировано
A02.16 41488 0 1 # Линейная скорость
A02.17 41489 0 1 # Длина импульсов
A02.18 41490 0 1 # Счетчик значения
A02.19 41491 0 1 # Напряжение на входе AI1 х100, В
A02.20 41492 0 1 # Напряжение на входе AI2 х100, В
A02.21 41493 0 1 # Напряжение на входе AI3 х100, В
A02.22 41494 0 1 # Частота на входе HDI1 х100, КГц
A02.23 41495 0 1 # Уставка ПИД х10, %
A02.24 41496 0 1 # Обратная связь ПИД х10, %
A02.25 41497 0 1 # Выходной сигнал ПИД х100, %
A02.26 41498 0 1 # Коэффициент мощности х10, %
A02.27 41499 0 1 # Время работы, мин.
A02.28 41500 0 1 # Шаг работы ПЛК
A02.29 41501 0 1 # Выходной сигнал регулятора ASR х10, %
A02.30 41502 0 1 # Напряжение на выходе A01 х100, В
A02.31 41503 0 1 # Напряжение на выходе A02 х100, В
A02.32 41504 0 1 # Ток ПЧ х10, А
A02.33 41505 0 1 # Момент х10
A02.34 41506 0 1 # Счетчик перегрузок двигателя
A02.35 41507 0 1 # Зарезервировано
A02.36 41508 1 1 # Текущий выбор двигателя
A03.00 41728 0 0 # Тип телеграммы
A03.01 41729 1 0 # Адрес устройства
A03.02 41730 0 0 # Параметр в телеграмме PZD3 (запись в ПЧ - DateOutput, %QW)

View File

@ -21,12 +21,14 @@
#include <usefull_macros.h>
#include "modbus.h"
#include "server.h"
#include "verbose.h"
typedef struct{
int help; // help
int verbose; // verbose level (not used yet)
int slave; // slave ID
int isunix; // Unix-socket
char **dumpcodes; // keycodes to dump into file
char **writeregs; // reg=val to write
char **writecodes; // keycode=val to write
@ -36,6 +38,7 @@ typedef struct{
char *outdic; // output dictionary to save everything read from slave
char *dicfile; // file with dictionary
char *device; // serial device
char *node; // server port or path
int baudrate; // baudrate
double dTdump; // dumping time interval (s)
} parameters;
@ -62,6 +65,8 @@ static sl_option_t cmdlnopts[] = {
{"outdic", NEED_ARG, NULL, 'O', arg_string, APTR(&G.outdic), "output dictionary for full device dump by input dictionary registers"},
{"readr", MULT_PAR, NULL, 'r', arg_int, APTR(&G.readregs), "registers (by address) to read; multiply parameter"},
{"readc", MULT_PAR, NULL, 'R', arg_string, APTR(&G.readcodes), "registers (by keycodes, checked by dictionary) to read; multiply parameter"},
{"node", NEED_ARG, NULL, 'N', arg_string, APTR(&G.node), "node \"IP\", or path (could be \"\\0path\" for anonymous UNIX-socket)"},
{"unixsock", NO_ARGS, NULL, 'U', arg_int, APTR(&G.isunix), "UNIX socket instead of INET"},
end_option
};
@ -111,8 +116,15 @@ int main(int argc, char **argv){
if(G.readregs) dumpregs(G.readregs);
if(G.readcodes) dumpcodes(G.readcodes);
if(G.dumpfile){
if(!setDumpT(G.dTdump)) ERRX("Can't set dumptime %g", G.dTdump);
DBG("dumpfile");
if(!rundump(G.dTdump)) signals(-1);
if(!rundump()) signals(-1);
}
if(G.node){
DBG("Create server");
if(!runserver(G.node, G.isunix)) signals(-1); // this function exits only after server death
}
if(G.dumpfile){
DBG("Done, wait for ctrl+C");
while(1);
}

View File

@ -27,8 +27,10 @@
#include "verbose.h"
static FILE *dumpfile = NULL;
static char *dumpname = NULL;
static dicentry_t *dumppars = NULL;
static int dumpsize = 0;
static double dumpTime = 0.1;
static dicentry_t *dictionary = NULL;
static int dictsize = 0;
@ -167,7 +169,8 @@ int opendumpfile(const char *name){
WARN("Can't open %s", name);
return FALSE;
}
fprintf(dumpfile, "# time,s ");
dumpname = strdup(name);
fprintf(dumpfile, "# time,s ");
for(int i = 0; i < dumpsize; ++i){
fprintf(dumpfile, "%s ", dumppars[i].code);
}
@ -175,6 +178,8 @@ int opendumpfile(const char *name){
return TRUE;
}
char *getdumpname(){ return dumpname;}
void closedumpfile(){
if(dumpfile && !isstopped){
if(!isstopped){
@ -182,6 +187,7 @@ void closedumpfile(){
while(!isstopped);
}
fclose(dumpfile);
FREE(dumpname);
}
}
@ -193,7 +199,7 @@ static void *dumpthread(void *p){
double startT = sl_dtime();
while(!stopdump){
double t0 = sl_dtime();
fprintf(dumpfile, "%6.3g", t0 - startT);
fprintf(dumpfile, "%10.3f ", t0 - startT);
for(int i = 0; i < dumpsize; ++i){
if(!read_entry(&dumppars[i])) fprintf(dumpfile, "---- ");
else fprintf(dumpfile, "%4d ", dumppars[i].value);
@ -205,20 +211,23 @@ static void *dumpthread(void *p){
return NULL;
}
int rundump(double dT){
if(!dumpfile){
WARNX("Open dump file first");
return FALSE;
}
int setDumpT(double dT){
if(dT < 0.){
WARNX("Time interval should be > 0");
return FALSE;
}
dumpTime = dT;
DBG("user give dT: %g", dT);
return TRUE;
}
int rundump(){
if(!dumpfile){
WARNX("Open dump file first");
return FALSE;
}
pthread_t thread;
static double T = 0.;
if(T != dT) T = dT;
DBG("user give dT: %g", T);
if(pthread_create(&thread, NULL, dumpthread, (void*)&T)){
if(pthread_create(&thread, NULL, dumpthread, (void*)&dumpTime)){
WARN("Can't create dumping thread");
return FALSE;
}
@ -237,19 +246,32 @@ void close_modbus(){
// read register and modify entry->reg; return FALSE if failed
int read_entry(dicentry_t *entry){
if(!entry) return FALSE;
if(!entry){
WARNX("NULL instead of entry");
return FALSE;
}
int ret = TRUE;
pthread_mutex_lock(&modbus_mutex);
if(modbus_read_registers(modbus_ctx, entry->reg, 1, &entry->value) < 0) ret = FALSE;
if(modbus_read_registers(modbus_ctx, entry->reg, 1, &entry->value) < 0){
WARNX("Can't read entry by reg %u", entry->reg);
ret = FALSE;
}
pthread_mutex_unlock(&modbus_mutex);
return ret;
}
// write register value; FALSE - if failed or read-only
int write_entry(dicentry_t *entry){
if(!entry || entry->readonly) return FALSE;
if(!entry || entry->readonly){
if(!entry) WARNX("NULL instead of entry");
else WARNX("Can't write readonly entry %u", entry->reg);
return FALSE;
}
int ret = TRUE;
pthread_mutex_lock(&modbus_mutex);
if(modbus_write_register(modbus_ctx, entry->reg, entry->value) < 0) ret = FALSE;
if(modbus_write_register(modbus_ctx, entry->reg, entry->value) < 0){
WARNX("Error writing %u to %u", entry->value, entry->reg);
ret = FALSE;
}
pthread_mutex_unlock(&modbus_mutex);
return ret;
}

View File

@ -30,7 +30,9 @@ typedef struct{
int setdumppars(char **pars);
int opendumpfile(const char *name);
void closedumpfile();
int rundump(double dT);
int setDumpT(double dT);
int rundump();
char *getdumpname();
int opendict(const char *dic);

View File

@ -1,5 +1,7 @@
main.c
modbus.c
modbus.h
server.c
server.h
verbose.c
verbose.h

4
modbus_params/relay.dic Normal file
View File

@ -0,0 +1,4 @@
id 0000 1 0 # relay ID
test1 1 0 0
test2 2 0 0
test3 3 0 0

122
modbus_params/server.c Normal file
View File

@ -0,0 +1,122 @@
/*
* This file is part of the modbus_param project.
* Copyright 2025 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include "server.h"
#include "modbus.h"
static sl_sock_t *s = NULL;
// stop dump and close dump file
static sl_sock_hresult_e closedump(_U_ sl_sock_t *client, _U_ sl_sock_hitem_t *item, _U_ const char *req){
closedumpfile();
return RESULT_OK;
}
// open new dump file
static sl_sock_hresult_e newdump(sl_sock_t *client, _U_ sl_sock_hitem_t *item, const char *req){
char buf[BUFSIZ];
if(!req){ // getter
snprintf(buf, BUFSIZ-1, "%s = %s\n", item->key, getdumpname());
sl_sock_sendstrmessage(client, buf);
return RESULT_SILENCE;
}else{
if(!opendumpfile(req) || !rundump()) return RESULT_FAIL;
}
return RESULT_OK;
}
static sl_sock_hitem_t handlers[] = {
{closedump, "clodump", "stop dump and close current dump file", NULL},
{newdump, "newdump", "open new dump file or get name of current", NULL},
{NULL, NULL, NULL, NULL}
};
// new connections handler (return FALSE to reject client)
static int connected(sl_sock_t *c){
if(c->type == SOCKT_UNIX) LOGMSG("New client fd=%d connected", c->fd);
else LOGMSG("New client fd=%d, IP=%s connected", c->fd, c->IP);
return TRUE;
}
// disconnected handler
static void disconnected(sl_sock_t *c){
if(c->type == SOCKT_UNIX) LOGMSG("Disconnected client fd=%d", c->fd);
else LOGMSG("Disconnected client fd=%d, IP=%s", c->fd, c->IP);
}
static sl_sock_hresult_e defhandler(sl_sock_t *s, const char *str){
if(!s || !str) return RESULT_FAIL;
char key[SL_KEY_LEN], value[SL_VAL_LEN];
int n = sl_get_keyval(str, key, value);
if(n == 0){
WARNX("Can't parse `%s` as reg[=val]", str);
return RESULT_BADKEY;
}
dicentry_t *entry = NULL;
int N;
if(sl_str2i(&N, key)){ // `key` is register number
entry = findentry_by_reg((uint16_t) N);
}else{ // `key` is register name
entry = findentry_by_code(key);
}
if(!entry){
WARNX("Entry %s not found", key);
return RESULT_BADKEY;
}
if(n == 1){ // getter
if(!read_entry(entry)) return RESULT_BADKEY;
snprintf(value, SL_VAL_LEN-1, "%s=%u\n", key, entry->value);
}else{ // setter
if(!sl_str2i(&N, value)){
WARNX("%s isn't a value of register", value);
return RESULT_BADVAL;
}
entry->value = (uint16_t)N;
if(!write_entry(entry)) return RESULT_FAIL;
return RESULT_OK;
}
sl_sock_sendstrmessage(s, value);
return RESULT_SILENCE;
}
int runserver(const char *node, int isunix){
if(!node){
WARNX("Point node");
return FALSE;
}
sl_socktype_e type = (isunix) ? SOCKT_UNIX : SOCKT_NET;
if(s) sl_sock_delete(&s);
s = sl_sock_run_server(type, node, -1, handlers);
if(!s){
WARNX("Can't run server");
return FALSE;
}
sl_sock_connhandler(s, connected);
sl_sock_dischandler(s, disconnected);
sl_sock_defmsghandler(s, defhandler);
while(s && s->connected){
if(!s->rthread){
WARNX("Server handlers thread is dead");
break;
}
}
DBG("Close");
sl_sock_delete(&s);
return TRUE;
}

23
modbus_params/server.h Normal file
View File

@ -0,0 +1,23 @@
/*
* This file is part of the modbus_param project.
* Copyright 2025 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <usefull_macros.h>
int runserver(const char *node, int isunix);