В цикле while не работает i++
- Войдите на сайт для отправки комментариев
Пнд, 19/05/2014 - 11:24
По какой-то причине while работает бесконечно, а i c самого начала равно 3, на дисплее всегда выводится 3, а чем может быть ошибка и как исправить? Довольно долго пытаюсь сделать - не работает и все тут./
int i=0; while(i<15) { uint8_t ppp=255; ppp = getFingerprintIDez(); //считываем с датчика номер под которым запомнен палец в переменнуюо ppp i++; lcd.setCursor(7, 1);// переводим курсор в 0 столбец 0 строку lcd.print(i); digitalWrite(beeper, HIGH); //короткие сигналы дают понять, что мы ждем палец) delay(30); digitalWrite(beeper, LOW); if (ppp!=255 && free_id[ppp]==1) //если палец валиден - открываем дверь) { lcd.setCursor(0, 0);// переводим курсор в 0 столбец 0 строку lcd.print(" Valid finger "); digitalWrite(door, HIGH); delay(5000); digitalWrite(door, LOW); break; } else //невалиден сей палец, мигаем светодиодом { digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); } }
Не понял, что я сделал с форматированием текста, и кнопки редактирования нет.
По какой-то причине while работает бесконечно, а i c самого начала равно 3, на дисплее всегда выводится 3, в чем может быть ошибка и как исправить?
Текст не весь. Есть следующие темные моменты:
1. Как объявлен массив free_id? Переменная i где объявлена? Рядом с free_id? Памяти точно хватает?
2. Судя по косвенным данным getFingerprintDez пишет во free_id массив, так? Может писать, например, в free_id[-1]
3. Какая Ардуина? Скетч большой?
Спасибо, вот полный код. Arduino Mega2560, getFingerprintDez - функция считывания отпечатка пальца, она просто return-ом выдает номер пальца в базе данных, массив free_id в начале работы программы считывается из eeprom.
Код собирался за пару вечеров, и там порой странные комментарии.
И я немного не понял, как free_id может быть связан с i, которая не хочет изменяться. Указателями я не пользовался.
Попробуйте объявить массив free_id[255] как 256 байтный - free_id[256]. Я сильно не вникал в программу, но увидел что индекс массива у вас может достигать значения 255. Видимо компилятор разместил переменную i сразу после этого массива, естественно она у вас затирается.
Спасибо, но к сожалению не помогло(
Вообще не могу представитть в чем проблема, при попытке сделать через for - i становится 2 и не изменяется, если использовать метку и условие с goto, то тоже ничего не работает.
Ещё в коде выше два раза int i=0;, но это ни на что не повлияло.
да работает ваш код. вставляйте задержку побольше и смотрите.
кстати, в конце while наверное что-то делайте в программе. обнулите i или в вечный цикл что-ли.
вот. и так до 14.
Да уж, красиво жить не запретишь, чтобы хранить единичку (1 бит) используется int.
Массив объявляется как
т.е. 255 * 2 байт, чтобы хранить 255 бит информации. Хватило бы и 8 байт, но это совсем другая история, там свои заморочки. Вообще то хоть и Мега2560, но памяти тоже не особо 8К всего, на этот массив free_id скушали килобайт. На стм32 я бы не парился, а здесь это уже звоночек. В любом случае мои предположение не подтвердились, переменная i и free_id расположены несколько в разных местах, потому наезда не будет. Опасное место строки 300-302, теоретически, если весь массив в 1, то зациклится, потому что freeFinger однобайтовая переменная. А если нажать на кнопку 256 раз, то вылезет за границы точно. Может нереально, но в жизни всякое бывает.
Да в 136 строке всё таки выкиньте int i, а то как обезьяна с гранатой. Во всяком случае лучше так не делать.
_Alexander, спасибо, у меня почему-то всегда на дисплее только тройка, завтра попробую задержку, но она и сама получается во время работы функций примерно 1,5с. А в чем нарисована схема? freezing?
kisofot, благодарю, из 136 убрал, случайно попало туда, когда менял циклы и пробовал переставлять инициализацию.
Я понимаю, что объявлять int-ом массив не правильно, код вообще надо оптимизировать, сейчас занимаюсь этим, я думаю вообще убрать этот массив и просто считывать значение из eeprom, чтобы не тратить оперативку.
На счет 300-302, там пока всего около 10 ячеек занято, free_id обозначает занятые\свободные ячейки под палец в памяти датчика отпечатка, но их всего около 170. За наводку на ошибку, спасибо)
А как можно free_id объявить, boolean?
Хм. если закомментировать 152ую строку, то цикл начинает работать нормально, вот уж не понимаю, что там происходит, по идее эта функция не должна никак к i относится. При этом если убрать из while i++;, а оставить лишь в начале loop() объявление int i=0;, то тогда на дисплей выводится 0, т.е. i=0, но если в цикле есть i++;, то на дисплее цифра 2.
Ещё попробовал инициализировать i 3, 5, 1, 0, если в while нет i++; то на дисплей выводится именно это число, но если же я пишу i++; то на дисплее именно 2.
Два варианта строк 151-155:
Хотя бы так, будет вдвое короче: uint8_t free_id[255]
Теперь такая штука, у Вас uint8_t ppp, а FingertypeDez возвращает int, Вы уже сделайте одинаково, иначе будет плохо, тем более если возвращает -1, то как оно его в байт затолкает, я не знаю. В любом случае это неправильно в беззнаковую переменную заносить отрицательное значение, надеясь на авось. Скорей всего в этом и проблема.
Я бы для начала сделал int ppp и проверял его на >= 0 И <255, это если в лоб, а вообще надо сразу корректно делать и типы не смешивать.
При -1 в uint вернётся 255, возможно так и было задумано
А я в этом не уверен, но проверить не на чем. Вы проверяли? То, что так и задумано - не вопрос, просто тут перекос на все 200%. Я уже объяснял, почему это неправильно.
Да и проверять незачем, нужно просто сделать правильно.
Нет, конкретно это переполнение я не проверял, но переполнение переменной или знака это известный приём. Ниже я задавал вопрос по преполнению, сам бы хотел знать является ли такая процедура для ардуино нормальной
Спасибо огромное, действительно, из-за переполнения ppp - остальная часть инта записывалась в чужую память, не додумался до этого. Раньше собирался сделать одинаковые типы, но в итоге забыл. Благодарю!!! Очень выручили!
Хочу увидеть это собственными глазами, вечером посмотрю в отладчике. А вообще это достаточно странное поведение компилятора. Ок, надеюсь это была реальная ошибка ;)