Форум ModelldepO

Форум ModelldepO (http://forum.modelldepo.ru/index.php)
-   Arduino (http://forum.modelldepo.ru/forumdisplay.php?f=220)
-   -   DCC декодер на Dualino + 8xPCA9685 (http://forum.modelldepo.ru/showthread.php?t=19872)

Eprinter 22.03.2019 03:37

DCC декодер на Dualino + 8xPCA9685
 
Вложений: 6
Прикинул свои потребности на перспективу, получилось до 30 серв и до 100 световых каналов. Естественно, ардуино и шим-драйвер - наше всё: два на стрелки и шесть на свет, если не удастся повесить на один декодер, сделаем два (так думал).

Немного порыл форумы и выбрал за основу эту библиотеку - http://www.mynabay.com/dcc_monitor/
Просидел выходные в попытке переделать скетч примера. Конечно, программист из меня ещё тот, более четырёх одновременно обслуживаемых приводов с плавным переводом не получилось, начинались пропуски команд. Без плавного проблем нет, но это же неинтересно. Задачка оказалась сродни попытке скрестить ужа с ежом: первый должен держать хвост на пульсе, дабы не пропустить нужную команду, но при этом четыре, ну пусть даже восемь иголок - далеко не ёж. Даже не морской...

В воздухе витала идея оставить ужу ужово, а ежу ежово. Услышано - сделано. Неделя свободного времени, и пара "гнедых" были впряжены в одну упряжку:
http://forum.modelldepo.ru/attachmen...1&d=1553264773

Прошу прощения, схема от руки, там всё до безобразия просто: опторазвязка (по ссылке выше), в качестве ужа Ардуино-Про-Мини-168, к ней через последовательный порт подключен ёж Ардуино-Нано-328, на её выход I2C цепляются гирлянды PCA9685. Ах да, ещё для удобства сделал пульт - дисплей 1602 I2C, энкодер и дополнительная кнопка (в скетче подписано, кто куда).

На данный момент у меня один драйвер 9685, остальные в пути, поэтому он отдувался за всех. При отключенном пульте производительности хватает обеспечивать 30 одновременно идущих переключений, если их больше - плавно увеличивается интервал между "шагами" (выбрал 20 мс - частота ШИМа для серв).

Пульт нужен в основном для настройки углов, скорости переключения, реверса, остальные добавлю по мере необходимости. Свои 14 стрелок и один расцепитель настроил, правда пару раз всё зависло, надо оптимизировать код настройки. В работе с КС от МД проверил, всё отлично. Зетку ещё не пробовал.

Да, для облегчения себе жизни остановился на 128 адресах (32х4), идущих подряд, тогда в один байт помещается и адрес, и команда. Мне пока достаточно, а там поглядим. Остальные детали в скетче, он тщательно прокомментирован, если что интересно_&&_!понятно - спрашивайте :)

Так было:
http://forum.modelldepo.ru/attachmen...1&d=1553214605

Так стало:
http://forum.modelldepo.ru/attachmen...1&d=1553214605

Пульт, режим настройки (скорость переключения):
http://forum.modelldepo.ru/attachmen...1&d=1553214605

ПС Забыл указать ресурсные возможности.
Уж заполнен кодом на 25%, данными на 50%, то есть в принципе можно было порыться на моём складбище и приколхозить Мегу8АУ, но 100 рублей не та экономия, ради которой ... :)
Ёж загружен на 32%+60%, еепром наполовину, так что запихнуть в него же дополнительные алгоритмы работы со светом вполне возможно.

http://forum.modelldepo.ru/attachmen...1&d=1553216418

Eprinter 22.03.2019 05:51

Решил немного пояснить алгоритм.

Первый чип загружен библиотекой ДСС, следит за командами. Если приходит из заданного диапазона (0:0 ... 31:3), преобразует к виду 5 старших бит адрес, 3 младших данные (порт и команда), и пропихивает в последовательный порт. Если получено несколько одинаковых команд подряд, обрабатывается только первая.

Второй чип постоянно проверяет буфер, если обнаружена команда - проверяет, не выполняет ли он её уже, и ставит в очередь. Каждые 20 мс запускается обработчик, перебирающий все 128 портов, и если обнаруживается новая или недовыполненная команда, высчитывает и отправляет на нужный драйвер очередной шаг.

Если при включении питания дисплей не был подключен, то медленные операции вывода на ЛСД отключены и в режим настройки зайти нельзя. Если был подключен, то на экран выдаётся последняя принятая в работу команда, для отлавливания багов удобно. В любой момент можно перейти в режим настройки, изменить все доступные параметры для любого порта или нескольких подряд и сохранить в еепром, работа при этом прекращается. Программирование CVs не предусмотрено в принципе, т.к. с пульта оказалось гораздо удобнее.

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

Мой макет имеет размер 1.22х2.44, поэтому подход централизованной обработки команд и раздачи по шине на места считаю более целесообразным, чем на одну шину ДСС вешать десятки декодеров и апгрейдить их все в случае необходимости. Да и по количеству проводов разницы большой нет - и так, и так их немерено :)

