Особенности работы функции constrain
- Войдите на сайт для отправки комментариев
Вс, 29/03/2020 - 17:01
Тема траблы. Ограничиваю переменную диапазоном от 5 до 99:
powerState = constrain(powerState, 5, 99);
но энкодер продолжает выдавать при вращении значения от 4 до 100. Пробовал ставить десятичку типа:
powerState = constrain(powerState, 5.0, 99.0);
всё равно проскакивает.
Пробую так:
powerState = constrain(powerState, 5,1, 99.1);
- при прямом ходе всё равно упирается, а при обратном - проскакивет мимо 1 цифру. Никто не сталкивался? В доках ничего не сказано...
То, что Вы пишете невозможно потому, что это невозможно никогда, ошибка у Вас в другом месте.
Будьте любезны, выложите предельно короткий, но полный (чтобы можно было скомпилировать и запустить) скетч, который демонстрирует проблему. Ибо constrain - это тупой как валенок макрос
и никаких особенностей у него нет и быть не может.
Код писать для повторения нереально, много подвязок и нестандартных либ (которые, в принципе, всегда нормально работали. Попробую объяснить без кода, ибо так будет проще.
Имеем функцию опроса энкодера через interrupt. Отлично считает +1 и -1, всё зашибись. Задаю через constrain диапазон, к примеру, от 5 до 95. Имею также кнопку Shift, после нажатия на которую приращение энкодера становится +/-10. И тут, интенсивно крутя энк, я с лёгкостью перелетаю (точнее, не я, а constrain) через заданный диапазон.
Тут сегодня засилие школьнегофф???
Кто мешает разбить всё это на ДВА условия??? Типа если это меньше 5 то равно 5 и больше 99 равно 99. ФСЁ!!!
А печатать в сериал до и после ограничения не пробовали?
Dorfman, посмотрите аккуратнее типы данных граничных значений и сравниваемой переменной. Если переменная объявлена беззнаковым типом, а её значение по смыслу должно стать отрицательным, то появляется знаковый разряд, интерпретация которого в двоичном коде будет разной у беззнакового и знакового чисел. Сравнение может сработать ошибочно.
Вот как раз условия-то и работают. А я спрашЭвал про конкретную функцЫю.
Увы, она "пролетает" мимо числа 128, я уже думал об отрицательных... Условия по if работают, а constrain нет, почему вопрос и поднялся. После того как потом шевельнёшь энкодер в любую стороны, constrain "исправляется" и сбрасывается на 128. Хех, ладно, потом ещё на досуге поколдую. Но спасибо за помощь.
Увы, она "пролетает" мимо числа 128, я уже думал об отрицательных... Условия по if работают, а constrain нет, почему вопрос и поднялся. После того как потом шевельнёшь энкодер в любую стороны, constrain "исправляется" и сбрасывается на 128. Хех, ладно, потом ещё на досуге поколдую. Но спасибо за помощь.
Вам же сказали, что без кода вам никто помочь не сможет. Но вы упорно проявляете свои ламерские принципы.
А пролетаем мимо 128 потому , что переменная у вас объявлена как знаковая восьми битная, что лишний раз является признаком ламера. Вам нужно в песочницу. Колдун, блин....
Вы уже столько времени потратили на болтовню здесь, что можно было уже два демонстрационных кода написать. Давно бы всё разрешилось.
Вы уже столько времени потратили на болтовню здесь, что можно было уже два демонстрационных кода написать.
так ему не надо решать проблему, ему общения не хватает...
Сел и переписал с нуля код, упростив и выбросив мишуру. Всё подробно откомментил. Вращая энкодер, мы меняем значение mainMenuPosition - это тот пункт меню, на который наведён фокус (в моём случае стрелка из строк 118-126). В функции mainMenuSelector() стоит ограничение значений меню от 0 до 7 с помощью constrain. При врашении энкодера на приращение значение добегает до 7 и на этом останавливается, что подтверждается и стрелкой, и выводом значения переменной mainMenuPosition. При обратном вращении энкодера происходит декремент, но после значения mainMenuPosition == 0 на контрольном индикаторе возникает на мгновение цифра 255, и потом спрыгивает на 7, то есть нижняя граница перескакивается.
Такая же петрушка проявляется, когда вставляю этот же обработчик энкодера и ограничения с constrain в остальные функции: sceneSelector(), void effectSelector(), speedSelector() и powerSelector().
Вроде как всё работает, но при обратном вращении происходит этот непонятный глюк. Вот так выглядит сам дисплей:
Dorfman , вы читаете что вам пишут? - разберитесь. чем отличаются знаковые и беззнаковые переменные
опишите mainMenuPosition как int - и проверьте еще раз
АЁ... голова садовая! Я пробовал, но не ту переменную менял, поэтому и результата не было. Работает! Огромное спасибо!
М-да, всё-таки косяк был не в этом... Я, баран, протупил, и допустил логическую ошибку. Сейчас, когда constrain стоИт ниже счётчика, всё работает как с int, так и с byte! То есть изначально у меня 8-я и 9-я строки были поменяны местами, поэтому ограничение происходило ДО переполнения на 1, вот и провозился 2 дня впустую, пока не нашёл...
Ну так сильно голову то пеплом посыпать не нужно. Нужно просто понять, что как правило в 99.99% в ошибках виноват автор кода. Так что изначально нужно искать ошибку у себя.
Это я знаю и понимаю, просто неправильно подошёл к вопросу. Нужно было поэтапно решать каждый функционал, а я набросился одновременно на всё. В результате получил 4к кода, в котором потом сам же и застрял. Ещё раз всем спасибо.
да и научиться работать с кнопками тоже не помешает.
да и научиться работать с кнопками тоже не помешает.
А при чём тут кнопки? У меня энкодер с раздолбанной кнопкой, и новый сейчас нет возможности купить (все рынки и единственный радиомагазин в городе закрыты). Программный дебонс срабатывает через раз, вот и юзаю через делей, пока новый не куплю. И я уже об этом писал выше.
Или я что-то не понял? Да и вообще, вопрос был по конкретной функции, которую я по своей невнимательности прописал раньше приращений энкодера.