Помогите понять ошибку в цикле for

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

Здравствуйте!
Писал функцию для плавного включения/отключения светодиодной ленты и наткнулся на некоторые трудности.
Для начала сам код:

void doNightLight(bool buttonstate, uint16_t value) {
  static bool flag = true;
  if (buttonstate && flag) {
    for (uint16_t i = 0; i <= value; i++)
    {
      analogWrite(pinNightLight, i);
      delay(25);
    }
    flag = !flag;
  } else  if (!buttonstate && !flag) {
    for (uint16_t i = value; i > 0; --i) // вот не хочет работать условие i = 0, i >= 0;
    {
      analogWrite(pinNightLight, i);
      delay(25);
    }
    //analogWrite(pinNightLight, 0); // костыль!!!! но так лента гаснет полностью.
    flag = !flag;
  }
}

Собственно проблема в том, что лента при таком условии не гаснет полностью. Если в условии указать "i >= 0" то цикл зацикливается. Но при том, лента выключаясь, начинает светиться с максимума (а не от значения value). Сам цикл проверил в отладке, все норм.

Помогите, пожалуйста, понять где я налажал ))

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

Просто для понимания: использую сенсорную кнопку с фиксацией.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Из каких соображений в первом цикле идёт "i++", а во втором "--i" ?
В чем разница синтаксиса понимаете ?

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

uint заменить на int, --i на i--, условие цикла изменить на >=0.

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

Kakmyc пишет:
Из каких соображений в первом цикле идёт "i++", а во втором "--i" ? В чем разница синтаксиса понимаете ?

Первый плавно включает, второй плавно выключает.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

А вообще зачем тебе беззнаковый тип переменной инкремента ?

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

Спасибо! Все заработало с интом. Но тепер не могу понять, как итератор вышел за пределы значений uint16_t...

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Как должен был , так и вышел.
Для uint16_t при декременте, после нуля идёт 65635, что опять же больше нуля.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Беззнаковая величина всегда >=0, поэтому и зацикливается. Используйте знаковые величины для переменных цикла.

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

Kakmyc пишет:
А вообще зачем тебе беззнаковый тип переменной инкремента ?

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

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

andriano пишет:

Беззнаковая величина всегда >=0, поэтому и зацикливается. Используйте знаковые величины для переменных цикла.

Спасибо! Полезная информация )

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Можно и беззнаковую конечно, но зачем ?

for (uint16_t i=value;i<=0&&i<=value;i--)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А зачем лишняя проверка?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

andriano пишет:

А зачем лишняя проверка?


Чтоб используя беззнаковый декремент включить 0 в результаты

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А зачем использовать беззнаковые величины? Только для того, чтобы потребовались лишние вычисления при организации цикла?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

andriano пишет:

А зачем использовать беззнаковые величины? Только для того, чтобы потребовались лишние вычисления при организации цикла?

Это нужно спросить у ТС'а

olivergreen
olivergreen аватар
Offline
Зарегистрирован: 15.08.2016

Я просто учусь пытаясь практиковать. Я не совсем понял, мою задачу можно решить одним циклом?

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

olivergreen, делайте двумя, овчинка выделки не стоит.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Kakmyc пишет:
Это нужно спросить у ТС'а

Нет, ну у ТС'а возникла проблема "почему цикл зацикливается". Соответственно, ошибку можно устранить разными способами, как более естественными, так и более "противоестественными". Лишние вычисления лично я считаю относящимися ко второму варианту.