Qvan22 22.03.2019 08:53

Цитата:

Сообщение от Eprinter (Сообщение 340417)
На данный момент у меня один драйвер 9685, остальные в пути, поэтому он отдувался за всех. При отключенном пульте производительности хватает обеспечивать 30 одновременно идущих переключений, если их больше - плавно увеличивается интервал между "шагами" (выбрал 20 мс - частота ШИМа для серв).

Есть еще такой нюанс, подумайте, сколько одновременно работающих сервоприводов сможет переварить ваш блок питания/стабилизаторы на 5 вольт /dc-dc преобразователи? Есть вероятность, что в итоге придется программно переводить стрелки небольшими группами по очереди. Мне вообще пришлось сделать так, что в границах одно модуля макета, стрелки переводятся по одной, друг за дружкой...

Eprinter 22.03.2019 10:23

Цитата:

Сообщение от Qvan22 (Сообщение 340421)
сколько одновременно работающих сервоприводов сможет переварить ваш блок питания/стабилизаторы на 5 вольт

Много :)
У меня БП 20В 5А, после него преобразователи дс-дс до 4В. Даже все 30 серв ну пусть 3А одновременно, значит от БП возьмётся немного менее 1А. Освещение ещё в разы меньше.

Другой вопрос, если световые эффекты потребуют бОльших вычислительных ресурсов, чем сервы. Но тогда можно их обрабатывать через одного или даже реже. То есть в принципе всё должно получиться.

ПС Вспомнил интересный нюанс.
Библиотека Adafruit_PWMServoDriver.h поддерживает следующий формат команд управления выходами:
pwm.setPWM(вывод, момент старта импульса ШИМ, момент финиша импульса ШИМ)
Для серв длительность импульса получается около 1/8 от возможной, то есть можно для разных выводов отправлять сигналы со сдвигом, и тогда всплески потребления размажутся. В теории :)

Qvan22 22.03.2019 15:42

Цитата:

Сообщение от Eprinter (Сообщение 340441)
Другой вопрос, если световые эффекты потребуют бОльших вычислительных ресурсов, чем сервы.

Интересно, что вы там такое "очень хитрое" придумали?

Eprinter 22.03.2019 17:06

Да пока ещё не знаю, что будет :)
Скорее всего эффекты типа "сварка", "цветомузыка", и прочая проще делать по месту, на своих контроллерах. Тогда и не надо будет сильно напрягаться с этим. Мне до света ещё далековато, недавно только макет наконец развернул после более чем годового стояния в углу...

Qvan22 22.03.2019 20:15

Цитата:

Сообщение от Eprinter (Сообщение 340474)
Да пока ещё не знаю, что будет
Скорее всего эффекты типа "сварка", "цветомузыка", и прочая проще делать по месту, на своих контроллерах. Тогда и не надо будет сильно напрягаться с этим. Мне до света ещё далековато, недавно только макет наконец развернул после более чем годового стояния в углу...

Да уж, тут фантазия нужна, на ум приходят такие эффекты как разгорание уличного фонаря, перемигивание люминесцентных ламп при включении, периодическое подмигивание лампы накаливания из-за плохого контакта, эффекты сварки, жд переезда, костра, телевизора в доме, зелено/красные лампочки на пульте в "башне"...

