LED-матрица + MAX7219 + MaxMatrix.lib

vk007
Offline
Зарегистрирован: 16.06.2015

Нет, вы пока еще так и не поняли разницы между delay() и millis(). Читайте. Много читайте. Как показывает практика, millis() для новичков почему-то одна из самых сложных в понимании функций.

И у вас есть реальный шанс разобраться с ней раз и навсегда.

vk007
Offline
Зарегистрирован: 16.06.2015

Наш скетч пока отложите в сторону и тренируйтесь на каком-либо простом скетче. Когда разберетесь что к чему, тогда и поймете, куда в нашем скетче эту millis писать.

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

Jenek_Anapa пишет:

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

читайте заново - вы ничего НЕ поняли про неё! (про millis())

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

это почему , ? смысл то таков 

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

millis() - это ЧАСЫ (если грубо говоря) которые считают время в тысячных долях секунды (1/1000) с момента включения МК

они никак не связаны ни с каким-либо видом пауз и задержек!

 

а принцип работы алгоритма запуска кода (части кода) здесь похож на работу ваше будильникаа дома, который вас на работу/школу утром будит

 

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

vk007
Offline
Зарегистрирован: 16.06.2015

Jenek_Anapa, я бы не рекомендовал вам пользоваться рисунком из поста #407. С будильником тут некорректное сравнение, и на самом рисунке ELITE тоже намудрил.

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

Представьте себе часы где нет часовой, минутной и секундной стрелок, а есть всего одна стрелка. Не напоминает ли вам сие устройство секундомер? Так и есть, только шкала у него не в секундах, а в миллисекундах - такой себе миллисекундомер. Запускается он автоматически, вместе со стартом программы. И в любой момент, вызвав функцию millis(), мы можем узнать, сколько уже натикало.

Чтобы в программе периодически выполнять какое-либо действие, обычно используется такая конструкция:

unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
  previousMillis = currentMillis;
  ... /* тут выполняем нужное действие */
}

Что же она делает? А вот что. Периодически, крутясь в loop'е, программа "посматривает на миллисекундомер": currentMillis = millis(); Т.е. переменной currentMillis присваиваем "текущее время". Дальше вычисляем разницу между этим текущим временем и временем предыдущего срабатывания (previousMillis). И, если прошло достаточно времени (получившаяся разница больше необходимого интервала), то делаем то, что нам нужно, а в previousMillis заносим текущее время (и теперь уже оно будет "временем предыдущего срабатывания"). ELITE в своем объяснении назвал эту переменную time и написал, что это "время следующего будильника" - нет, это время не следующего будильника, а наоборот - предыдущего. И time = millis(); - это не заводка будильника, а всего-лишь такой себе чекпоинт.

Если еще не стало понятней, то объясню несколько иначе, на примере. Допустим, жена приказала наварить целую кучу яиц. Яйца будем варить по 10 минут. Приступаем. Засекаем время начала - в программе это соответствует

unsigned long previousMillis = 0;

Это делается на этапе инициализаций переменных (т.е. вне пределов всех функций) и эта переменная будет глобальной. Это не значит, что таким образом мы "включаем" millis(), "обнуляем" ее или еще чего с ней делаем! Просто объявляем переменную previousMillis и присваиваем ей ноль, так как мы ее используем в формуле и до первого срабатывания должна же она чему-нибудь равняться. Поскольку срабатываний еще не было, то принимаем ее значение равным нулю. Можно конечно в сетапе ей присвоить значение millis(), но если сетап короткий, то millis() еще много не натикает - т.е. от 0 далеко не убежит, значит, можно не париться.

Дальше бросаем яйца в каструлю (с налитой водой и стоящей на огне) и читаем газету (курим, смотрим телевизор и т.д.), но постоянно в процессе этих действий поглядываем на на наши "часы". Прочитали пару строк - посмотрели на часы. Например, прошло 5 минут (5 - 0 = 5) - рано (5 < 10), читаем дальше. Снова посмотрели, на часах уже 8 минут - рано. Снова читаем. Смотрим - 11 минут. Ага норма (11 > 10). Достаем яйца, бросаем новую партию. Засекаем текущее время, как время срабатывания, - в коде это

previousMillis = currentMillis;

Т.е. в нашем случае previousMillis будет теперь равно 11 минутам. И дальше, поглядывая на часы, мы уже будем считать, сколько времени прошло с 11-ти минут. Т.е. от текущего времени, которое мы узнаем из millis(), минусуем 11 минут (previousMillis) и смотрим на разницу - прошло ли уже 10 минут или нет. Например, на часах 14 минут - значит прошло всего 3 минуты (14 - 11 = 3), а это рано - 3 < 10. ... Посмотрели в следующий раз - на часах 24 минуты - значит прошло 13 минут (24 - 11 = 13) - норма (13 > 10). Снова меняем яйца. Время срабатывания (previousMillis) теперь будет равно 24 и дальше будем от него "плясать"... И т.д., пока жена не скажет хватит или не свалимся от бессилия...

Текста получилось конечно дохрена, но как смог...

vk007
Offline
Зарегистрирован: 16.06.2015

Еще небольшое дополнение, почему не стоит учиться на картинке от ELITE.

if (millis() - time > 1000) time = millis();

У него time - это время следующего будильника, но ведь в жизни будильник выставляется на будущее время, т.е. больше текущего. Например, сейчас 10 часов утра, нам надо отоспаться от ночной и выйти на работу во вторую смену - мы хотим чтобы будильник разбудил нас в 17 часов (т.е. через 7 часов). И если использовать такую формулу для проверки, то такой будильник конечно когда-то сработает, но никак не через 7 часов, а соооовсем в другое время. Т.е. ни в 11 часов (11 - 17), ни в 16 (16 - 17) ни в 17 (17 - 17) разница не будет больше 7 часов, а значит условие не выполнится и мы проспим.

Дальше, при выполнении условия, он объясняет time = millis(); как заводка будильника на новое время. ОК, пусть будет так. Но тогда получается, сработал будильник и мы время следующего срабатывания выставляем равным текущему. Но ведь текущее уже "было"??? Зачем выставлять время будущего срабатывания на текущее? Грубо говоря, 1 марта 2018 года 17:00 больше никогда не наступит - оно было только один раз, разве что календарь поменяют, ну или наступит "великое переполнение millis". Но о последнем лучше не заикайтесь даже, тут же набежит Святая Инквизиция и в самом оптимистичном варианте развития сюжета расскажет "почем в одессе рубероид" и быстро "научит родину любить" :)

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

Jenek_Anapa
Offline
Зарегистрирован: 13.02.2018

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

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

vk007 главное, чтобы человек понял суть, даже если объяснение кривое и по мнению гуру, не логичное, но в целом верное, и человек, которому оно адресованро, на его основе поймет принцип работы - то можно считать "задача решена"

sadman41
Offline
Зарегистрирован: 19.10.2016

Неважно, что хирург на место правой руки пришил пациенту левую ногу и наоборот. Даже если по мнению гуру это нелогично. В целом-то всё верно - у человека есть и руки и ноги! И если это поймет тот, кому это адресовано, то можно считать, что задача решена.