Синхронная работа 8 Ардуино мигание диодов в секундах
- Войдите на сайт для отправки комментариев
Вс, 18/10/2020 - 22:58
Есть такой проект, через радиомодуль подаётся сигнал на 8 ардуино, и они должны работать по прописанному коду синхронно включать выключать диоды на костюмах ws2812b. Часы реального времени дают задержку каждые 5 секунд. Пытались менять код и mills и delay. Но разсрнхронизация все равно есть. Сначала диоды загораются при подаче сигнала синхронно. Но в процессе кода начинаются сбои и рассинхрон. В чем может быть проблема ? Ардуино итальянское не китайское. Думаю перейти на esp32 или nodemcu на базе eap8266 и через mqtt протокол запустить все 8 костюмов. Но в esp вообще не разбираюсь. Кто то вообще сталкивался с синхронной работой ардуино от 5 шт. Код прописан по секундам.
Если кто знает как решить этот вопрос готов заплатить
Стандартный встречный вопрос. А где код, схема подключения?
Как вариант может в ардуино заранее загружать готовый алгоритм мигания диодами. А по радиоканалу только команда на синхронный старт.
И где тут синхронизация?
Схема работы такая и есть. Только вот ардуины не мигают синхронно по заданому времени. Чем дальше идет код тем больше время разсинхрона между ними. Одна быстрее мигает другая медленее. И так каждая со постеменно в своем время мигает. Где то после 20 секунды
Причем пробовали мигать светодиодом на самой ардуине не подключая при этом диоды. И все равно такой же разсинхрон
Дак вам пока VirtualWire отложить бы в сторону и стартовать по digitalRead(2), например. Все D2 подчиненных ардуин собрать на ардуину-мастера и ею отмашку давать.
036
}
037
void
loop
() {
038
// Some example procedures showing how to display to the pixels:
039
if
(vw_get_message(message, &messageLength))
// Если есть данные..
040
{
041
if
(message[0] ==
'H'
)
042
{
043
digitalWrite(13, HIGH);
044
dance();
// включение по радио
045
}
046
}
047
}
В этот момент идет синхронное включение всех 8 ардуин через радиомодуль. А дальше просто на каждой эта программа мигает. Думал из за кварцевого резонатора но не знаю можно ли его перепаивать на самой ардуине хотя бы на те же 16 МГц которые там заложены . Читал за кварц что он имеет свойства изнашиваться. Но ардуины новые только распечатанные были.
Дело думая не в радиомодуле. Потому что при первом загорании они синхронно загораються, а вот потом только начинают накапливать задержки
так на миллисах и не пойдёт
адаптировать на delay тоже пробовали все равно задержка идет
Судя по количеству ключей - это лишь малая часть полного кода. Код полностью длится, наверно, несколько минут?
Я правильно понял, что вся синхронизация заключается в одновременном запуске? Это ерунда.
Надо посылать синхросигналы в каждый ключевой момент танца, то есть при каждой проверке переменных key1-key135
Да это малая часть кода, по задумке будет еще больше ключей.
Думали по такому принципу, тоже делать как вы описываете. Но проблема если будет большая сцена с большим колличеством аппаратуры. Возможны задержки или перебои.
Не понимаю почему все ардуины не работают синхронно, до сих пор не могу понять.
Дело думая не в радиомодуле. Потому что при первом загорании они синхронно загораються, а вот потом только начинают накапливать задержки
решение - синхросигналы каждые 2-3 секунды
Дело думая не в радиомодуле. Потому что при первом загорании они синхронно загораються, а вот потом только начинают накапливать задержки
А вы попробуйте. Не используя и не запуская VirtualWire вовсе. Потом расскажете.
А как его воплотить? ) Какая схема?
Не понимаю почему все ардуины не работают синхронно, до сих пор не могу понять.
это просто. Работа с адресной лентой сбивает системный таймер ардуины. Как вы не старайтесь, без постоянной синхронизации не обойтись
Работа с адресной лентой сбивает системный таймер ардуины.
А VirtualWire сидит в ISR...
мы мигали светодиодом на самой ардуине через mills и delay. Все равно был рассинхрон думал не в ленте дело. А вот синхросигнал интересно
А как тогда реализовать это все?
Только через синхросигнал?
Извините я просто чайник вообще в этом
Можно ли VirtualWire поместить не в ISR?
Как чайнику я и посоветовал - сделайте для начала без VirtualWire, уберите одно потенциально проблемное звено. Ибо ваши предположения о его непричастности пока что ни на чём не основаны.
Прописал через delay
Все равно задержка есть, не такая большая но уже 2 минуте видно разсинхрон
FastLED запытайте ещё. Чисто логически - ардуины должны идти в ногу. Искать где сбивается - за просто так никто вам не будет. Это надо стенд собирать и пр. и др. Да ещё и результат непредсказуем.
Скажите, а может быть проблема в кварцевом резонаоре? Может быть из за того что кварц изначально разного размера в каждой ардуине? Может не качественный где стоит? Не понимаю динамику хаотичного рассинхрона. Если был бы рассинхрон из за диодов или библиотеки то он был бы на всех одинковый скорее всего. Они бы может отставали по задумке с музыкой но работали по одной и той же схем. Может быть в платах из начально заложены погрешности, не могут они быть едентичными все. Особенно кварц я читал что в резонатор кладут камень разного размера иногда, и написано 16мгц резонатор а юыьб 15.654 и тд. Что вы думаете по этому?
Можно ли вообще кварцевый резонатор на ардуине перепаять на такую же частоту?
Потенциально может быть что угодно.
Про кварцы тут вот поясняют: http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/chastotomer-na-arduino-uno-i-2004-vremennyi
Но без инструментальных исследований нельзя однозначно утверждать, что дело в кварце. А если и в нём - что вы предпримете? Где найдёте более лучшие? Во что это обойдётся?
Выхода тут три:
1) Урезать осетра и более толерантно относится к рассинхрону;
2) Искать другое железо. Гарантии успеха - нет;
3) Делать workaround, разбивая весь процесс на этапы небольшой продолжительности, на которых рассинхрон не заметен. После этого с мастера давать отмашки на исполнение каждого последующего этапа.
P.S. MQTT - не realtime протокол. С ним даже нет гарантии синхронного старта.
Спасибо, лаконично и четко )
Олег911, добавлю к вышесказанному, что начать надо с того, что полностью переписать программу. Объявлять по 100 штук 16 битных переменных (хотя используется лишь один бит), и копировать в столбик по 10 раз вызов одной и той же функции - никакой памяти не хватит. Конечно компилятор старается всё лишнее выкинуть, а вызовы функций оптимизировать, но его возможности не безграничны. И когда вы допишите ещё полсотни обработчиков "ключей" наверняка начнутся проблемы.
Никаких проблем по времени с точки зрения ардуино и кварцев быть не должно. У кварцев расхождение +-0.005%. Чтобы что-то заметное накопилось, нужны недели. Ошибки однозначно в коде/проектировании, которые, судя по всему, сделаны весьма несерьезно.
паузы и генерацию key надо крутить на главной ардуине
на остальных все время ждать key и по приходу начинать вывод нужных "картинок" без финальной паузы
А можно вообще все сделать на ESP и просто спамить рассылку UDP.
Олег911, добавлю к вышесказанному, что начать надо с того, что полностью переписать программу. Объявлять по 100 штук 16 битных переменных (хотя используется лишь один бит), и копировать в столбик по 10 раз вызов одной и той же функции - никакой памяти не хватит. Конечно компилятор старается всё лишнее выкинуть, а вызовы функций оптимизировать, но его возможности не безграничны. И когда вы допишите ещё полсотни обработчиков "ключей" наверняка начнутся проблемы.
вы думаете переписать все на Fastled ? Или как можно оптимизировать код ?
потому что я пробовал через стандартный блинк мигать с 1 ключем. Все равно идёт разсинхрон
Олег911, я вообще то несколько другое имел ввиду, -сам код вы начинаете писать слишком "размашисто", это чревато проблемами в перспективе. Менять библиотеки вряд ли есть смысл, они скорее всего все блокируют прерывания(предположение). Короче инструменты типа millis и delay будут врать что-б вы там не делали. Нужно писать свой обработчик 1-го таймера (можно через библу timerOne), который будет дёргать прерывание скажем пару раз в секунду, и вести свой счёт времени. И привязываться к нему. Либо ещё лучше переходить на ARM, и работать через DMA, благо библиотеки под это дело тоже есть. Ну или слать с "главного" контроллера буквально каждую команду, или небольшими порциями как уже советовали выше.
вы думаете переписать все на Fastled ? Или как можно оптимизировать код ?
библиотека тут не причем - сам код написан очень плохо, куча повторов и неэффективных конструкций. Научитесь пользоваться процедурами и функциями, для похожих операций используйте массивы и циклы...
например, вместо 5 строк
можно написать одну
далее смотрим, что кусок
у вас повторяется раз десять, меняется только цвет. Оформляем его как функцию, попутно заменяя одинаковые строчки на цикл. как показано выше:
Теперь везде, где вы вызываете изменение цвета для лент2 3 - просто пишем
То же самое сделайте для лент 4 и 5 - и у вас код уменьшиться раз в десять...
Олег911, я вообще то несколько другое имел ввиду, -сам код вы начинаете писать слишком "размашисто", это чревато проблемами в перспективе. Менять библиотеки вряд ли есть смысл, они скорее всего все блокируют прерывания(предположение). Короче инструменты типа millis и delay будут врать что-б вы там не делали. Нужно писать свой обработчик 1-го таймера (можно через библу timerOne), который будет дёргать прерывание скажем пару раз в секунду, и вести свой счёт времени. И привязываться к нему. Либо ещё лучше переходить на ARM, и работать через DMA, благо библиотеки под это дело тоже есть. Ну или слать с "главного" контроллера буквально каждую команду, или небольшими порциями как уже советовали выше.
А если как вы пишите на ARM перейти, повторения такого же результата на сколько вероятно?
потому что микроконтроллеры на arm не дешево стоят.
Для непрофессионала (безличностный термин) вероятность факапа всегда > 90%
А если как вы пишите на ARM перейти, повторения такого же результата на сколько вероятно?
потому что микроконтроллеры на arm не дешево стоят.
Олег, мне кажется, Вы не совсем верно поняли dimax... в первую дело не в контроллере... а в вашем коде
А "микроконтроллеры на arm" бывают разные, некоторые дешевле ардуинок стоят. Но, обратите внимание, совет dimax был не просто сменить контроллер, а "переходить на ARM и работать через DMA". Если вы возьмете арм и напишете примерно такой же код. как выше - он и глючить будет так же.
Вы в начале ветки писали, что готовы заказать эту работу профессионалу. Думаю для вас это будет оптимальный вариант.
А если как вы пишите на ARM перейти, повторения такого же результата на сколько вероятно?
потому что микроконтроллеры на arm не дешево стоят.
Олег, мне кажется, Вы не совсем верно поняли dimax... в первую дело не в контроллере... а в вашем коде
А "микроконтроллеры на arm" бывают разные, некоторые дешевле ардуинок стоят. Но, обратите внимание, совет dimax был не просто сменить контроллер, а "переходить на ARM и работать через DMA". Если вы возьмете арм и напишете примерно такой же код. как выше - он и глючить будет так же.
Вы в начале ветки писали, что готовы заказать эту работу профессионалу. Думаю для вас это будет оптимальный вариант.
Понял вас, написан код был так потому что я первый раз сам программирую, и мне надо по хореографии разложить когда светодиоды загораються когда тухнут и какие по времени.
прописывал вот так код и мигал только ардуиновским диодом, все равно был разсинхрон.
Если что я в электронике вообще первый раз занимался всю жизнь хореографией. Думаю тут код по меньше написан. По этому Думаю дело не в коде. Могу конечно ошибаться. Пока самый актуальный вариант который все говорят это сделать одну главную и с нее отдавать сигналы. Но все равно хочу покопаться с вариантом когда один старт, а потом каждая по своему коду идет. Если вы говорите что по arm скорее всего такая же будет проблема будет, если код длинный, то и пробовать не буду на ней.
Чтобы отсеять сомнения по поводу кварцев, советую записать скетч совсем без библиотек. Просто синхронный старт по изменению уровня на ноге, зажигание светодиодов и переключать каждую минуту. Посмотреть через какое время будет не синхронно. И хорошо бы оперировать цифрами - через какое время и на сколько. А по результату - думать, что делать.
Олег, ну какой смысл повторять одно и тоже заново? вам же уже сказали убрать библиотеку VirtualWirе -а она опять в коде
Заинтересовал меня этот разлёт, провёл эксперимент. Питание одинаковое - ардуины соединены по VCC/GND
Nano "Master"
Nano "Slave"
Код наколеночный (D8 - особенности конструкции самопального шилда, где D13 не выведен на гребенку):
Результат "Wiring" фрагмента: A1-A2 ~45ms, B1-B2 ~63ms
Результат "Bare metal" фрагмента: A1-A2 ~37ms, B1-B2 ~45ms
Нашёл ещё одну Нану с "правильными" кварцами (картинка "Master" в предыдущем посте) , прогнал тест на двух одинаковых.
Результат "Wiring" фрагмента: A1-A2 ~28.2ms, B1-B2 ~28.4ms
Результат "Bare metal" фрагмента: A1-A2 ~53.7ms, B1-B2 ~53.9ms
Почему-то на "Bare metal" получился большой gap, но... суть в другом - разбег на порядки снизился.
...пока оформлял пост - ардуины с нормальными кварцами "подразбежались" и рассинхрон стал виден.
суть в другом - разбег на порядки снизился.
Гриш, что-то я не вижу тут "на порядки" - даже в 2 раза разницы нет. Было Wiring A1-A2 = 45мс, стало 28...
Но больше интересно другое - не могу понять из твоих диаграмм - вот например разница 45мс на самой первой картинке - это за какой период. Можешь вычислить разницу частот ардуин в процентах?
суть в другом - разбег на порядки снизился.
Гриш, что-то я не вижу тут "на порядки" - даже в 2 раза разницы нет.
Ну да, поленился описать ход эксперимента, поэтому не очень понятно.
Две ардуины - мастер и слейв. Мастер пинает слейва и они начинают промигивать по одному и тому же сценарию.
Для локализации проблемного места измерялось время отставания момента зажигания светодиода на слейве от зажигания светодиода на мастере. И оно нарастало - за 6 секунд на 18мс... В целом, при простом алгоритме, Wiring радикально картину не портит, проблема в кварцевом резонаторе. Delay на millis() от delay на ассемблеровских фрагментах сильно тут не отличается.
А вот далее начинаются наслоения - VirtualWire на таймере и пр, что усугубляет проблему.
Но, думаю, при аккуратной работе с библиотеками и перестройке командного аппарата, можно добиться удовлетворительного результата.
Если задержки делать на millis(), то никаие VirtualWire не должны мешать. Чтобы сбить millis необхомо запретить прерывания на 2мс или больше. Я код VirtualWire не смотрел, но вряд ли там такая шняга.
Разницу частот... Где-то, вроде, упоминался скетчик, который реальную частоту вычисляет. Dimax подскажет если - я промеряю.
Вот по этому я и писал, что все задержки должны отслеживаться только на мастере и он должен высылать "номер картинки". Слейвы в основном слушают мастера и выводят картинки в зависимости от полученного номера.