Еще, вам стоит обратить внимание на две вещи про шину i2c:
- Во первых частота шины, по умолчанию в библиотеке Wire.h, установлена как "стандартная" и ее можно разогнать/переключить на "быстрый режим".
Скрытый текст

Wire.setClock(clockFrequency);
clockFrequency: значение частоты (в герцах) тактового сигнала. Принимаются значения 100000 (стандартный режим) и 400000 (быстрый режим).

Скорость общения с "быстрыми" i2c устройствами вырастет(PCA9685, oled-i2c экраны), а для медленных(например pcf8574 с lcd экраном) ничего не изменится.

Вашего драйвера у меня нет, но по моим замерам, для передачи UNO 5 байтного сообщения для stm8s, уходит 0.64 мс в стандартном режиме, и 0.22 мс в быстром...

- Во вторых,читал в интернете, на разных i2c модулях установлены подтягивающие резисторы для линиий sda и scl.
И при увеличении количества модулей - эта подтяжка будет параллелиться и ослабевать. Может быть придется выпаивать эти резисторы для работоспособности шины...

Eprinter 23.03.2019 01:18

Спасибо за ценные идеи!

Частоту разгонять в данном случае не нужно по двум причинам:
- резко уменьшится расстояние, читал, что при 1МГц уже на одном метре начинаются ошибки, зависит от ёмкости линии
- 100 кГц вполне достаточно: 30_команд х 30_бит_длина_команды х 50_раз_в_секунду = 45 кГц, это предельная нагрузка

Посмотрел, на этих модулях подтягивающих резисторов нет. Молодцы разработчики, предусмотрели их ж.д. область применения - включение "паровозиком" :)

ПС Впрочем, могу ошибиться насчёт частоты - пишется ведь два байта, так что надо смотреть, включен ли режим многобайтных пакетов. Если да, то 60 кГц, укладываемся. Если нет, то 90 кГц, уже айяйяй...

Alexmit 23.03.2019 10:49

Вложений: 1
Цитата:

Сообщение от Eprinter (Сообщение 340516)
Впрочем, могу ошибиться насчёт частоты - пишется ведь два байта, так что надо смотреть, включен ли режим многобайтных пакетов.

Очень рекомендую: Логический анализатор USB Saleae logic
Вложение 169044
(на картинке чтение из MCP23017)

Eprinter 24.03.2019 02:53

Вложений: 1
Цитата:

Сообщение от Alexmit (Сообщение 340529)
Логический анализатор USB Saleae logic

Есть такой, правда клон китайский, но работает с этой программой прекрасно :)
Всё никак не соберусь опторазвязку на 6N137 спаять, чтоб ДСС вживую смотреть. Давно делал на PC817, быстродействия не хватало, сигнал искажался, а других под рукой не оказалось.



Измерил стрелочным тестером токи. Когда сервы (пока 17 у меня) в покое, потребление на уровне 100 мА. При одновременном переключении не превышает 1 А. Одну случайную серву померял, +30 мА в движении.

ПС Посмотрел сигнал по I2C, идёт два байта двумя командами. Будем экспериментировать с частотой либо последовательной передачей команд.
http://forum.modelldepo.ru/attachmen...1&d=1553395785


И ещё обнаружился баг с оптопарой - после примерно получаса непрерывной работы она сначала начинает мешать в сигнал какой-то мусор, а позже вообще просаживает выход в ноль.
Может ограничительный резистор уменьшить? Везде рисуют 1 кОм, я попробовал вначале, но он грелся как печка, поэтому поставил 3к3.

shalex 24.03.2019 13:41

Вложений: 1
Цитата:

Сообщение от Eprinter (Сообщение 340574)
Везде рисуют 1 кОм, я попробовал вначале, но он грелся как печка, поэтому поставил 3к3



Из практики: 4к7 и греется уже не так сильно. 1к - это совсем мало.

p.s. 3к3 вроде выглядит оптимальным, но если Вы пишете о проблемах, то видимо маловато будет.

