Настраиваемое ядро для Arduino

Тема в разделе "Глядите, что я сделал", создана пользователем DIYMan, 20 дек 2017.

  1. DIYMan

    DIYMan Guest

    Посмотрел. Это не глюк, а фича - если компилировать под 328-ю - там один Serial, поэтому:
    Код (C++):
    HardwareSerial* CoreRS485::getMyStream(uint8_t SerialNumber)
    {
    #if (TARGET_BOARD == MEGA_BOARD) || (TARGET_BOARD == DUE_BOARD)
      switch(SerialNumber)
      {
        case 0:
          return &Serial;
        case 1:
          return &Serial1;

        case 2:
          return &Serial2;
        case 3:
          return &Serial3;

        default:
          return NULL;
      }
    #elif TARGET_BOARD == ATMEGA328_BOARD
      return &Serial;
    #elif TARGET_BOARD == ESP_BOARD
      #error "NOT IMPLEMENTED!!!"
    #else
      #error "Unknown target board!"
    #endif      
    }
    Видите, чего возвращается? Указатель на Serial, т.к. ATMEGA328_BOARD будет активна, если компилировать под Uno. Соответственно, в этом случае и наступает трындец. Задумка-то в том, что каждый транспорт на своём аппаратном UART, а у Uno он всего один, Serial - через который с МК уже общается конфигуратор.

    Чо делать будем? Надо думать, как быть в этом случае, однако. Какие будут ваши доказательствапредложения? :D
     
  2. alex_rnd61

    alex_rnd61 Нерд

    Я уже прикупил 328PB, думаю на них переползать, там два аппаратных. А в данном случае наверное просто отдать порт 485, для других целей он не нужен. Но если даже изменяется скорость, почему затык с конфигуратором получается, даже если меняю скорость в нём, МК перегружается и уже не отвечает.
     
  3. DIYMan

    DIYMan Guest

    @alex_rnd61 - обновил на гитхабе, принудительно запрещаю юзать Serial всем транспортам, что бы там не выбиралось/подо что бы ни компилировалось. Но проблема с одним Serial для 328-й - остаётся, т.к. этот порт - для общения с конфигуратором, а там сделано, чтобы Serial нельзя было выбрать ни для одного транспорта.

    Потому что фича в прошивке, я её пофиксил, попробуйте. Я же говорю - под 328-й не проверял, ибо не заточен изначально под это дело проект, надо много нюансов учесть ;)
    Тогда конфигуратор побоку, и вы с него ничего не сможете в МК загрузить. Вернее - сейчас должны смочь, но RS-485 не будет работать, от слова "совсем".

    Можно в случае с одним UART делать SoftwareSerial, конечно - но там скорости печальные, до 9600 максимум. А давать в конфигураторе выбирать для транспорта Serial - тоже не алё, т.к. конфигуратор общается именно через него.

    Можно подумать в следующем направлении: если есть инфа, что в данной сессии общаемся через конфигуратор, то все транспорты, которые привязаны к Serial - молчат до перезагрузки контроллера. Фактом общения с конфигуратором может служить наличие запроса какой-либо команды по UART. Такой вариант - прокатит? Тогда всё вроде должно работать прозрачно: если что привязано к Serial - оно будет молчать до тех пор, пока ядро общается с конфигуратором.

    Короче, надо думать - дело тонкое, с этим Serial.
     
  4. alex_rnd61

    alex_rnd61 Нерд

    Может быть при выборе UNO автоматом отключать все транспорты, кроме 485? На них ресурсов всё равно не хватит. А уже при выборе 328PB предоставить возможность выбрать некоторые транспорты, с небольшим потреблением ресурсов. А с конфигуратором можно и через переходник USB-RS485 общаться, завтра попробую. Блин ... сегодня :) Усё - в койку!
     
  5. DIYMan

    DIYMan Guest

    Ограничиваемся в настройках. А вдруг кому RS-485 не нужон, а вместо этого - надо ESP? Я сейчас думаю, как обойти это дело, чтоби при общении с конфигуратором транспорты, юзающие Serial - не чухались, но там много тонкостей, например: при старте ядро выдаёт в Serial информацию, что ядро загружено, это надо для конфигуратора. И если эта инфа уйдёт ESP или по RS-485 - может случиться вава :D Потом - надо вводить дополнительные флаги всякие в транспорты, чтобы понимать, что надо переинициализировать Serial, если конфигуратор не подцеплен.

    Короче, задали вы мне задачку, будь она неладна :)
     
  6. DIYMan

    DIYMan Guest

    Подумал, и пока решил оставить как есть, т.е. не давать возможность выбирать Serial в настройках. Ибо горячку спороть - я всегда успею, а вот поразмыслить, как грамотно обойти всякие тонкости - надо, считаю ;) Так что пока буду думать.
     
  7. alex_rnd61

    alex_rnd61 Нерд

    А если при старте МК сделать небольшую задержку и в это время слушать порт, если пришел запрос от конфигуратора, тогда переключиться на него. Иначе загрузить настройки из конфига. А после установки всех параметров, если конфиг уже не нужен, сделать сброс и не трогать МК. Конфигуратор нужен только для настройки и отладки. Я сейчас свои слейвы настраиваю через Qmodbus, и какая им разница кто с ними говорит. Получили команду - выполннили. С ESP тоже можно общаться по зтому протоколу. Только если к конфигуратору подключается МК мастер он должен переключиться в режим слейва.
     
  8. DIYMan

    DIYMan Guest

    Думал в этом направлении, но не хочется искуственных задержек. Я пока не решил, что буду делать. Тут спешить низзя ;)
     
  9. alex_rnd61

    alex_rnd61 Нерд

    Если перевести конфигуратор и МК на ModBusRTU протокол, то и менять тогда много не придётся. Если есть драйвера , будет RS485, если нет будет обычный Serial. С ESP тоже можно на него перейти, будет стандарт и её тоже можно будет через конфигуратор настраивать.
     
  10. DIYMan

    DIYMan Guest

    Нет в планах, меня интересует только MQTT ;)
     
  11. DIYMan

    DIYMan Guest

    @alex_rnd61 - всё думаю над проблемой неоднозначности, когда есть всего один Serial. Что если сделать проще - переключатель на плате, и когда он в одном положении - плата не общается по Serial с внешним миром, оставляя его под транспорты? Понятно, что костыль, но в этом случае вообще никаких неоднозначностей, типа "ждём 5 секунд, и если не поступило ни одной команды из Serial - освобождаем его для транспортов". Прошу понять правильно - там кучу нюансов, типа той же команды перезагрузки ядра при выгрузке в него конфига - много чего рестартуется и т.п., просто так отвязать Serial - сходу не получится легко.
     
  12. alex_rnd61

    alex_rnd61 Нерд

    Может особо не мучиться и смотреть вперёд, в плане 328PB. А на тех, где один, использовать софт Serial, только не тот что в комплекте, а AltSoftSerial. Этот работает лучше, у меня на нём датчик CO2 сидит. Хотя у тех же ARMов есть отдельный пин для загрузчика, как вариант выделить один пин с кнопкой и задержек не надо. При запуске, если кнопка нажата, общаемся с конфигуратором.
     
  13. DIYMan

    DIYMan Guest

    Ок, будем думать. Надеюсь, решение придёт само, после определённой выдержки по времени - всё должно отлежаться, как известно :)
     
  14. alex_rnd61

    alex_rnd61 Нерд

    Главное шоб не заржавело :) А пока добью альтернативный конфигуратор на Nextion.
     
    DIYMan нравится это.
  15. DIYMan

    DIYMan Guest

    Обновил ядро, добавил возможность юзать Serial в транспортах. Софт обновился, там можно теперь выбирать Serial. Принцип простой - если в течение времени CORE_RELEASE_SERIAL_DELAY (в настройках) приходит хоть одна команда в Serial - считаем, что общаемся с конфигуратором, иначе - рестартуем транспорты, завязанные на Serial.

    Получилось забавно - настроил ESP на Serial, и при рестарте без конфигуратора, с монитора порта теперь можно общаться с ESP, пиша в Serial всякие ответы на запрошенные ESP команды.

    Так что можно пробовать. Однако - тут есть одна тонкость: обработчик неизвестных команд, который плюёт в ответ ER=UNKNOWN_COMMAND. Если представить ситуацию с клиентским модулем на RS-485, на примере: модуль включился в сеть, и ждёт 5 секунд, прежде чем переинициализировать RS-485. При этом Serial пока захвачен ядром (ждёт команды от конфигуратора), и на любые входящие данные, если там есть перевод строки - в Serial будет выплюнуто ER=UNKNOWN_COMMAND. Впрочем, при грамотном проектировании работы с шиной проблем быть не должно, но - надо тестировать, конечно ;)

    Я сейчас пока сделал так: ответ идёт только на команды, начинающиеся с GET= или SET=, всё остальное - тупо проглатывается.

    И да, самое важное: при включённом _DEBUG в Serial продолжают пуляться данные, поэтому, если уж RS-485 или другой транспорт прикреплён к Serial - надо отключать отладочный режим, а то будет каша, т.к. у каждого транспорта своя логика работы с UART ;)

    Пробуйте, теперь, теоретически, можно и Uno клиентом системы сделать ;)
     
    ИгорьК и alex_rnd61 нравится это.
  16. alex_rnd61

    alex_rnd61 Нерд

    До ESP ещё не добрался, если правильно понял, там всё через AT-команды. Больше интересен RS-485, но тут с протоколом пока не разобрался. И тут ещё ручки шаловливые всё время к PB-шке подбираются, запарился их отбивать :)
     
  17. DIYMan

    DIYMan Guest

    Да, с ESP общение идёт по AT-командам, также как и с SIM800. С RS-485 - там реализована логика обмена хранилищем только - от слейвов к мастеру по запросу от мастера. Т.е. если слейвы включены в сеть - на мастере появятся данные с их хранилищ, т.е. централизованно в одном месте соберутся. Далее уже, в зависимости от настроек - они могут мастером автоматом публиковаться в MQTT-брокер, например. В этом и была задумка - рутинную работу сделать сразу.

    Если же надо по своим протоколам по RS-485 общаться - то можно выключить логику ядра при работе с RS-485. При этом ничего не будет происходить, а глобальный объект RS485 будет предоставлять методы для работы с шиной:
    Код (C++):

    // возвращает UART, используемый для RS-485
    HardwareSerial* getSerial();
    void sendData(uint8_t* data, uint8_t dataSize); // отправляет данные в шину: переключается на передачу, посылает данные, после отсыла - переключается на приём
        void switchToReceive(); // переключается на приём
        void switchToSend(); // переключается на передачу
        void waitTransmitComplete(); //ждёт окончания передачи
    Т.е. в этом случае из логики конкретного проекта можно делать с ним, что хошь - читать/писать, используя методы, предоставленные объектом RS485. При этом не парясь, на какой там номер пина настроено переключение приёмом/передачей MAX485 и т.п.

    Теоретиццки было бы неплохо давать возможность из логики добавлять свои типы пакетов для RS-485 - но там всё не так прозрачно, т.к. в этом случае хотелось бы сохранить и обмен данными хранилищ.
     
  18. DIYMan

    DIYMan Guest

    @alex_rnd61, смотрите, какая фишка с RS-485 - у меня там пакеты фиксированной длины, по 30 байт - для любого транспорта. Я могу добавить ещё тип пакета - пользовательский пакет, полезной информации там будет 23 байта максимум. Если такое устроит - можно расширить функционал RS-485, а в логике, при необходимости, склеивать данные в кучу. При этом будут события типа "получен пакет с пользовательскими данными", и метод "отправить пакет с пользовательскими данными".

    Ы?
     
  19. alex_rnd61

    alex_rnd61 Нерд

    Я сейчас использую реализацию ModBusRTU с функциями 3, 6 и 16(пока использую 3 и6). Длина пакета в функции 6 фиксированная. У 16 скорее всего пока тоже будет фиксирована, пока предполагается передача времени слейвам. А вот 3 будет зависеть от кол-ва датчиков и кол-ва байт в данных. А при жесткой фиксации длины будет зря расходоваться время CPU. Тем более что присутствуют два устройства с непредсказуемым поведением( GSM модем и Nextion).
     
  20. DIYMan

    DIYMan Guest

    Ну как бы в любом случае внутреннюю логику обмена хранилищами по RS-485 всегда можно отключить, и юзать какие хошь пакеты из логики конкретного проекта ;) В этом смысле считаем, что объект RS85 просто предоставляет минимальную обвязку и уже настроен на нужный UART через конфигуратор, и всё. Я ж не хочу и сам себя загонять в жёсткие рамки - мало ли, что там в конкретном проекте потребуется ;) Именно поэтому пока реализовал только простейший набор пакетов - получение инфы по хранилищу у слейва по запросу мастера, и всё - ибо даже с этим пока неясно, насколько применимо и архитектурно правильно организовано ;)