Борьба с циклом while
- Войдите на сайт для отправки комментариев
Пнд, 24/02/2020 - 11:14
Всем доброго дня. Я тут работаю над кодом и столкнулся с проблемой, моих знаний и пониманий не хватает. Прошу помогите с кодом.
#include <Arduino.h> #include <U8x8lib.h> //#include U8X8_HAVE_HW_I2C #include <Wire.h> #include "GyverButton.h" U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); GButton butt3(2); // SEL GButton butt2(3); // NEXT GButton butt1(4); // BACK int i, j, mx, mn, bfr, pic = 0; unsigned long time, timer = 0; char *menu1[] = { "PARAMETERS", // 0 "DATA RECORD", // 1 "DISPLAY", // 2 "HELP", // 3 "PROJECT INFO" // 4 }; uint8_t sht[30]; void header() { u8x8.setFont(u8x8_font_amstrad_cpc_extended_f); u8x8.inverse(); u8x8.setCursor(4,0); u8x8.print("ST v1.0"); } void setup(void) { butt1.setDebounce(0); butt1.setTimeout(400); butt1.setClickTimeout(100); butt1.setType(LOW_PULL); butt1.setDirection(NORM_OPEN); butt2.setDebounce(0); butt2.setTimeout(400); butt2.setClickTimeout(100); butt2.setType(LOW_PULL); butt2.setDirection(NORM_OPEN); butt3.setDebounce(0); butt3.setTimeout(400); butt3.setClickTimeout(100); butt3.setType(LOW_PULL); butt3.setDirection(NORM_OPEN); u8x8.begin(); u8x8.setFlipMode(0); digitalWrite(6, HIGH); } void loop() { butt1.tick(); butt2.tick(); butt3.tick(); time = millis(); switch (pic){ case 0: u8x8.noInverse(); u8x8.setFont(u8x8_font_px437wyse700b_2x2_r); u8x8.setCursor(3,1); u8x8.print ("by DA"); u8x8.setCursor(1,4); u8x8.print ("ST v1.0"); delay(3000); u8x8.clear(); pic = 1; j = 2; break; case 1: header(); u8x8.noInverse(); u8x8.setFont(u8x8_font_chroma48medium8_r); for (i=0; i <= 4; i++) { u8x8.setCursor(2,i+2); u8x8.print(menu1[i]); } u8x8.setCursor(1,j-1); u8x8.print (" "); u8x8.setCursor(1,j); u8x8.print (">"); u8x8.setCursor(1,j+1); u8x8.print (" "); mx = 6; mn = 2; break; case 20: pic = 1; u8x8.clear(); timer = time; while ((millis() - timer) < 5000) { u8x8.setFont(u8x8_font_px437wyse700b_2x2_r); u8x8.setCursor(2,2); u8x8.print ((millis() - timer)*0.001); } timer = 0; break; case 30: u8x8.setFont(u8x8_font_px437wyse700b_2x2_r); u8x8.setCursor(2,4); u8x8.print (analogRead(6)); break; } if (butt2.isSingle()) { j++; if ( j >= mx+1 ) j = mx; } if (butt1.isSingle()) { j--; if ( j <= mn-1 ) j = mn; } if (butt3.isHold()) { if (pic >=1 && pic <= 10) pic = (j - 1) * 10; } if (butt3.isDouble()) { if (i>10) pic = (i*0.1)-1; else pic = 0; } }
В месте где switch pic = 20 есть цикл while И он посторяется дважды перед тем как выйти из цикла, я пытался все заключить в цикл for, но ситуация не изменилась. прошу помогите мне люди
Не понял, кто повторяется дважды и откуда должен выйти, но если дважды не надо, то зачем вообще цикл?
цикл while повторяется до того как условие "millis() - timer) < 5000" не станет ложным. Но по завершении выполнения всех условий, он начинает выполнять его опять и только потом иду до "break;"
мне нужно чтобы while досчитал до 5 секунд и потом пошел дальше
но он считает до 5 дважды и лишь потом идет дальше
мне нужно чтобы while досчитал до 5 секунд и потом пошел дальше
но он считает до 5 дважды и лишь потом идет дальше
Значит, когда он после первого "счёта" снова сюда приходит, pic по-прежнему равен 20.
А вообще в строка №№88-92 у Вас написана дикая дичь. Вы хоть представляете как часто Вы собрались экран обновлять?
Anytcent - миллис как условие для while ничем не отличается от delay, такой код показывает, что вы так и не поняли, как правильно использовать миллис
Anytcent - миллис как условие для while ничем не отличается от delay,
Почему? У него ж там вывод на дисплей стоит.
Почему? У него ж там вывод на дисплей стоит.
лучше бы не стоял :)
мне нужно чтобы while досчитал до 5 секунд и потом пошел дальше
но он считает до 5 дважды и лишь потом идет дальше
Значит, когда он после первого "счёта" снова сюда приходит, pic по-прежнему равен 20.
здесь вы правы. и я незнаю как "pic" прировнять к 1, я уже его ставил во внутрь цикла "while", до цикла после цикла, но никак не добился результата.
А вообще в строка №№88-92 у Вас написана дикая дичь. Вы хоть представляете как часто Вы собрались экран обновлять?
касательно этих строк, да. Я планировал что начнется цикл "case" дисплей обновится, потом начнотся цикл "while", потом он закончится и мы опять вернемся к "pic = 1". Разве не так?
как вы посоветуете? что поставить вместо милис?
как вы посоветуете? что поставить вместо милис?
вопрос неправильный. Правильно будет "чем заменить while". разберитесь в примерах, использовать while для ожидания периода времени - категорически неверно
Как вижу в коде кривущие библиотеки типа этой для кнопки, так сразу ясно становится, что автор кода либо с головой не дружит, либо уровня ниже начинающего.
Данный пример подтверждает мои замечания.
Ни одной переменной float , но упорно пытаемся умножать на дробные числа
Проблема конкретно в кривущей библиотеке кнопки.
А точнее в неправильном методе опроса.
У ТС идёт опрос=>действие=>расчет значения опроса.
От этого весь код идёт по женскому половому органу.
Перемести свой switch в самый низ программы.
Каких бы чувст к Гуверу я не испытывал, библиотека с кнопкой тут наврядли может являться причиной несчастий. Во всяком случае по сценарию, описанному Кактусом. "Перенос свича вниз" более правилен алгоритмически, но не принесёт никакого видимого эффекта до тех пор, пока руки пользователя не научились кликать со скоростью 1000Гц.
Хотя, конечно, дебаунс = 0 превращает скетч ещё в ту рулетку...
как вы посоветуете? что поставить вместо милис?
вопрос неправильный. Правильно будет "чем заменить while". разберитесь в примерах, использовать while для ожидания периода времени - категорически неверно
ошибочно было использовать в условии "while" "millis". Я хотел чтобы этот цикл был принудительным, чтобы при счете времени программа не бегала по всему коду, а закрылась в цикле "while", пока не посчитает. Но как вы сказали это было ошибкой. Посоветуйте пожалуйста как тогда мне быть. код еще не полный я буду еще его увеличивать в размере, поэтому подумал об этом заранее.
Каких бы чувст к Гуверу я не испытывал...
Нет. Во всём виноват Гайвер!) А Гувер - это директор ФБР, в прошлом.)
я отключил дебаунс до 0 от того, что я использую не механическую кнопку а модуль. там уже исключен вариант дребезга кнопок.
простите если оскорбляю чуства профессионалов (это не сарказм, а искренние извенения)
Я не хочу чтобы вы подумали, что я тут отшучиваюсь. Я правда не могу понять в чем причина. Ведь кнопки как таковые не участвуют в цикле while. возможно как ранее было сказано я ошибочно использую millis, но подскажите тогда как выйти из положения.
а... значит все изза того что в библиотеках Гайвера уже используется millis, и тут еще я со своими циклами? блин тогда прийдется отключать его библиотеку или есть другой выход?
Каких бы чувст к Гуверу я не испытывал, библиотека с кнопкой тут наврядли может являться причиной несчастий. Во всяком случае по сценарию, описанному Кактусом. "Перенос свича вниз" более правилен алгоритмически, но не принесёт никакого видимого эффекта до тех пор, пока руки пользователя не научились кликать со скоростью 1000Гц.
Хотя, конечно, дебаунс = 0 превращает скетч ещё в ту рулетку...
И тем не менее, присвоение переменной pic большого значения(для меня не ясно какого именно, т.к. код писал какой то индус), происходит только во время состояния btn.isHold, когда кнопка нажата.
Соответственно если она нажата дольше , чем проходит цикл, оно изменится только в конце следующего цикла следующего после того как она будет отжата, т.е. после двух циклов while.
И тут не кликать нужно, "со скорстью 1000Гц", что бы сработало криво, а с точностью до наоборот .
А на вопрос :"как же так мы же делаем pic=1;, внутри цикла while ?, Ответ такой: "зато у нас до сих пор состояние кнопки isHold и он снова станет 20, когда дойдет до места проверки
Тут согласен, поленился я проходить весь скетч.
Однако, библиотека кнопки всё же невиновна, если её использовали задом наперёд. ;)
Тут согласен, поленился я проходить весь скетч.
Однако, библиотека кнопки всё же невиновна, если её использовали задом наперёд. ;)
Если она позволяет такое , то она и виновата.
Моя допустим один раз переменную только позволяет использовать.
А, ну да... Молоток виноват в том, что бьёт по пальцам, автомобиль в том, что давит пешеходов, Си - в том, что у него есть указатели.
Я дико извиняюсь, но могли бы вы разъяснить ваши аллегории?)
Я дико извиняюсь, но могли бы вы разъяснить ваши аллегории?)
Что ещё не понятно ?
Написал же, перенести цикл switch в конец loop
спасибо за советы я еще попробовал изменить butt1.setClickTimeout(100); и еще добавил
Тут согласен, поленился я проходить весь скетч.
Однако, библиотека кнопки всё же невиновна, если её использовали задом наперёд. ;)
лично проверял его библиотеку, работает )))
тут озадачился и тактовую кнопку на аналоговом пине сделал и, даже работает
Я дико извиняюсь, но могли бы вы разъяснить ваши аллегории?)
то что вы сказали работает просто отлично, вы действительно профессионалы, я подумаю почему, мне надо научиться. Сейчас еще добавляю еще некоторые функции и после выложу код уже с комментариями
лично проверял его библиотеку, работает )))
тут озадачился и тактовую кнопку на аналоговом пине сделал и, даже работает
Так вопрос не в том, что работает или нет, а в том как криво это может работать.
Имхо для кнопки конечный автомат это излишество.
Не говоря уже о том, что не все состояния должны быть в распоряжении пользователя и раз уж ты выкатил , якобы "всем понятный и доступный код", то озаботься поставить на него защиту от дурака.
Вопрос о том сколько все это жрет ресурсов это отдельная песня.
Однозначно в топку.
Поищи в гугле или тут по форуму ,выкладывал kakmyc_btn.h .
Весь функционал конструктор + чтение.
Что не помешало мне на ней написать кодовый замок на одной кнопке.
лично проверял его библиотеку, работает )))
тут озадачился и тактовую кнопку на аналоговом пине сделал и, даже работает
криво может работать любой код, где используются статические коэффициенты времени, о чём я, к примеру можно нажимать кнопку со скоростью нажатия 30 символов в минуту а можно 200, весь код на обработку кнопок что я видел (видел наверное далеко далеко не всё), по двойному и тройному нажатию в топку, человек то прекрасно распознаёт, а потому, что нажатия равномерно (почти) темперированы с определённой скоростью, вот когда увижу такой код, скажу ДА УЖ )))
PS без аппаратного подавления дребезга такой код по видимому не написать
лично проверял его библиотеку, работает )))
Возможно ты не в курсе, но "личнопроверяльщик" - это отдельная специальность в программировании, причём крайне высококвалифицированная. Поэтому, прости, но, при всём уважении, фраза "лично проверял" от тебя не звучит ни разу. Если бы ты ещё сказал "лично проверил и нашёл глюк" - это было бы нормально, а вот проверить так, чтобы ответственно говорить, что глюков нет ... извини, но тебе пока рано.
Эта библиотека (как и другие от этого автора) содержит достаточное количество глюков - "лично проверял" :-)
Осталось добавить "мамойклянусь". А оппонент наверно "зубдаю". Детский сад . Если проверял и работает. Что именно проверял, на какой версии либки, как проверял, как кнопку подключал.... Если глючит - аналогично подробности плюс список обнаруженных глюков. А так двое треплются кто громче крикнет "Гувер бог" или "гувер лох".
пока руки пользователя не научились кликать со скоростью 1000Гц.
Патише! А то проснется калапуций и покажет как кнопку дро... долбить надо.
подробности плюс список ....
Прости, братан, забыл тебя спросить что и как мне делать, а чего не делать.
Подробности о глюках в библиотеках гивера с примерами и пояснениями почему так, а не иначе я выкладывал в его собственной теме (например). В ответ получил объяснение в совершенно твоём стиле (я даже грешным делом подумал, уж не ты ли под этим ником скрываешься)
Но фича - не фича. а "фичи", на которые я указал он быстро подправил. С тех пор я как-то не горю желанием исправлять его фичи. Нужны конкретные данные по косякам у гивера - пожалуйста, но только после того, как он (или кто другой) заплатит за эту работу.
А пост мой ты совсем не понял. Оно вовсе не про гивера вообще. Я лишь объяснял человеку, что тестировщик - это отдельная специализация и работа эта требует высокой квалификации. Возможно, ты об этом не знаешь, но это не мои проблемы.
Кстати, я сейчас залетел с Гугла на сайт Гайвера (не спрашивайте зачем). И я там обнаружил, активно постящего всякие там .h и рассказы про то, как из миллиса интервалы получать... Кого бы вы думали?
Ну ты и интриган, выкладывай скорее )))
del
Выкласти не смогу, но намекну: его ник начинается на Arhat, а заканчивается на 109
слава богу, мы его не потеряли ;-)
Россию которуюгения которого мы потеряли, хрустфранцузкой булкисрача на форумеhttps://community.alexgyver.ru/search/97580/
Джентльмены, оффтопик детектед, заканчивайте пожалуйста.
To TS.
Уважаемый, а не могли-бы Вы простым языком рассказать, что должна сделать данная программа? Продраться через преобразования переменных я не смог.
Скорее всего все это можно решить более простыми путями, а учитывая Ваш while(...5000), время Вас особенно не беспокоит. Так и считывайте кнопки напрямую, поставив после этого delay(100). Уберите непонятные библиотеки. Теперь про экран - обновлять его нужно не чаще, чем скорость его обновления по даташиту. Не надо на него давить - нехорошо это даже по отношению к электронным компонентам.
Я еще не закончил, еще очень много доделывать, но вот более или менее закомментированный вариант. Я готов получать камнями, поэтому пишите.
вот более или менее закомментированный вариант.
Вас же попросили совсем не об этом. Не код выложить, а
Да, я вас не совсем правильно понял, так как занимаюсь кодом в перерывах между работой.
Это программа для устройства, которое будет считать количество хлопков за период времени заданный пользователем. В состав устройства входит модуль микрофона, зуммер, 3 кнопки, ардуино про мини, дисплей.
Кнопки предназначены для управления устройством (итак все понятно, но все же указал)
Дисплей для отображения информации о количестве хлопков, порог регистрации, время работы зуммера, время регистрации.
Микрофон как датчик хлопков
Зуммер для оповещения
а могу ли я в циклах for и while использовать не одну переменную, а сразу несколько через запятую?
а могу ли я в циклах for и while использовать не одну переменную, а сразу несколько через запятую?
можете, но результат, думаю, вас удивит...
А впрочем, покажите код. Может это я удивлюсь %)
Можно, но не рекомендуется. Типа, правило нехорошего тона. Но кто ж их выполняет.)
переменная i используется для позиционирования на дисплее текста, переменная bfr для отображения значений переменной, переменные mnd и mxd для ограничения значений выводимых на дисплей с 0 по 5. при нажатии кнопок mnd++ mxd ++ и mnd-- mxd --
Не сильно наглядно. Имело бы смысл при объявлении локальных внутрицикловых переменных. А так - инициализировать до цикла, инкрементировать внутри цикла. Будет понятней.