---------- Сообщение добавлено в 13:41 ---------- Предыдущие сообщение было в 13:27 ----------

Концентрация каналов очень большая, а в памяти Нано надо хранить тучу настроек. Плюс накладные расходы памяти на диммер с плавной регулировкой, плюс спецэффекты. Может перейти на Мегу, вместо двух Нано? Появились весьма компактные и недорогие Меги, всего раза в 3 больше Нано.

Вложение 169086

Qvan22 24.03.2019 15:14

оффтопик

Eprinter 24.03.2019 15:17

Цитата:

Сообщение от shalex (Сообщение 340586)
Может перейти на Мегу, вместо двух Нано?

Можно и на мегу. Но мне пока хватает нано :)
Еепром занят ровно на половину - 128 адресов по 4 байта настроек, можно смело ещё 3 байта на канал использовать. Оперативка немногим более половины занята, тоже есть куда расти. Память программ только на треть, пиши - не хочу. Будет не хватать - возьму мегу. Или вместо одной нано возьму две, по 64 канала, в режиме чтения они могут вдвоём с одного сериал-порта команды получать. Один будет чисто под сервы, второй под свет, красота :)

Вы возможно не до конца поняли основную фишку этого декодера. Главная причина использования двух чипов - разделение разных типов задач. Первый камень спокойно следит за непрерывным потоком команд, отлавливая нужные и отсылая по аппаратному последовательному порту. Второй спокойно, в асинхронном режиме, обрабатывает полученные команды. Никаких конфликтов прерываний, никаких ошибок со стеком, не нужно бороться за каждый процессорный такт. Программы простые и понятные, не смотря на то, что этот декодер практически заменяет 32 обычных 4-х канальных.



Насчёт оптопары у меня какой-то глюк в монтаже, ещё не разобрался, времени пока нет. На сборной макетке с таким же резистором работает часами. Меняю оптопары местами - глюк остаётся. Спиртом плату мыл, не помогло. Распаяю всё и соберу заново.


Цитата:

Сообщение от Qvan22 (Сообщение 340594)
первый байт адрес устройства на шине + 5 байт сообщение

А, ну да, там же два двубайтных значения уходит - старт и стоп импульса ШИМ. Плюс адрес.

shalex 24.03.2019 20:13

Цитата:

Сообщение от Eprinter (Сообщение 340595)
Вы возможно не до конца поняли основную фишку этого декодера.

Почему не понимаю, сам подобные декодеры делаю.

Alexmit 24.03.2019 20:59

Цитата:

Сообщение от shalex (Сообщение 340598)
Почему не понимаю, сам подобные декодеры делаю.

Александр, если бы у тебя так же стояли две ардуины, на одной бы крутился локонет, а на другой управление PCA9685.
Вот тогда были бы подобные.

shalex 24.03.2019 21:43

Цитата:

Сообщение от Alexmit (Сообщение 340603)
Александр, если бы у тебя так же стояли две ардуины, на одной бы крутился локонет, а на другой управление PCA9685.
Вот тогда были бы подобные.

Просто не вижу особого смысла в двух ардуинах. Проще еще один декодер поставить поблизости и не тянуть провода через весь макет.

Кстати, хорошо бы в протокол обмена ардуин добавить подтверждение приема команды. А еще вынести обмен по порту из обработки DCC-события, сделать стек DCC-команд и т.д.

И самое главное - освободить штатные последовательные порты, чтобы можно было нормально отлаживать код.

Alexmit 24.03.2019 22:11

Цитата:

Сообщение от shalex (Сообщение 340608)
Просто не вижу особого смысла в двух ардуинах.

Однако сейчас появилась такая тенденция.
Особенно там, где реально не хватает скорости на две задачи.
Как пример: https://wiki.rocrail.net/doku.php?id...n-gbm-strom-de

Так же могу напомнить #60
Там тоже несколько ардуин получается, только интерфейс обмена другой.

shalex 24.03.2019 22:29

Цитата:

Сообщение от Qvan22 (Сообщение 340594)
Там dcc библиотека обрабатывает свои функции в главном цикле и чуть что, пойдут потери пакетов.
А вот вторую нано, может и имеет смысл прокачать до меги/есп/стм32...

