Видосов много, но в одном он очень сильно удивлялся тому, что при изменении диэлектрической проницаемости среды в ближнем поле уходит частота резонанса антенны. Так себе специалист.
Видимо анотацию в самом начале? Ибо не писал бы о сферических конях потому как у Ротхамеля хорошо описывается как работают антенны на UHF
Было скучно, грустно, тоскливо ... Захотелось деятельности... Давно хотел убрать костыли со старых термостатов 2007-го года в виде самописанного протокола связи по RS485, и завести устройства через шлюз MODBUS RTU <-> MQTT на OpenHAB. (Устройства у меня на даче, и на даче у родителей жены) Заодно убрать все прямые подключения MODBUS устройств на OpenHAB (дома, два IN/OUT устройства). Иначе в логах OpenHAB фиксируется каждый запрос на MODBUS устройства. Логи отключены, чтобы не засирать флэш, но нужно, наверное, на mqtt все перевести. Для отладки поменял в прототипе термостата, Мегу8 на Мегу 328П, иначе не хватало места во Flash под MODBUS RTU. Драйвер ADM485 там стоял с самого начала, прототип без удаленного управления работал у родителей жены на даче с 2007-го года без единого сбоя. Добавил в прототип обмен по MODBUS RTU. Подключил прототип к ноуту с Modbus Pull. Подключил опрос 3-х функций Fn= 01,03,04. Всего пока опрос 15 регистров, включая coils. Спойлер: Это меню локальной настройки Код (C++): #define KEY_1 0 #define KEY_2 1 #define KEY_3 2 #define KEY_4 3 void (*MMFTab[4][2])(void)= { {Key_1_1, Key_1_2}, {Key_2_1, Key_2_2}, {Key_3_1, NULL}, {Key_4_1, Key_4_2} }; void SetContrast(void) { OCR1AL=(Contrast*5)+155; } void SetBacklight(void) { OCR1BL =((21-LED)*12)+3; } void SetTime(void) { TempMinVal=125; TempMaxVal=-55; } void SetTimeMin(void) { CurTime.Sec=0; SetTime(); } typedef struct _menuItem { char flash * itemText; signed char * Cur_Val; signed char Esc_Val; signed char Min_Val; signed char Max_Val; signed char * eep_addr; void (*itemFunction)(void); } MenuItem; static flash char _Contrast_str[] = "Contrast", _Backlight_str[] = "LED Ligh", _Gisteresis_str[] = "Gisteres", _NetAddr_str[] = "Net Addr", _AntiFrTemp_str[] = "AF Temp.", _TempCorr_str[] = "TempCorr", _AntiFrOnOff_str[] = " A.F.On ", _KeyBeepOnOff_str[] = "Key Beep", _AutoDimOnOff_str[] = "Auto Dim", _Date_Year_str[] = " Year ", _Date_Month_str[] = " Month ", _Date_Day_str[] = " Day ", _Time_Hour_str[] = " Hour ", _Time_Min_str[] = " Minute " ; MenuItem MenuItems[] = { {_Contrast_str, &Contrast, 0, 0, 20, &eep_Contrast, &SetContrast}, {_Backlight_str, &LED, 0, 0, 20, &eep_LED, &SetBacklight}, {_Gisteresis_str, &Gister, 0, 0, 10, &eep_Gister, NULL}, {_NetAddr_str, &NetAddr, 0, 1, 99, &eep_NetAddr, NULL}, {_AntiFrTemp_str, &AntiFrTemp, 0, 0, 20, &eep_AntiFrTemp, NULL}, {_TempCorr_str, &TempCorr, 0,-5, 5, &eep_TempCorr, NULL}, {_AntiFrOnOff_str, &AntiFrOnOff, 0, 0, 1, &eep_AntiFrOnOff, NULL}, {_KeyBeepOnOff_str, &KeyBeepOnOff, 0, 0, 1, &eep_KeyBeepOnOff, NULL}, {_AutoDimOnOff_str, &AutoDimOnOff, 0, 0, 1, &eep_AutoDimOnOff, NULL}, {_Date_Year_str, &CurTime.Year, 0, 0, 99, NULL, &SetTime}, {_Date_Month_str, &CurTime.Month, 0, 1, 12, NULL, &SetTime}, {_Date_Day_str, &CurTime.Day, 0, 1, 31, NULL, &SetTime}, {_Time_Hour_str, &CurTime.Hour, 0, 0, 23, NULL, &SetTime}, {_Time_Min_str, &CurTime.Min, 0, 0, 59, NULL, &SetTimeMin}, }; MenuItem *_mptr = MenuItems; void MainMenuProcess(char key) { unsigned char num=Key_Mode[key]; void (*function)(void); ChangeDataFlag |= CHG_MENUMODE; function=MMFTab[key][num-1]; if (*function) (*function)(); } void MenuProcess(char key) { ChangeDataFlag |= CHG_MENUMODE; switch (key) { case KEY_1: // Key 1 presed if(_mptr_choiced) { *(_mptr->Cur_Val) = _mptr->Esc_Val; if(_mptr->itemFunction) (*_mptr->itemFunction)(); _mptr_choiced = NULL; } else if (SubMenu_choiced) { MenuClose(); } break; case KEY_2: // Key 2 presed if(_mptr_choiced) { if (_mptr->itemFunction) (*_mptr->itemFunction)(); if (_mptr->eep_addr) EEPROM_WRITE((int)(_mptr->eep_addr), *(_mptr->Cur_Val)); _mptr_choiced = NULL; } else if (SubMenu_choiced) { _mptr_choiced = _mptr; _mptr->Esc_Val= *(_mptr->Cur_Val); } break; case KEY_3: // Key 2 presed (+) if(_mptr_choiced) { if (*(_mptr->Cur_Val) < _mptr->Max_Val) { (*(_mptr->Cur_Val))++; if(_mptr->itemFunction) (*_mptr->itemFunction)(); } } else if (SubMenu_choiced) { if (--_mptr < MenuItems) _mptr = &MenuItems[(sizeof MenuItems)/(sizeof (struct _menuItem)) - 1]; } break; case KEY_4: // Key 2 presed (-) if(_mptr_choiced) { if (*(_mptr->Cur_Val) > _mptr->Min_Val) { (*(_mptr->Cur_Val))--; if(_mptr->itemFunction) (*_mptr->itemFunction)(); } } else if (SubMenu_choiced) { // ïåðåõîäèì íà ñëåäóþùèé ïóíêò ìåíþ if (++_mptr > &MenuItems[(sizeof MenuItems)/(sizeof (struct _menuItem)) - 1]) // åñëè ïîñëåäíèé _mptr = MenuItems; // òî ïåðåõîäèì íà ïåðâûé } break; } } К этим переменным и функциям прикручены данные MODBUS. Регистры (значения переменных) на прототипе удаленно можно поменять по Fn=0x05, 0x06, 0x0F, 0x10. Сделал широковещательное обновление регистров (Если указан адрес 00 - то получают все контроллеры в сети и выполняют, без ответа мастеру) Таким образом синхронизируется время. Пока все работает. Норм. Все самописное, на Си без Ардуино. Все написано на Си в 2007-ом, модбас добавлен сейчас. Работает. Теперь хочу сделать два "мастер" устройства для связи этих подсетей с OpenHAB по MQTT. СМС надоели, нет возможности мониторить в реалтайме, для мониторинга поставил Wemos c ESP8266 и DS18D20. Думаю первое буду делать на Меге2560+Ethernet Shield от Амперки под Ардуино, так как нужен Ethernet и MQTT (PubSubClient - проверен). Второе устройство хочу делать на ESP + RS485 на SP3485. Вопрос, использовать HardwareSerial1 + ModbusMaster или все самому написать? Что не понравилось в HardwareSerial1 + ModbusMaster - это переключение передачи/приема RS485, которое блокирует loop() на время передачи байтов из буфера передачи. У меня на слэйве нет блокировок, все по прерываниям. Так как? Может кто делал мастера без блокировок? Посоветуйте наработки, библиотеки.
Дошли руки, запаял переходник TTL-RS485 на SP3485 подключил к Меге2560 на Serial1. Все это хозяйство подключил параллельно тому, что было подключено на RS485. (A,B,GND) Хозяйство из двух термостатов и USB-RS485, подключенного к компу с поднятым RDP и Modbus Pull. Там же сидит и AVRISP mkII через который заливается код в один из термостатов. Зашел по VPN в домашнюю сетку, подключился по RDP можно что то поделать пока есть время. Дома просто подключился по RDPи можно отлаживаться. Залил в Мегу заранее подготовленный тестовый код Modbus Master c ModbusMaster.h. Вроде все работает, но периодически появляются ошибки ответа 0xE0. RS485 у меня в полудуплексе, переключается прием/передача. RE/DE объединены и посажены на пин Меги. В примерах есть вариант с полудуплексом, вызываются из библиотеки через callback функции. Вот пример: Код (C++): void preTransmission() { digitalWrite(MAX485_RE_NEG, 1); digitalWrite(MAX485_DE, 1); } void postTransmission() { digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0); } void setup() { pinMode(MAX485_RE_NEG, OUTPUT); pinMode(MAX485_DE, OUTPUT); // Init in receive mode digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0); // Modbus communication runs at 9600 baud Serial.begin(9600); // Modbus slave ID 1 node.begin(1, Serial); // Callbacks allow us to configure the RS485 transceiver correctly node.preTransmission(preTransmission); node.postTransmission(postTransmission); } Погонял таймауты, результат - так себе. Ошибки все равно есть Думал уже 120 Ом вешать. Но полез в библиотеку, от туда в serial.h Есть ожидание конца передачи по флагам UDRIE, TXC. Потом отрабатывает postTransmission(). И как бы все... А прерывание на пием то не запрещаются на время переключения и передачи Добавил в preTransmission() / postTransmission() запрещение/разрешение прерывания на прием и все - молотит уже несколько часов без единой ошибки. Код (C++): void preTransmission() { UCSR1B &= ~(1<<RXEN1); // запретим RX interrupt digitalWrite(MAX485_DE_RE, MAX485_TO_SEND ); } void postTransmission() { digitalWrite(MAX485_DE_RE, MAX485_TO_RECEIVE); UCSR1B |= (1<<RXEN1); // разрешим RX interrupt } И вот как??? Но библиотека на попробовать, с блокировкой с момента начала передачи, до получения ответа или окончания таймаута ожидания приема, который 2 СЕК... Нужно либо переделывать, либо искать что то другое.
Доброго времени суток, братцы! Вопрос собственно про MySQL сервер на Debian. Всё работает и вопросы основные решены... но вот надо стало управлять объектом и снимать с него текущие параметры. Уточняю: решил сделать таблицу, через которую будет управление и сбор данных. Таблица не переменной длины, а с фиксированным количеством записей... ну типа того что данные переписываются с интервалом от 1 до 10 сек. А сотрудник будет доставать данные с нужной ему частотой и класть команды обращаясь как к серверу MySQL с помощью своей программы. Моя программа только по Modbus RTU общается с объектом и с базой на MySQL. Вот и вопрос : могу ли часто обращаться к записям в таблице, т.е. нет подводных камней со стороны MySQL? Уж больно не хочется лепить опять свой сервер обмена. ЗЫ: система работает давно как сервер управления, а сейчас объект пополнился новым оборудованием и требуются изменения. Ранее с сотрудником делали систему... я делал сервер управления, он соединялся с ним и клал в свою базу и через мой сервер менял задания и т.п. Вот и хочу применить MySQL (с другого оборудования уже давно собираю данные в свою базу). А можно часто перезаписывать таблицу? ЗЫ: я с базами не очень, вот бы хорошо если бы было в буфере а не на диске. Спасибо!
Вроде как, да. Попробуйте задать вопрос с соответствующими тегами на habr q&a и linux форуме, но не факт, что и там знают ответ. Не забудьте указать версию MySQL и Debian. Кстати аккаунт набравший наибольшее количество очков на stakoverflow как раз по СУБД давал ответы.
Спасибо, что откликнулись! К сожалению меня на хабре нет... но он мне знаком. Код (Text): www-data@debian2:~/coding/SCS2/pksserver$ uname -a Linux debian2 4.9.0-18-686-pae #1 SMP Debian 4.9.303-1 (2022-03-07) i686 GNU/Linux Код (Text): root@debian2:/home/httpd/coding/SCS2/pksserver# mysqld --version mysqld Ver 10.1.48-MariaDB-0+deb9u2 for debian-linux-gnu on i686 (Debian 9.13) ЗЫ: интересует возможность частоты обращения для перезаписи. Раньше применял самодельную программу, данные которой были в файлах в локальной сети, а потом вот решил сделать всё на вебморде с данными в MySQL и то же в локалке. Вот: ну и не хочу ломать готовое... в смысле MySQL, которая будет применяться для другого.
Эта показанная БД нормальная, в смысле окончена и работает 24/7 - там всё автоматом на Си и Баш. К этому серверу надо добавить условную БД из которой совсем другой сервер будет брать данные с программируемым интервалом согласно заданию от нескольких секунд до нескольких часов и класть в свою БД. Мне же надо в неё ложить данные часто, а взаимодействие с объектами уже наладил: Debian <--ethernnet-->Moxa UC7101LX<---Modbus RTU(rs485)--->Объекты. ЗЫ: Беспокоюсь что диск HDD на сервере Debian уйдёт в "точку" если будет перезапись таблиц(ы) на 14 объектов, каждый из которых с толпой параметров. Вот данные одного из объектов: Код (Text): ----------------------- Uc1: 234.1 CntTPower1: 180123 Uc2: 0.00 CntTPower2: 0 TmpSCS: 0 TimeWork: 34209792 TimeShieldO: 7929856 Iout: 29.20 Uout: 11.80 Usp: 0.00 Upp: 0.00 ModeCTL_SCS: 0 ModeCTL_SCS_set: 0 Iset: 35.00 Usetsp: -10.00 Usetpp: 0.00 Usetout: 0.00 ----------------------- Status(HEX): 00 ----------------------- это не весь список параметров.
Реализовал команду UPDATE - полёт пока нормальный... без настроек. И читаю другой программой: Код (Text): ----------------------- Uc1: 235.8 CntTPower1: 180907 Uc2: 0.0 CntTPower2: 0 TmpPKS: 0 TimeWork: 665 TimeShieldO: 265 Iout: 35.5 Uout: 14.0 Usp: 0.0 Upp: 0.0 ModeCTL_SCS: 0 ModeCTL_SCS_set: 0 setIout: 35.0 setUsp: -10.0 setUpp: 0.0 setUout: 0.0 Status(HEX): 0015 ---дверь открыта ---управление местное ---станция не исправна ---нет обрыва измерительных цепей ---включены резервные модули ---дистанционная крманда: ВЫКЛ. ---основное питание ---есть питание
Доброго времени суток! Вопрос: имеется время в int64 в данных MySQL, занесённое туда программой на Си: Код (C++): t = time(NULL); а вэб страница своим кодом на JS получает это значение из MySQL и надо получить дату и время в виде строки в JS ЗЫ: Искал, а смог найти только обратную функцию... ну и примеры конечно. Спасибо!
https://stackoverflow.com/questions/847185/convert-a-unix-timestamp-to-time-in-javascript Оно или я что то не так понял? В int64 хранится Unix datetime?