Алексей
я взял старый вариант которому больше двух лет где описывал каждую кпопку отдельно
Алексей
и тоже только три кнопки работает
Алексей
я хз, в чем дело
Ivansuper
Алексей Тюрин, [09.09.20 15:52] это main.cpp Алексей Тюрин, [09.09.20 15:52] #include <Arduino.h> //#include <LiquidCrystal_I2C.h> //const uint8_t COLUMN = 20; //const uint8_t LINE = 4; //LiquidCrystal_I2C lcd(0x27,COLUMN, LINE); bool btn_menu = false; bool btn_up = false; bool btn_down = false; bool btn_left = false; bool btn_right = false; //#include <_general.h> #include <_button.h> //#include <_lcd.h> void setup() { //Get_LCD_Print(); Serial.begin(9600); } void loop() { // Set_Button(8, btn_right); Set_Button_Left(9); if (btn_left == true) { Serial.print("LEFT "); } Set_Button_Down(10); if (btn_down == true) { Serial.print("DOWN "); } Set_Button_Up(11); if (btn_up == true) { Serial.print("Up "); } Set_Button_Menu(12); if (btn_menu == true) { Serial.print("Menu "); } } Алексей Тюрин, [09.09.20 15:53] это _button.h Алексей Тюрин, [09.09.20 15:53] //bool Set_Delay_Millis(uint32_t, uint32_t); void Set_Button_Menu(const uint8_t PIN_BTN_MENU) { static bool setup = false; if (!setup) { pinMode(PIN_BTN_MENU, INPUT_PULLUP); setup = true; } btn_menu = false; uint32_t first_time = millis(); uint32_t click_timer; while (digitalRead(PIN_BTN_MENU)) { btn_menu = false; } click_timer = millis(); if (click_timer - first_time < 20) return; click_timer = millis(); btn_menu = true; } void Set_Button_Up(const uint8_t PIN_BTN_UP) { static bool setup = false; if (!setup) { pinMode(PIN_BTN_UP, INPUT_PULLUP); setup = true; } btn_up = false; uint32_t first_time = millis(); uint32_t click_timer; while (digitalRead(PIN_BTN_UP)) { btn_up = false; delay(1); } click_timer = millis(); if (click_timer - first_time < 20) return; click_timer = millis(); btn_up = true; } void Set_Button_Down(const uint8_t PIN_BTN_DOWN) { static bool setup = false; if (!setup) { pinMode(PIN_BTN_DOWN, INPUT_PULLUP); setup = true; } btn_down = false; uint32_t first_time = millis(); uint32_t click_timer; while (digitalRead(PIN_BTN_DOWN)) { btn_down = false; delay(1); } click_timer = millis(); if (click_timer - first_time < 20) return; click_timer = millis(); btn_down = true; } void Set_Button_Left(const uint8_t PIN_BTN_LEFT) { static bool setup = false; if (!setup) { pinMode(PIN_BTN_LEFT, INPUT_PULLUP); setup = true; } btn_left = false; uint32_t first_time = millis(); uint32_t click_timer; while (digitalRead(PIN_BTN_LEFT)) { btn_left = false; delay(1); } click_timer = millis(); if (click_timer - first_time < 20) return; click_timer = millis(); btn_left = true; } /*void Set_Button(const uint8_t &PIN, bool &a) { static bool setup = false; if (!setup) { pinMode(PIN, INPUT_PULLUP); setup = true; } a = false; uint32_t first_time = millis(); uint32_t click_timer; while (digitalRead(PIN)) { a = false; if (Set_Delay_Millis(click_timer, first_time, 20)) a = true; } } */ Алексей Тюрин, [09.09.20 15:53] это _general.h Алексей Тюрин, [09.09.20 15:53] bool Set_Delay_Millis(uint32_t &a, uint32_t &b, const uint8_t &DELAY_MILLIS) { a = millis(); if (a - b < DELAY_MILLIS) return false; a = millis(); return true; }
Для начала -- после return писать код бесполезно
Ivansuper
Для продолжения -- здесь вряд ли, но лучше не пользоваться скоростями сериала низкими. Там задержка на принт символа огромная, и при достаточных количествах вывода код начнет задыхаться
Алексей
ну как бы выход вункциb void если время меньше 20 миллисекунд, что бы дальнейшее не обрабатывать,
Алексей
так и если монитор подключить, если три функции кнопки то можно менять значение любой цифры в плюс в минул если их 4 то все , не работают они тупо
Василий
данный код обречен, он взаимо зависим, надо переписывать - что бы небыло никаких ожиданий и переключений на ходу
Ivansuper
И финал -- ты в функциях для кнопок поставил while циклы безвыходные пока с пина не свалится ноль. В итоге если кнопка не нажата, то код застрянет в цикле
Василий
лучше сделать вообще по прерыванию
Ivansuper
Ты должен один раз проверить и выйти из функции
Ivansuper
Не умею
Научись : )
Ivansuper
Вбей в гугл, найдешь примеры
Ivansuper
Главное с прерываниями помни про аттрибут IRAM_ATTR. Ибо функция обязана быть в RAM и только там
Алексей
Ivansuper
Во-первых — видео и голосовые кидать это не очень хорошо. Не у всех есть возможность их прослушать, чтобы продолжить беседу
Алексей
ну извените
Ivansuper
Во-вторых — код изначально проблемный, поэтому аргумент "раньше работало" не очень хороший
Ivansuper
Я понимаю, что у тебя эмоции отчасти зло на неработающий код
Ivansuper
Но переделай ты нормально
Ivansuper
Что за плата у тебя?
Ivansuper
http://arduino.ru/Reference/AttachInterrupt
Ivansuper
Все. Это прерывания в ардуино
Алексей
ардуино уно, я по разному делал и с while и без него, но все работает ровно до трех кнопок. Спасибо буду читать
Ivansuper
Вешаешь прерывания на спад сигнала, по прерыванию ставишь button_pressed = true
Алексей
Вешаешь прерывания на спад сигнала, по прерыванию ставишь button_pressed = true
если два внешних прерывания то кнопок повесить можно тоже две? или столько сколько необходимо?
Ivansuper
Но на уно их только два. Капец
Алексей
Ну я вот и прочел про два, поэтому у меня и вопрос этот появился
Ivansuper
Ivansuper
И че то я не пойму, ты еще в булевыми финты какие то делаешь
Ivansuper
btn_menu = digitalRead() == LOW; Все
Алексей
Ну да если кнопка нажата, тоесть цикk while но время меньше 20 миллисекунд прошло то в любом случае это лож, а если , больше то это истина
Ivansuper
По скольку ты сделал PULLUP, у тебя по умолчанию оно вверх подтянуто, и для нажатия тебе надо коротить к земле
Алексей
это антидребезг
Ivansuper
К слову может ты кнопку коротишь не к земле, и от того у тебя часть работает а часть нет
Ivansuper
это антидребезг
это не антидребезг, а оверэнжиниринг : )
Алексей
Ладно, спасибо за помощь, буду переделывать
romanetz
Эх, не работал человек с ПЛК.... Там если время скана (цикла while(1) главного) превысишь - по башке от гипервизора прилетает )) сразу учишься писать код без бесконечных циклов
romanetz
И непонятных ожиданий )
romanetz
Фронт задетектил нужный, таймер запустил - и дальше опрашивать )
Алексей
Эх, не работал человек с ПЛК.... Там если время скана (цикла while(1) главного) превысишь - по башке от гипервизора прилетает )) сразу учишься писать код без бесконечных циклов
да я ведь не программист, меня научили так. Но ведь пока нажата кнопка один черт контроллер ни чего не делает пока ее не отпустишь, хоть через вайл писать хоть без него
romanetz
А почему, собсно, он ничего не делает? Пусть крутится в основном цикле тогда ) если нужно будет, чтобы делал - сможет
romanetz
Например, я делал аналогичную затею с зажатием кнопок в меню, только на "заднем плане" ещё строчки бегущие на дисплей выводились
romanetz
Названия песен, по-моему, если помню правильно
Ivansuper
А разве ардуина не сделает суицид и ребут от долгой работы в лупе без yield?
Алексей
как мне обьясняли что пока кнопку не отпустишь то в любом разе контроллер не на что не реагирует, не принимает с датчиков значения и тд и тп
Ivansuper
как мне обьясняли что пока кнопку не отпустишь то в любом разе контроллер не на что не реагирует, не принимает с датчиков значения и тд и тп
Тут надо развернуть стол понятий — это ТЫ ничего не делаешь, а у контроллера может быть что угодно в фоне
romanetz
А разве ардуина не сделает суицид и ребут от долгой работы в лупе без yield?
Если только там с вочдогом какие-то приключения, надо 🐈 смотреть
romanetz
Тут надо развернуть стол понятий — это ТЫ ничего не делаешь, а у контроллера может быть что угодно в фоне
👍 В более других контроллерах ещё фоном сеть бывает, юзби или ещё какой-то канал связи, который отрабатывать надо вовремя )
Алексей
Ну если бы это был двух ядерный контроллер, попробуйте нажать кнопку при передаче данных в сериал, много будет передаваться их туда?
romanetz
Да все, собсно, которые должны быть отправлены
romanetz
При нажатиях кнопок интересуют их фронты и длительность состояния
romanetz
Фсё!
romanetz
Не надо там сто ядер для этого
Алексей
пробую не получается, вы уж ссаными тряпками не кидайтесь , я совсем новичок
romanetz
typedef struct { bool prev_button_state; bool changed; unsigned long state0_length; unsigned long state1_length; } button_struct; void button_processing (bool button_state,button_struct* t,unsigned long scantime) { t->changed=(button_state!=t->prev_button_state); t->state0_length=!button_state?t->state0_length+scantime:0; t->state1_length=button_state?t->state1_length+scantime:0; t->prev_button_state=button_state; }
romanetz
я бы как-то так это замутил
romanetz
по вкусу прибавить проверки на нулевой указатель, объявления переменных и работу в цикле
Ivansuper
Он сказал, что он не программист совсем. У него там паника начнется
romanetz
scantime берётся из таймера какого-нибудь, как время между вызовами функции
Алексей
Он сказал, что он не программист совсем. У него там паника начнется
Не начнется, посижу долго долго , почиаю и узнаю, но пока не понятно да
Ivansuper
: )
romanetz
Но на уно их только два. Капец
а там PCINT нету разве?
romanetz
328 мега - это старшая сестра 48/88/168? а там PCINT были... давно с аврками дел не имел, поправьте, если что
romanetz
как раз прерывания по фронтам/портам, почти по всем ножкам
Ivansuper
а там PCINT нету разве?
К сожалению тут не скажу ничего. Те часы, что я провел за нативными ардуино платами, можно по пальцам пересчитать
romanetz
Ну тоды, если очень хочется, можно поспать даже контроллеру, если ему больше делать нефиг )) уменьшим жор МК и свой вклад в глобальное потепление )))
AntikillerVova 🇷🇺
как мне обьясняли что пока кнопку не отпустишь то в любом разе контроллер не на что не реагирует, не принимает с датчиков значения и тд и тп
Какую кнопку? Кнопку резет если только. Все остальные вход/выход он реагирует, проверка простая, выводи данные с ацп на дисплей а когда нажимаешь кнопку( работа команды по низкому или высокому фронту) то прибавьте число 10. И ты увидишь что мк выполняет основной код и ему фиолетово на удержание кнопки.
AntikillerVova 🇷🇺
Как он реагирует на на фронты я точно не знаю, но скорее всего если отработать надо по спаду, то он фиксирует "1", и после каждого пролёта строчки где указан отработать по спаду он сравнивает с "1" если без изменений то пролетает дальше, если было изменение то он выполняет код
AntikillerVova 🇷🇺
Может я не прав
AntikillerVova 🇷🇺
Но как мне говорили, что код выполняется по очереди(по строчно)
AntikillerVova 🇷🇺
Ах да, на ардуино используй miles вместо delay
AntikillerVova 🇷🇺
Чтобы мк не халявничел