Да, и каналов при этом туча. И все равно, можно попробовать одной ардуиной обойтись, может быть на 64 канала оставить.
К сожалению ускорение работы требует памяти на всякие кеши и буферы.

Вот например, для первой ардуины можно добавить массив на 4 шт unsigned long (итого 16 байт) и сохранять там последний direction для каждой стрелки в виде бита. И не отсылать лишний раз команду на вторую ардуину, если новый direction стрелки совпадает со старым. И трафик в шине ардуина-ардуина упадет почти до 0. Но это 16 байт, почти 1% памяти. Последовательный порт между ардуинами реализовать софтовым способом, хватит и умеренных скоростей, особенно если переложить спец.эффекты на вторую ардуину.

Кстати, этот же механизм может заменить текущий, который на проверку дублирования.

shalex 24.03.2019 23:01

Другой пример - диапазон скорости изменения PWM, например, для сервы. Столкнулся с тем, что надо очень плавно двигать сервой (ворота депо), и переменная типа "байт" не давала плавности движения. Пришлось увеличивать в два раза тип переменной. Допустим было 128 байт (серв), а стало 256. Было 6.25%, а стало 12.5% памяти. При условии, что серв 128.

Надеюсь топикстартер учтет мою критику, т.к. старался быть макс.конструктивным. Сам на эти грабли наступал и теперь периодически нахожу их в чужом коде.

Alexmit 25.03.2019 00:40

Цитата:

Сообщение от shalex (Сообщение 340612)
Последовательный порт между ардуинами реализовать софтовым способом,

И похерить всё то, ради чего делалось разделение на два контроллера.

Eprinter 25.03.2019 00:53

Вложений: 1
Цитата:

Сообщение от Alexmit (Сообщение 340610)
Однако сейчас появилась такая тенденция.

О, спасибо за ссылку, сам не наталкивался на двухпроцессорную реализацию в нашем деле. Значит в самом деле уловил идею, витающую в воздухе :)
Да, это реально более простой путь, ведь стоимость дополнительной платы - копейки по отношению к многим часам отладки сложного кода.


Цитата:

Сообщение от shalex (Сообщение 340613)
переменная типа "байт" не давала плавности движения.

Согласен, в каких-то случаях будет мало предусмотренных возможностей. Но этих случаев - единицы. Считаю более целесообразным реализовать для каждого свой узко заточенный декодер, а для основной массы оставить простой, но на много каналов, в сумме это даст бОльшую экономию и средств, и времени.

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

Кстати, для ворот депо я как раз использую освободившийся СервоМоушен :)
ПС Впрочем, глупость сморозил... Там ведь те же 255 шагов. Для плавных движений правильнее использовать аналоговые привода с конечниками, например вот такой движок с планетарным редуктором:
http://forum.modelldepo.ru/attachmen...1&d=1553470748
Рассчитан для работы от 24В, но прекрасно крутится и от меньшего. Например при 6В делает один оборот за 30-40 секунд. Ток при этом 20мА. Потребует своего декодера, но зато ради одного его не нужно будет усложнять все остальные :)
ПСПС Впрочем, и декодер свой не понадобится, достаточно драйвера, следящего за конечными выключателями, а управлять сигналами 1 и 0.

Цитата:

Сообщение от shalex (Сообщение 340608)
И самое главное - освободить штатные последовательные порты, чтобы можно было нормально отлаживать код.

Нет, как раз самое главное - это использовать хардварные каналы, которые не отвлекают лишние ресурсы от основной задачи. А для перепрошивки у меня предусмотрена перемычка. Отлаживать же вполне можно каждый чип по отдельности, ибо каждый выполняет свою чётко ограниченную функцию.

Qvan22 25.03.2019 00:55

Цитата:

Сообщение от shalex (Сообщение 340612)
Да, и каналов при этом туча. И все равно, можно попробовать одной ардуиной обойтись, может быть на 64 канала оставить.
К сожалению ускорение работы требует памяти на всякие кеши и буферы.

