Почему не идет приращение переменной?
- Войдите на сайт для отправки комментариев
Ср, 10/11/2021 - 08:08
Добрый день
Недавно начал играть с ардуино, накидал небольшой код, но есть вопрос в котором не могу разобраться.
Не идёт приращение переменной.
#define CLK 7 #define DT 6 #define SW 4 #include "GyverEncoder.h" #include <OLED_I2C.h> #include <microDS3231.h> Encoder enc1(CLK, DT, SW); // для работы c кнопкой OLED myOLED(SDA, SCL); MicroDS3231 rtc; extern uint8_t MediumNumbers[]; byte segment; byte sec; char time[8]; char mod_time[8]; unsigned long timing_loop; unsigned long timing_blink; void setup() { enc1.setType(TYPE2); myOLED.begin(SSD1306_128X32); myOLED.setFont(MediumNumbers); Serial.begin(9600); rtc.begin(); } void loop() { enc1.tick(); if (segment > 0) { if (enc1.isClick()) segment++; if (segment > 3) segment = 1; if (sec > 100) { segment = 0; sec = 0; } sec++; } else { if (enc1.isClick()) segment = 1; } printTime(); Serial.println(sec); Serial.println(segment); delay(100); } void change_time() { } void printTime() { rtc.getTimeChar(time); Serial.println(time); }
По какой то причине sec++ не сохраняет значение при проходе loop, он всегда сбрасывается на 0.
Если sec++ вставить в самое начало цикла loop, тогда перестает запоминаться segment, он сбрасывается на 0.
Видимо где то есть глупая ошибка в логике, но не могу понять где
void loop() { sec++; enc1.tick(); if (segment > 0) { if (enc1.isClick()) segment++; if (segment > 3) segment = 1; if (sec > 100) { segment = 0; sec = 0; } } else { if (enc1.isClick()) segment = 1; } printTime(); Serial.println(sec); Serial.println(segment); delay(100); }
У меня было похожее. Помогло sec=sec+1. Колхоз, но времени разбираться не было. Работает и иже с ним.
Возможно, у вас другой случай
А что, если оставить в лупе только ++, println и delay - тоже постоянно нулю равно значение?
У вас sec увеличивается только при условии segment > 0.Сам segment увеличивается тоже только при условии segment > 0. А в каком месте segment становится больше нуля? Ну и что вас удивляет? ))
А в каком месте segment становится больше нуля?
В строке №47 при условии, что enc1.isClick() не 0.
А что там происходит с "enc1.isClick()" мы не знаем.
Вы нажимаете и отпускаете кнопку ?
А в каком месте segment становится больше нуля?
В строке №47 при условии, что enc1.isClick() не 0.
А что там происходит с "enc1.isClick()" мы не знаем.
Вот то то ж и оно. Пока на кнопку не кликнет, ничего не заработает ))
Пока на кнопку не кликнет, ничего не заработает ))
Ну, как бы кнопка для того и существует...)))
Это клик энкодера, его нажимаешь и сегмент увеличивается, доходит до трёх сбрасывается до одного, все в соотвествии с кодом.
А вот sec++ вообще никак не реагирует.
Хоть закликайся, увеличивается только segment.
У вас sec увеличивается только при условии segment > 0.Сам segment увеличивается тоже только при условии segment > 0. А в каком месте segment становится больше нуля? Ну и что вас удивляет? ))
Меня удивляет то, что вы не видите, что есть условие при котором segment будет больше 0, при этом это условие выполняется -_-
Ну... Раз выполняется, начт, всё работает нормально. Чо ты от нас-то хошь тогда?
А вот sec++ вообще никак не реагирует.
А Вы не пробовали сами хоть что-нибудь сделать для решения проблемы?
Вот, смотрите. ВСЕГДА (от слова АБСОЛЮТНО ВСЕГДА - БЕЗ ИСКЛЮЧЕНИЙ) если возникает затык, то начинать надо не с поста на форуме, а с элементарной вставки отладочного вывода и его изучения.
Вот я вставил кое что в Ваш код, смотрите
Строка №28 нужна практически всегда! По идее, она печатается один раз, но важность её в том, что если программа по каким-то причинам неожиданно перегружается, Вы это увидите по повторному появлению этой печати в листинге.
Ну, а остальное более или менее понятно.
Запустите, изучите и, если не поймёте проблему, выкладывайте свежий код и протокол работы, чтобы мы могли изучить.
А вот sec++ вообще никак не реагирует.
А Вы не пробовали сами хоть что-нибудь сделать для решения проблемы?
Вот, смотрите. ВСЕГДА (от слова АБСОЛЮТНО ВСЕГДА - БЕЗ ИСКЛЮЧЕНИЙ) если возникает затык, то начинать надо не с поста на форуме, а с элементарной вставки отладочного вывода и его изучения.
Вот я вставил кое что в Ваш код, смотрите
Строка №28 нужна практически всегда! По идее, она печатается один раз, но важность её в том, что если программа по каким-то причинам неожиданно перегружается, Вы это увидите по повторному появлению этой печати в листинге.
Ну, а остальное более или менее понятно.
Запустите, изучите и, если не поймёте проблему, выкладывайте свежий код и протокол работы, чтобы мы могли изучить.
Разумеется пробовал, а иначе как бы я понял, что sec не сохраняет значение и где то обнуляется?
Вот вывод монитора с вашим кодом:
При этом в конце кода стоят два принта которые выводят сегмент и сек, к моменту их вывода sec уже обнулена.
Но самое интересное, что если из кода вообще убрать sec = 0;
а если 59 ю закомментировать ?
Меня удивляет то, что вы не видите, что есть условие при котором segment будет больше 0, при этом это условие выполняется -_-
Вас удивляет совсем не то, что должно удивлять. Программа работает как задумано? Нет? Значит условие не выполняется. Условие выполняется, но переменная обнуляется? Значит где-то что-то ее обнуляет. И видимо это происходит где-то в недрах используемых библиотек. Если лень искать, где это происходит, просто переименуйте ее, например, в sec1
Вот вывод монитора с вашим кодом:
Впредь вставляйте с номерами строк! Ну как это теперь обсуждать?
Ну, вот уже из этого листинга мы видим, Вы нам пудрите мозги (возможно, и себе тоже), когда пишете
А вот sec++ вообще никак не реагирует.
Если бы ++ не работал, то мы НИКОГДА не увидели бы вывода (в хз какой строке) типа
Just after sec++: sec=1
А раз он есть, значит, ++ работает. Согласны?
Для меня ошибка уже очевидна, Вы распахиваете память и тупо записываете 0 в эту sec. И понятно в каком именно месте. Если для Вас это пока неочевидно, то можно поставить вывод sec буквально через строчку, только так, чтобы выводы отличались один от другого, и тогда Вы чётко увидите в каком месте и кто гадит.
Дальше сами или мне продолжать?
Вы распахиваете память и тупо записываете 0 в эту sec. И понятно в каком именно месте.
ура!
Евгений, как обычно, ТС забыл выделить место под терминатор?
PS - а вот и благодарность - кто-то уже влепил минус :)
а если 59 ю закомментировать ?
Это решает проблему, но что не так с 59?
Там стандартная функция для часов.
Пробовал обозвать переменную иначе, но это не помогает, она все равно обнуляется.
Разве вызов функции должен ее обнулять?
ура!
Евгений, как обычно, ТС забыл выделить место под терминатор?
Под терминатор?
что не так с 59?
Там стандартная функция для часов.
Разве вызов функции должен ее обнулять?
Ее обнуляет не "вызов функции", а ваша ошибка с выделением памяти. Читайте внимательно сообщение #15
16:06:20 это 8 символов + 1 символ #0 как окончание строки - ИТОГО 9 ...
Вы же выделили всего 8 байт под переменную time !!! Измените на 9 как минимум !!!
Загуглите "нультерминированные строки"
Разве вызов функции должен ее обнулять?
А самому узнать что не позволяет? Религия или камасутра?
Дальше сами или мне продолжать?
Ну, тваю ш дивизию! Мужики!
Ну, он бы сам дошёл очень скоро! И запомнил бы! Не столь важно про буфер, сколь про методику поиска ошибки!
А так Вы выложили всё на тарелочке и что? До следующего затыка? :-(((
...Ну, он бы сам дошёл очень скоро! ...
НЕ ВЕРЮ
он не туда смотрит как минимум
тем более что переменные объявлены как бы в другом порядке ...
Вот и посмотрели бы :-(
он не туда смотрит как минимум
Вот поставил бы после каждой строчки печать, и просто некуда бы больше смотреть.
Ну, он бы сам дошёл очень скоро!
ну соррри... я старался не прямо намекнуть
Правда, судя по местному опыту - примерно до 70% новичков даже после прямой подсказки не доходит.
Те, кто умеют думать - глупые вопросы на форумах не задают.
16:06:20 это 8 символов + 1 символ #0 как окончание строки - ИТОГО 9 ...
Вы же выделили всего 8 байт под переменную time !!! Измените на 9 как минимум !!!
Загуглите "нультерминированные строки"
Огромное спасибо!
Впервые столкнулся с этой проблемой, т.к. раньше не писал на С.
p.s. личное уважение, очень приятно было получить ответ от культурного человека в теме.
очень приятно было получить ответ от культурного человека в теме.
если б вы эту ошибку сами нашли, как вас пытались направить - пользы было бы больше, запомнили бы надолго.
А догадайтесь с одного раза кто виноват ???
Это пример с гита гАЙВЕРА :-))))))))))))))))))))))))))
ТСу. Можете читать/смотреть/учиться у гАЙВЕРА, но НИКОГДА не пользуйтесь его ГОВНОКОДОМ !!!
Кто бы сомневался.
Я , кстати , сам недавно попал в подобную ситуацию.
Даже перед заказчиком неудобно стало.
В промежуточной версии все работало как положено , а в предрелизной у заказчика дисплей падал после ввода параметров. При чем у меня все работало.
В общем в одной из правок был изменён вывод вводимых значений , точнее продублирован. Ну и соответственно под вводимые данные я выделил 4байта(3 знака на вывод), а по факту из за кириллицы нужно было выделять 7.
Самое печальное, что для того что бы отловить ошибку пришлось версию ПО заказчика у себя воспроизводить.
В моей видимо память как то по другому выделялась и на работу это переполнение никак не влияло.
Фигня. Вот я лет много назад на bash писал скрипт и не мог переменную инкрементить. Ну никак. Все строка получалась. )))
ЗВ: Конечно же разобрался потом, но кто бы мог подумать о таких «выкрутасах» в bash)))
У меня такая херня была. Написал программу, а переменные выдают жесть. Оказалось, что в библиотеке переменные с теми же именами.