Разговоры на технические темы

Тема в разделе "Флудилка", создана пользователем Igor68, 1 апр 2021.

  1. parovoZZ

    parovoZZ Гуру

    Видосов много, но в одном он очень сильно удивлялся тому, что при изменении диэлектрической проницаемости среды в ближнем поле уходит частота резонанса антенны. Так себе специалист.
     
  2. Airbus

    Airbus Радиохулиган Модератор

    Ну ты то конечно круче его в разы! Или даже на два порядка
     
  3. parovoZZ

    parovoZZ Гуру

    2-3 это как-то не серьезно. Бери сразу 10
     
  4. Рокки1945

    Рокки1945 Гуру

    Пускай сначала нолик маленький нарисует в соседней ветке - там люди просят.
     
  5. Airbus

    Airbus Радиохулиган Модератор

    Видимо анотацию в самом начале? Ибо не писал бы о сферических конях потому как у Ротхамеля хорошо описывается как работают антенны на UHF
     
  6. Airbus

    Airbus Радиохулиган Модератор

    Дак ясен пень! Где Звер и где ты
     
    Рокки1945 нравится это.
  7. parovoZZ

    parovoZZ Гуру

    Мы говорим про конкретную антенну - штырь.
     
  8. Un_ka

    Un_ka Гуру

    То то есть 10 порядков= 10^10.
     
  9. SergeiL

    SergeiL Оракул Модератор

    Было скучно, грустно, тоскливо :( ...
    Захотелось деятельности...

    Давно хотел убрать костыли со старых термостатов 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() на время передачи байтов из буфера передачи. У меня на слэйве нет блокировок, все по прерываниям.

    Так как?
    Может кто делал мастера без блокировок? Посоветуйте наработки, библиотеки.
     
  10. SergeiL

    SergeiL Оракул Модератор

    Дошли руки, запаял переходник 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(). И как бы все...

    А прерывание на пием то не запрещаются на время переключения и передачи :mad:
    Добавил в 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 СЕК...
    Нужно либо переделывать, либо искать что то другое.
     
  11. Igor68

    Igor68 Гуру

    Доброго времени суток, братцы!
    Вопрос собственно про MySQL сервер на Debian. Всё работает и вопросы основные решены... но вот надо стало управлять объектом и снимать с него текущие параметры. Уточняю: решил сделать таблицу, через которую будет управление и сбор данных. Таблица не переменной длины, а с фиксированным количеством записей... ну типа того что данные переписываются с интервалом от 1 до 10 сек. А сотрудник будет доставать данные с нужной ему частотой и класть команды обращаясь как к серверу MySQL с помощью своей программы. Моя программа только по Modbus RTU общается с объектом и с базой на MySQL.
    Вот и вопрос : могу ли часто обращаться к записям в таблице, т.е. нет подводных камней со стороны MySQL? Уж больно не хочется лепить опять свой сервер обмена.

    ЗЫ: система работает давно как сервер управления, а сейчас объект пополнился новым оборудованием и требуются изменения. Ранее с сотрудником делали систему... я делал сервер управления, он соединялся с ним и клал в свою базу и через мой сервер менял задания и т.п. Вот и хочу применить MySQL (с другого оборудования уже давно собираю данные в свою базу). А можно часто перезаписывать таблицу?

    ЗЫ: я с базами не очень, вот бы хорошо если бы было в буфере а не на диске.

    Спасибо!
     
    Последнее редактирование: 29 мар 2022
  12. Un_ka

    Un_ka Гуру

    Вроде как, да.
    Попробуйте задать вопрос с соответствующими тегами на habr q&a и linux форуме, но не факт, что и там знают ответ. Не забудьте указать версию MySQL и Debian.
    Кстати аккаунт набравший наибольшее количество очков на stakoverflow как раз по СУБД давал ответы.
     
  13. Igor68

    Igor68 Гуру

    Спасибо, что откликнулись! К сожалению меня на хабре нет... но он мне знаком.
    Код (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 и то же в локалке. Вот:
    Screenshot 2022-03-30 at 08-10-06 Процессы плавок.png
    ну и не хочу ломать готовое... в смысле MySQL, которая будет применяться для другого.
     
    Последнее редактирование: 30 мар 2022
  14. Un_ka

    Un_ka Гуру

    Для хранения данных типа значение — время должна лучше подойти БД времянных рядов.
     
  15. Igor68

    Igor68 Гуру

    Эта показанная БД нормальная, в смысле окончена и работает 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
    -----------------------
    это не весь список параметров.
     
    Последнее редактирование: 30 мар 2022
  16. Un_ka

    Un_ka Гуру

  17. Igor68

    Igor68 Гуру

  18. Igor68

    Igor68 Гуру

    Реализовал команду 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
    ---дверь открыта
    ---управление местное
    ---станция не исправна
    ---нет обрыва измерительных цепей
    ---включены резервные модули
    ---дистанционная крманда: ВЫКЛ.
    ---основное питание
    ---есть питание
     
     
  19. Igor68

    Igor68 Гуру

    Доброго времени суток!
    Вопрос: имеется время в int64 в данных MySQL, занесённое туда программой на Си:
    Код (C++):
    t = time(NULL);
    а вэб страница своим кодом на JS получает это значение из MySQL и надо получить дату и время в виде строки в JS

    ЗЫ: Искал, а смог найти только обратную функцию... ну и примеры конечно.

    Спасибо!
     
  20. Andrey12

    Andrey12 Гик

    https://stackoverflow.com/questions/847185/convert-a-unix-timestamp-to-time-in-javascript

    Оно или я что то не так понял? В int64 хранится Unix datetime?
     
    Igor68 нравится это.