Можно попробовать, но целесообразность этого зависит от лишь от личных предпочтений, хотите все в одном устройстве, или наоборот, можно раздать функции между разными контроллерами...
У кого-то функционал устройства расширяется через прямое управление PCA9685, MCP23017 или 74hc595, а мне, например, больше хочется использовать маленькие ведомые МК, которые просто ждут команду, и при этом, сами знают как "красиво помигать светом в клозете"...
Тут все варианты правильные, и главное, чтобы это все заработало, так как вы это задумали:)

Цитата:

Сообщение от shalex (Сообщение 340613)
Столкнулся с тем, что надо очень плавно двигать сервой (ворота депо), и переменная типа "байт" не давала плавности движения. Пришлось увеличивать в два раза тип переменной.

Иногда помогает уменьшить рывки, если разбить каждый шаг поворота сервы, на маленькие шажки через(writeMicroseconds()), например каждый шаг включает: шажок вперед, следом шажок назад и далее 2-3 шажка вперед...

Eprinter 25.03.2019 05:46

Появилось время, внимательно перечитал ещё раз.
Александр, вижу явное недопонимание идеи. Возможно потому, что в Локонете, которым занимаетесь вплотную, иная организация обмена - команды плотнее упакованы по частоте, идут с приличными интервалами, а в ДСС они непрерывны, размазаны тонким слоем, постоянно повторяются.
Во втором случае приходится постоянно отвлекаться на прерывания, отслеживая каждую смену полярности на рельсах, ведь любая может оказаться началом нужной тебе команды. А это десятки потраченных тактов на переключение между задачами десятки (даже порядка сотни) тысяч раз в секунду, то есть масса процессорного времени уходит впустую.

Цитата:

Сообщение от shalex (Сообщение 340608)
сделать стек DCC-команд и т.д.

Буфер последовательного порта 64 байта, стек не нужен вообще. Реализация на уровне железа означает, что если запихнул байт в выходной регистр порта, то можешь забыть о его дальнейшей судьбе - он обязательно окажется в буфере получателя. Если тот не завис, конечно :)
ПС Для иллюстрации. У меня при редактировании настроек работа останавливается, и если команды по ДСС продолжали поступать, после возврата в режим работы они отрабатываются.

Цитата:

Сообщение от shalex (Сообщение 340608)
Проще еще один декодер поставить поблизости и не тянуть провода через весь макет.

Можно сравнить.
Каждый декодер требует 4 провода - ДСС и питание. Плюс желательно отдельное питание для исполнительных механизмов. Итого - 5.
РСА9685 требует... тоже 5 проводов.
О чём спор? ;)


Ещё пропустил:
добавить массив на 4 шт unsigned long (итого 16 байт) и сохранять там последний direction для каждой стрелки в виде бита. И не отсылать лишний раз команду на вторую ардуину, если новый direction стрелки совпадает со старым. И трафик в шине ардуина-ардуина упадет почти до 0
Это лишнее. Аксессуарные команды как правило не дублируются постоянно в цикле, в отличие от локомотивных.
Не смотрел пока, как это реализовано в Зетке, в МДпрог идёт повтор одной и той же команды в течении 1/16 секунды, от него у меня как раз реализована защита.
Более узкое место - декодирование сигнала ДСС, поэтому максимально разгружать нужно именно первый чип.

Alexmit 25.03.2019 09:40

Цитата:

Сообщение от Eprinter (Сообщение 340627)
Аксессуарные команды как правило не дублируются постоянно в цикле, в отличие от локомотивных.

Z21 и MULTIMAUS постоянно передают последнюю аксессуарную команду.

Eprinter 25.03.2019 10:18

Цитата:

Сообщение от Alexmit (Сообщение 340648)
Z21 и MULTIMAUS постоянно передают последнюю аксессуарную команду.

То есть если переключаем 10 стрелок подряд, первые 9 команд уйдут по одному разу (два, три, ... 10), а последняя будет повторяться до выключения станции? Вперемешку с локомотивными командами?

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


Текущее время: 05:29. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc. Перевод: zCarot
Copyright © ModelldepO.ru 2006 -