Здравствуй millis Новый Год
- Войдите на сайт для отправки комментариев
Пт, 18/11/2016 - 10:36
Здравствуйте !
Делаю автомат световых эффектов , где вместо delay использую millis. Почему millis - на будущее прикручу кнопку для переключения эффектов. Вроде все работает , но задержка к примеру в 20 миллисекунд получается почти секундной. Подскажите плиз где я накосячил.
Код
int aa=0; //****************Переменные пинов светодиодов int l1 = 4; //1 int l2 = 5; //2 int l3 = 6; //4 int l4 = 7; //8 int l5 = 8; //16 int l6 = 9; //32 int l7 = 10; //64 int l8 = 11; //128 int l9 = 12; //256 int l10 = 13;//512 int l11 = 14;//1024 int l12 = 15; //2048 int l13 = 16; //4096 int l14 = 17; //8192 int l15 = 18; //16384 int l16 = 19;//32768 int l17 = 1; //65536 int l18 = 3;//131072 //************************** int lp[] = {l1, l2, l3, l4, l5, l6, l7, l8,l9, l10, l11, l12, l13, l14, l15, l16, l17, l18}; // массив пинов светодиодов #include <avr/pgmspace.h> const PROGMEM uint32_t point[] = { 3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0, 16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0,16323,0, 32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0,32707,0, 229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0,229375,0, 262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0,262143,0, 262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143, 262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143,262143, }; const char inv_on = LOW ; //LOW для макета, HIGH с транзисторами const char inv_off = HIGH ; // HIGH для макета, LOW с транзисторами int Count = (sizeof(point)/4); //Подсчет количества элементов в массиве long duration=20; // интервал long previousMillis = 0; void setup() { for (int i = 0; i < 18; i++) { pinMode(lp[i], OUTPUT); digitalWrite(lp[i], inv_off); } Serial.begin(9600); } void loop() { // Serial.println(aa); ///////////////////////////////////////////////////////////// { for (int p0=0; p0<Count; p0++ ){ for (int p1=0;p1<18;p1++){ long int p2 = pgm_read_dword (&(point[p0])); int ppp3; if (bitRead(p2,p1)==1) { ppp3=inv_on; } if (bitRead(p2,p1)==0) { ppp3=inv_off; } //****************** для задержки в millis // Serial.println(aa); while (aa==0){ unsigned long currentMillis = millis(); if(currentMillis - previousMillis > duration) { previousMillis = currentMillis; aa=1; } digitalWrite(lp[p1], ppp3); } aa=0; //***************************** } } } }
а чем твоя задержка отличается от делай? я не увидел отличия принципиального
а что массив такой большой? сколько светодиодов. какое железо
Не знаю, связано ли это с описываемой проблемой, но бросилось в глаза, что в строках 37-38 переменные объявлены как long, лучше бы они были unsigned long.
unsigned
long
вместо цикла - if
while
(aa==0){
класс титановый велосипед для delay без delay().
Железа пока нет - на выходах ардуины по одному светодиоду. Всего 18.
Клапауций 234
По вашему совету нет задержки. Пробовал применить титановый велосипед , но ничего не вышло.
jeka_tm
Массив сам собирал.
понятно в массиве записано как тот или иной светодиод должен светится. но видно это чей то уже готовый массив, скорее всего
262143 это всего 15 бит, а значит 15 светодиодов. ну или дублируются
а чем твоя задержка отличается от делай? я не увидел отличия принципиального
тем, что в неё можно вставить опрос кнопки, он же писал.
А вот зачем в этом цикле стоит "digitalWrite(lp[p1], ppp3);" я тоже не понимаю.
но задержка к примеру в 20 миллисекунд получается почти секундной.
А с чего Вы это взяли? Боюсь, что это Вам так кажется чисто внешне. Поставьте вывод в сериал значения millis перед строкой 72 и после строки 80. Думаю, что Вы уидите, что задержка у Вас нормальная. Если, вдруг, паче чаяния, нет, то выложите что там напечаталось, посмотрим.
А то, что у Вас эффекты не меняются, так разбирайтесь со своим массивом point. Например, для начала, удалите запятую в конце строки 32. И вообще, посмотрите на массив.
Мерцание при 20 ms и мигание раз в секунду уж очень отличимы.С чтением массива все нормально. Эффекты меняются правильно , только очень медленно. И где теряется время не могу отловить. В цикле между 72 и 80 строками все нормально.
digitalWrite(lp[p1], ppp3); вынес из цикла while - результат прежний . Запятую убрал .Все очень медленно.
Мерцание при 20 ms и мигание раз в секунду уж очень отличимы.
Да, с этим-то никто и не спорит, просто прчин тому может быть много, вот я и спросил, с чего Вы взяли, что именно задержка виновата. Без печатей, о которых я просил, трудно судить.
digitalWrite(lp[p1], ppp3); вынес из цикла while - результат прежний . Запятую убрал .Все очень медленно.
Ну, здесь-то никто результата и не ожидал, просто это тоже надо было исправить. Только вот инересно куда Вы его внеысли.
Вот это уже интереснее, давайте смотреть.
Первое, что Вы должны отметить. Разница между "строка 80" и предшествующей ей "строка 72" всегда и везде почти правильная - 21 - 24 мс. Обратили на это внимание?
Вывод - задержка отрабатыват правильно - в районе 20-25 мс.
Значит проблема в другом. Не в в этом цикле. Вы с этим согласны?
Ищите в другом месте. Также печатайте время и анализируйте.
Если нужна моя помощь в поиске, выложите текущий скетч, я скажу где ещё печатей постаставить, чтобы что-то выловить.
Спасибо огромное ! Помощь очень нужна.
В массиве мерцание светодиодом на 13 ноге (20ms) . На самом деле мигает раз в секунду. Можно проверить на любой ардуине.
Вот что имеем сейчас
mobistrike, мозг взрыватся когда смотришь на ваш код. Вы так намудрили, что похоже и сами не понимаете как это работает.
Есть несколько советов. Во первых если вы любите называть переменные так: aa, p1, p2, ppp3 -вы конечно можете это делать, но если выкладываете свой код на осмотр ЛЮДЯМ то желательно давать более адекватные имена. Во вторых вы генерите очень много кода и кучу лишних переменных, например в последнем коде из #11 строки 53... 61 вполне заменяются одной командой
digitalWrite(lp[p1], !bitRead(p2,p1));
Ну и в третьих нет форматирования, -любые вложенные операции должны быть с отступлением строки от той, где произошло вложение. По сути дать заключение очень трудно ввижу вышесказанного, но предварительно я вижу например по коду в #11 что вы в 50-51 строках перечитываете байт флеша из массива на каждой итерации светодиода. Т.е. как минимум вы делаете 19 раз операцию довольно ресурсожоркую операцию, которую нужно было сделать перед циклом всего 1 раз.
Вы так намудрили, что похоже и сами не понимаете как это работает.
Спасибо за критику . Намудрил - согласен. Но это от того что не программист. Учусь. Как работает представляю - писал все сам с нуля. Про эстетику и переменные приму к сведению.
Так, давайте сделаем так.
I. Сначала давайте обсудим логику
Мне кажется, у Вас логическая ощибка, но я не уверен.
Насколько я понимаю, Вы хотите делать так
1. Поменяли значение всех 18 светодиодов
2. Отработали задержку
3. Переход к п.1.
И так ДЛЯ ВСЕХ массив point
Это правильно Вы этого хотите?
Если "да", то у Вас логическая ошибка. Сейчас Вы отрабатываете задержку не после того, как поменяли значения всех светодиодов, а после каждого отдельного светодиода.
Понимаете разницу?
В общем, если я прав, то просто вынесите задержку из цикла, который начинается в строке 50, но при этом она должна остаться в цикле, который начинается в строке 49 и тогда всё будет хорошо.
2. Если же с логикой у Вас всё в порядке,
то ниже я прикду скетч. который я чуть-чуть причесал (а то коллега прав - мозг взрывается). Запустите его и проанализируйте времена. Если не поймёте, то выложите сюда лог, будем вместе смотреть.
Еще раз благодарю !
I. Сначала давайте обсудим логику
1. Поменяли значение всех 18 светодиодов
2. Отработали задержку
3. Переход к п.1.
И так ДЛЯ ВСЕХ массив point
Это правильно Вы этого хотите?
Да именно так.
Залил . Вот лог .
Ой, блин, ну в строке 50 вместо print надо println, Разумеется.
Если так (про логику), то Вы вынесли задержку из цикла? Вынесите и проблема решится.
Ой, блин, ну в строке 50 вместо print надо println, Разумеется.
Если так (про логику), то Вы вынесли задержку из цикла? Вынесите и проблема решится.
Вынес . Все так же медленно. Вы так имели ввиду ?
Вот лог сейчас
mobistrike, а то что я писал -мимо ушей промчалось? 16 строчку перед 14 вставить
mobistrike, а то что я писал -мимо ушей промчалось? 16 строчку перед 14 вставить
Сделано . Без изменений.
mobistrike, будьте внимательнее
1. Я Вам говорил ln добавить в строке 50, а Вы добавили в 49. Вы же видите что в печати лажа, ну и поправьте.
2. Про перестановку задежрки. Конечно, я имел в виду не так. Но может быть Вам так и нужно - это только Вы знаете.
Давайте ещё раз договоримся о логике. В каком месте должна быть задержка? Так как я описывал, или как-то по-другому. Напишите точно и чётко, что Вы хотите сделать. Без этого мы никуда не продвинемся.
Алгоритм такой
1 Берем первое число массива
2 раскладываем на биты
3 Побитово выводим -в зависимости от битов в числе - 1 вкл светодиод, 0 выкл светодиод
4 Задержка
5 берем следующее число и так до конца массива
Как то так.
Я вот тоже не понял что собссно не так, 19 итераций по 20мс + накладные расходы -итого примерно 1 Гц и получаем.
Алгоритм такой
1 Берем первое число массива
2 раскладываем на биты
3 Побитово выводим -в зависимости от битов в числе - 1 вкл светодиод, 0 выкл светодиод
4 Задержка
5 берем следующее число и так до конца массива
Как то так.
Надо не "как-то так", а точно.
Правильно ли я понимаю, что п.3. Выше включает в себя все 18 битов (т.е. весь цикл строки 14???).
Тогда задержка нужна после цикла строки 14.
Попробуйте вот так:
Время между "Enter Loop" и "Exit loop" должно быть приблизительно 120-130 мс.
Дело в том, что задержка у Вас находится в цикле строки 56. Цикл выполняется в данном случае 6 раз. Вот 6*20 + время на всё остальное и даёт 120-130 мс.
Если получится так. то это нормально. Именно так, как написано.
Покажите что получилось.
[
Покажите что получилось.
Не покажу !
Потому что теперь работает правильно ! Я в принципе не сомневался что специалисты справятся.Сам пытался. Два вечера просидел но так и не разобрался.
Спасибо всем откликнувшимся.
Отдельная благодарность ЕвгенийП за проявленное внимание и терпение.
С победой!
Вам бы код причесать. Dimax правильно говорил, там у Вам и по памяти раза в два можно сократить и по размеру.
Вам бы код причесать.
Так вы его уже причесали до неузнаваимости(в хорошем смысле) .Гляжу на свой код в первом сообщении и на ваш последний . Теперь я знаю откуда взялось выражение , как нельзя лучше подходящее к этому действию. "Причесать !" :-))
Да, нет, там ещё много. В принципе у меня есть свободный час, сейчас минутку, я займусь и выложу.
Этот код можно причёсывать и причёсывать, пока три строчки не останется :))
Если расположить светодиоды не абы как, а по строго по портам,то можно полностью убрать цикл перебирания светодиодов, а вместо него вставить всего три (!!!) команды на запись портов. Типа PORTA=p2; PORTF=(p2>>8); PORTE=(p2>>16);
рыба гирлянды с использованием класс титановый велосипед для delay без delay().
у кого есть много фонтазии, что такого можно интересно намигать - приглашаю в garland();
Ну, в общем, не особо напрягаясь и не пытаясь как-то и что-то поменять в логике (например, как советуют - переставить светодиоды, и т.п.). Просто Ваш код ну чуть-чуть прилизал то, что в глаза бросалось.
Вот Ваш код из поста 23. Я прокомментировал в нём то, мне резало глаза.
При компиляции у меня:
Sketch uses 3 332
Global variables use 360 bytesТепер
теперь просмотрите на то, что я переделал. Опять же, сам бы я глобально не так бы делал, но здесь просто переделка того, что было у Вас.
При компиляции у меня:
Sketch uses 2 954
Global variables use 300 bytesТепер
это #define DURATION 20ul какая-то фигня, а не гирлянда
И снова здравствуйте !
Прикрутил кнопку. Занимаюсь переключением режимов. Реализовал так : один массив, в котором последовательно записаны эффекты, к примеру по адресу от 0 до 10 один эффект,11-20 второй ,21-30 и т.д. По нажатию кнопки выбираются адреса начала и конца . Все работает но что то мне подсказывает что можно сделать проще. Что думаете ?
Видео покажу чуть позже.
видео покажи. а то хз какие эффекты
видео покажи. а то хз какие эффекты
Примерно так ....
https://www.youtube.com/watch?v=1HtyRJ1WaWw&feature=youtu.be
ничего сложного или случайного не увидел. все можно описать математически
как минимум здесь -
previousMillis = currentMillis;