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

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

  1. DIYMan

    DIYMan Guest

    Из того, что оттестировано:

    1. Однозначно работает ESP;
    2. Проверены датчики BH1750, Si7021, DS18B20, DS3231;
    3. Проверена работа с SD;
    4. Протестирован веб-сервер через ESP;
    5. Работает MQTT через ESP и SIM800;
    6. Работает ThingSpeak через ESP и SIM800;
    7. Приём звонков и СМС на SIM800;
    8. Отсыл СМС через SIM800;
    9. Сигналы.

    Что - не тестировано или тестировано рамочно:

    1. Рамочное тестирование RS-485 - общая логика работает, пакеты ходят; с конкретным слейвом, прошитым ядром - не тестировалось;
    2. LoRa - пока не тестировалось вообще, написана только общая логика.

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

    Строго говоря, RS-485 можно протестировать и без MAX-485 - просто соединив два МК перекрёстно по нужным UART. Если кто из интересующихся протестирует - буду только рад. Но, емнип, так я уже тестировал, и там всё было норм.
     
  2. alex_rnd61

    alex_rnd61 Нерд

    485-й могу потестить, у меня полдюжины слейвов. Сейчас как раз его у себя отлаживаю.
     
    DIYMan нравится это.
  3. DIYMan

    DIYMan Guest

    Буду признателен ;) Я сейчас занят отладкой разных юзкейсов с ESP и SIM800 - отвал коннекта, отвал посередине передачи данных и т.п. Зависимостей очень много, например - разные тайминги ответа на команды: если ESP быстро ответит, что не удалось законнектиться, то SIM800 по паспорту может тупить аж 65 секунд. Зато SIM800 всегда в ответе выдаёт ID клиента, для которого ответ. А вот ESP, если его попросить законнектиться клиентов номер 1 к неизвестному адресу - просто тупо выплюнет ERROR в поток, и понять, для какого это клиента ответ - хз. Поэтому приходится делать всё последовательно, шобы не дай бог клиентов не перепутать. А это, в свою очередь, означает, что пока SIM800 тупит несколько десятков секунд при коннекте к битому адресу - она не будет отрабатывать других клиентов.

    Короче, куда ни кинь - везде партизаны :) И в клиентах транспортов приходится учитывать максимальное время ожидания ими ответа от транспорта, и в самих транспортах - отлаживать ещё кучу тонких мест.

    А начиналось всё просто - заметил, что передача на ThingSpeak отвалилась, пока сын смотрел видосы и забил весь канал. Вот так всегда - на идеальном окружении всё сразу взлетает, а в боевых условиях - ещё тестить и тестить :)

    Так что отнеситесь с пониманием, если что ;) Я каждый день чего-то правлю, вот и сейчас - на гитхабе уже лежит поправленная версия, с учётом таймаутов и пр. шелухи. Но это не значит, что там нет нюансов, конечно. Буду добивать, и обязательно добью, т.к. по опыту - стабильность большого проекта отрабатывается только под реальной нагрузкой, когда сотни зависимостей и пр. тонкостей. Именно так, и никак иначе, пмсм.

    Ведь в реале хочется, чтобы всё шевелилось толпой и сразу - и в MQTT-брокер данные пулялись, и на ThingSpeak тоже, и ещё куда, при этом чтобы оставалось время сделать конкретную работу - включить там свет по расписанию или ещё чего. Это я ещё про дисплеи не начинал :) Короче, ещё плыть и плыть.
     
  4. DIYMan

    DIYMan Guest

    @alex_rnd61 - кстати, если желаете - можете присоединиться к проекту: вдруг какие ошибки сами выявите и поправите, или допишете чего нужное - через гитхаб можно это дело объединять ;) Надеюсь, вы увидели главную фишку проекта и понимаете, для чего вся эта возня и хождение по мукам :)
     
  5. alex_rnd61

    alex_rnd61 Нерд

    Вот и я не одну шишку набил :) , поэтому отделил мух от котлет. У меня сенсоры отдельно, исполнительные устройства отдельно, а мастер рулит этим хозяйством и общается с внешним миром. Хотя в минимальном варианте часть функций может взять на себя.
     
    DIYMan нравится это.
  6. DIYMan

    DIYMan Guest

    Ну это известный подход, реализованный в проекте в моей подписи. Собственно, и ядро работает по такому же принципу - можно часть устройств сделать слейвами, и одно - мастером. При этом на слейвах повыключать все ненужные фишки директивами условной компиляции (в файле CoreConfig.h) - и всё ;) Но при этом, опять же - остаётся возможность оставить слейвов "жирными", т.е. чтобы каждый слейв в тот же MQTT-брокер писал, и был привязан к своему каналу на ThingSpeak.

    Так что считайте это расширенной версией того подхода, что вы описали ;) При этом самый главный плюс - это то, что когда ядро отладится - за его функционал можно будет не переживать, он будет одинаков для всех проектов. При этом остаётся возможность для любого устройства написать свою конкретную логику: один швец, другой - жнец, третий - скрипочку пилит, и при этом все основаны на ядре и умеют общаться меж собой, сливая данные своих хранилищ в одну топку. Как-то так.

    Хранилище, кстати - это не сенсоры, это просто данные, которые могут быть показаниями с датчиков, да. Но могут быть вообще любыми, а могут - и отсутствовать (в случае исполнительных устройств). При этом любое устройство кластера может добавить в хранилище любые байты данных, которые мастер сможет анализировать в логике конкретного проекта. Короче, ширше некуда.
     
    alex_rnd61 нравится это.
  7. DIYMan

    DIYMan Guest

    Кстати: в ядре есть концепция сигналов - 80 штук, настраиваются по условиям. Если прикрутить сбор карты сигналов от слейвов на мастер - то получится обмен флагами состояний в рамках кластера, а что конкретно делать с этими флагами - дело логики проекта, использующего ядро. Пока обмена картой сигналов нету, есть просто доступ к сигналам из логики - можно всегда посмотреть, установлен ли сигнал, и по этому признаку выполнить чего-то-там. Тоже полезный уровень абстракции ;)
     
  8. DIYMan

    DIYMan Guest

    Протестировал работу ядра с облачным MQTT-сервисом:

    screen.png

    Как видно - всё ходит отлично, только указал в настройках нужные адреса/пароли/явки - и всё ;)
     
  9. DIYMan

    DIYMan Guest

    Добавил в ядро возможность для веб-сервера подключать динамические обработчики. Например, если хочется, чтобы при запросе http://тут_адрес_esp/test.txt выдавались какие-либо данные, зависящие от логики конкретного проекта - то сделать это очень просто, например, вот так:

    Код (C++):
      // мы можем назначить свои обработчики запросов к веб-серверу, если надо
      #ifdef CORE_ESP_WEB_SERVER
        // для примера - назначим обработчик обращения к файлу test.txt при помощи лямбда-функции
        ESPWebServer.on("test.txt", [](const char* uri, const char* params){

              ESPWebServer.send(
                200,  // код ответа
                "text/plain", // тип контента
                "This is dynamic handler!" // данные контента
                );
         
          });
      #endif
    И всё. В примере показано, как это делать при помощи лямбда-функций, но и обычные функции канают ;)
     
    sys и ИгорьК нравится это.
  10. DIYMan

    DIYMan Guest

    Сутки маслает, отсылая в брокер MQTT и на ThingSpeak - полёт нормальный, т.е. на первый осторожный взгляд - память не течёт, страшных логических ошибок в конечных автоматах - пока не выявлено.
     
  11. DIYMan

    DIYMan Guest

    Результат суточного пинания ThingSpeak через ESP, два графика - рандомное число и кол-во свободной оперативки:

    screen.png
     
  12. alex_rnd61

    alex_rnd61 Нерд

    Загнал всё-таки заразу ... в 328. С первой попытки не пошло, после записи конфига в МК получался облом, правда не всемирный :) С последней версией пошло, сейчас с BH1750 данные читает. Не плохо было бы чтобы конфигуратор тип МК с платы получал, у меня пишет ATmega2560, хотя плату указал PRO_MINI. Ещё на очереди 328PB, там последовательных интерфейсов "каждой твари по паре". И ещё, часики не обязательно иметь в аппаратном виде, можно иметь софтовые или получать время извне.
     
    DIYMan нравится это.
  13. DIYMan

    DIYMan Guest

    Злой вы :) Я ж писал, что изначально это дело - под Mega и Due, ибо возиться в условиях ограниченных ресурсов 328-й - не хочется, от слова "совсем".

    А потому что у меня там только два типа плат возвращается - Due и Mega, конфигуратор уже умеет получать информацию о типе платы, но, поскольку под 328-й не планировалось вот и возвращает Mega, всё просто.

    Поверьте - лучше не возиться с 328-й, ибо - оперативки не хватит ни на что: те же СМС требуют не меньше килобайта свободной (не дай боже придёт длинное, его надо расшифровывать и т.п.). Плюс ESP - тоже требует порядком: ответ от того же ThingSpeak - минимум 450 байт заголовков. Плюс хранилище, настройки, сигналы - короче, ужать-то можно, но смысл?

    Я вот, например, не далее как вчера загнал в ядро поддержку Nextion, всё удобно, можно с ним работать, но: даже такая маленькая тварь - тоже съедает оперативку.

    Ну и последний довод - Mega Mini стоит у китайцев 400 руб, думаю, посильная трата за гораздо больше возможностей.

    И самый последний довод - думаю, через несколько времени и Mega будет неактуальна, именно поэтому делаю с поддержкой Due, с прицелом на будущее - адаптировать и под другие камни, типа STM32 и ESP.

    Ну а 328-я - да, как вариант в минимальной конфигурации и клиент на какой-нибудь шине, но секаса с оптимизацией в этом случае - кучу, а за неё (оптимизацию) - я ещё не брался.

    Да вот как бы нет проблемы сейчас с DS3231, хотя - всегда можно ввести датчик "Аппаратные часики" с типом данных "Дата/время": если интересуетесь - можете попробовать это организовать, там несложно по аналогии ;) Если не к спеху - я подумаю в этом направлении, хотя, ещё раз - вопрос не сильно для меня актуальный, ибо если надо другие типы часиков - всегда можно добавить в хранилище из логики конкретного проекта датчик с пользовательскими данными - и обновлять его, когда хошь ;) И будет он всегда в системе, вне зависимости от того, что прописано в конфиге - и такая возможность есть.

    Теоретически, опять же - можно сделать так, чтобы конфиг не грузился с EEPROM, а грузился из флеша (т.е. был жёстко прописан в скетче), этот код даже был у мну - но я его выпилил в угоду конфигуратору. И да - EEPROM таки лучше юзать внешний на I2C - стоит копейки, поддерживается ядром из коробки, с размером проблем нету ;)
     
  14. alex_rnd61

    alex_rnd61 Нерд

    Ну моя Мега не 400, а раза в два более, с мелочью. Mega Mini такой же огрызок, как и большая. И какой смысл в DUE или STM, если нужны только показания с пары-тройки удалённых датчиков. У меня большинство датчиков I2C + DS18B20, ещё возможно SPI и пару цифровых и аналоговых. А тянуть кучу проводов к одной Меге не мой метод. Конфиг только при отладке будет часто переписываться, а в реале записал и забыл. Так что смысла в внешней памяти нет. Ну а ThingSpeak, СМС и другими делами пусть Мега занимается. В новых Nextion есть свои часики, так что можно время у них брать.
     
    DIYMan нравится это.
  15. DIYMan

    DIYMan Guest

    Не подумайте - я не отговариваю и не настаиваю: 328-я так 328-я :) Просто интересно, что туда вместится и в какой конфигурации? Вангую - там пришлось по-максимуму всё отключать :)

    З.Ы. Щас пойду адаптировать под 328-ю, чтобы начало под неё компилироваться ;) А то я там защит понаставил :)
     
  16. DIYMan

    DIYMan Guest

    Обновил на гитхабе - сделал, чтобы компилировалось и под Atmega 328, но там всё с конфигурацией печально, конечно: у мну удалось скомпилировать только с включенным транспортом RS-485, и датчиками DS18B20, BH1750, Si7021, DHT. Можно в узких пределах комбинировать, но особо не разбежишься.

    Хотя согласен - как тонкий клиент в распределённой системе - имеет право на жизнь: чтобы настраиваться из одного самовара, что называется ;)

    Надо думать над оптимизацией кода, чой-то жирно оно занимает в 328-й :) Хотя и фарша накидано там, конечно, порядком.

    З.Ы. Голова садовая - компилировал в дебаг-режиме :) Так что не всё так плохо :)
     
  17. alex_rnd61

    alex_rnd61 Нерд

    Сейчас включены BH1750, RTC, DIGITALPORT и ANALOGPORT. Занимает чуть более 20кб флеша и 644 озу. В предыдущей версии было более 26кб. При оптимизации можно ещё уменьшить, если слезть с ардуиновских библиотек. Мой вариант с датчиками SI7021, TSL2561, DS18B20, mh-z19 и ModBusRTU занимает чуть более 10кб. флеша и 854 байт озу. Платы под 328 делаю свои, а вот под больших пауков уже тяжело паять. :(
     
    DIYMan нравится это.
  18. DIYMan

    DIYMan Guest

    Здорово ;) Это я так наоптимизировал или вы там чего повыкусывали? Не забывайте #define _DEBUG комментировать, чтобы ненужную шелуху в монитор порта не выводить (хотя, думаю, вы и так в курсе :)).

    Был у мну код свой для Si7021 - с моих датчиков читал исправно, а вот у людей - не всегда :) Хотя вроде делал по даташиту. Поэтому пока оставил библиотеку HTU21D. А всё остальное - ручками, без библиотек. Ну разве что AT24CX сторонняя, но она неактуальна, если внешнюю EEPROM не юзать.

    Сходу посмотрел по оптимизации - с кондачка не сделать, да и за удобства приходится платить: виртуальные методы, VMT - зарраза, кусается по объёму. Но без этого код перестанет быть красивым :)

    З.Ы. Строго говоря, если у мну возникнут потребности в действительно тонких клиентах - можно будет написать отдельные конфигурируемые прошивки для 328-й, правда, без конфигуратора и прочих плюшек. Зато объём будет гоораздо меньше. Но это - дело отдалённого будущего, сейчас главное - нарастить мышцу для Mega и Due :)
     
    Последнее редактирование модератором: 19 фев 2018
  19. alex_rnd61

    alex_rnd61 Нерд

    Кажись нашёл этот глюк. Когда RS485 запрещён, то всё нормально. Если разрешен, то при попытке записи конфига в МК и наступает этот облом. Даже если выбран Serial3 у Serial изменяется скорость, как у 3 и всё. :(
     
    DIYMan нравится это.
  20. DIYMan

    DIYMan Guest

    Ок, пасиб, сейчас посмотрю, что к чему.