Неправильно работает скетч
- Войдите на сайт для отправки комментариев
Чт, 15/06/2017 - 14:13
#include <LiquidCrystal.h>
const int BUTTON_RIGHT = 1;
const int BUTTON_UP = 2;
const int BUTTON_DOWN = 3;
const int BUTTON_LEFT = 4;
const int BUTTON_SELECT = 5;
int x = 0;
int y = 0;
int button;
int getPressedButton()
{
int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0)
if (buttonValue < 100) {
return BUTTON_RIGHT;
}
else if (buttonValue < 200) {
return BUTTON_UP;
}
else if (buttonValue < 400){
return BUTTON_DOWN;
}
else if (buttonValue < 600){
return BUTTON_LEFT;
}
else if (buttonValue < 800){
return BUTTON_SELECT;
}
}
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );
void setup() {
lcd.begin(16, 2);
}
void loop() {
button = getPressedButton();
switch (button)
{
case BUTTON_RIGHT:
x+=1;
break;
case BUTTON_LEFT:
x-=1;
break;
case BUTTON_UP:
y-=1;
break;
case BUTTON_DOWN:
y+=1;
break;
case BUTTON_SELECT:
lcd.setCursor(x,y);
lcd.print(0);
break;
}
}
По идее, этот скетч должен перемещать курсор Вправо-Влево-Вверх-Вниз, по нажатию соответствующей кнопки, а по нажатию кнопки SELECT рисовать 0 в позиции курсора, но почему-то происходит иначе: кнопки работают как-то непонятно, курсор двигается в не пойми какое место, и по нажатию SELECT 0 рисуется не всегда.
границы не отслеживаешь. И кнопки дребежжять.
После строки 42 поставьте вывод в сериал значения переменной button - узнаете много интересного :)
И как с этим борьтя :)?
> И кнопки дребежжять.
В каком смысле?
И как с этим борьтя :)?
Ну, я же Вам сказал что сделать. Сделали? Посмотрите что выдаёт и подумайте.
> И кнопки дребежжять.
В каком смысле?
В самом прямом. Сделайте то, что я сказал - увидите.
Выдает аналоговое значение A0, внезапно. И что мне теперь делать?
> И кнопки дребежжять.
В каком смысле?
Вы никогда не слышали про дребезг кнопки (дребезг контактов)?
https://ru.wikipedia.org/wiki/%D0%94%D1%80%D0%B5%D0%B1%D0%B5%D0%B7%D0%B3...
https://uscr.ru/drebezg-kontaktov-i-sposoby-podavleniya-drebezga/
Выдает аналоговое значение A0, внезапно. И что мне теперь делать?
А Вы ЭТО сделали? Или теоретизируете?
Какое нахрен A0?
Вас что просили выдавать? Переменную button . Она у Вас может быть равна 1-5 и ничему другому и означает какая кнопка нажата.
Вот и выдайте и посмотрите что (и сколько раз) по мнению компьютера Вы нажимаете.
А с аналоговым входом способ, описанный во второй ссылке, сработает?
Один раз. Без нажатия кнопки выводится 263.
Один раз. Без нажатия кнопки выводится 263.
это потому что вариант "ни одна кнопка не нажата" в скетче вообще не предусмотрен и не обрабатывается
Один раз. Без нажатия кнопки выводится 263.
Закройте дыру в функции getPressedButton (после строки 32 напишите "else return NO_BUTTON;" )
Разумеется, определите константу NO_BUTTON выше.
После строки 42 поставьте "if (button == NO_BUTTON) return;"
И только после этого печать. Тогда она (печать) не будет Вам весь экран засирать.
Затем смотрите что выдаётся, соотвтетсвует ли это нажатым клавишам.
Заодно можете поставить печать x и y после строки 61. Тогда Вы сможете оценить адекватно ли программа отреагировала на нажатую клавишу.
Смотрите и разбирайтесь.
Правильно ли я понимаю, что с BUTTON_NONE проверка в getPressedButton должна быть buttonValue = 0? Этот код:
#include <LiquidCrystal.h> const int BUTTON_NONE = 0; const int BUTTON_RIGHT = 1; const int BUTTON_UP = 2; const int BUTTON_DOWN = 3; const int BUTTON_LEFT = 4; const int BUTTON_SELECT = 5; int x = 0; int y = 0; int button; int getPressedButton() { int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0) if (buttonValue < 100) { return BUTTON_RIGHT; } else if (buttonValue < 200) { return BUTTON_UP; } else if (buttonValue < 400){ return BUTTON_DOWN; } else if (buttonValue < 600){ return BUTTON_LEFT; } else if (buttonValue < 800){ return BUTTON_SELECT; } else if (buttonValue = 0){ return BUTTON_NONE; } } LiquidCrystal lcd(8, 9, 4, 5, 6, 7 ); void setup() { lcd.begin(16, 2); } void loop() { button = getPressedButton(); lcd.print(button); delay(1000); }Тоже выводит 263 до бесконечности.
неправильно. Строки 34-35 должны быть
else { return BUTTON_NONE;}Теперь работает. Правда, на кнопки надо нажимать очень сильно, прямо давить, иначе выводится 0. Проблема, скорее всего, аппаратная. Щас проверим еще кое-что.
Сделал это. При нажатии кнопок LEFT и RIGHT выводится бесконечный набор случайных символов, хотя должны выводиться x и y. При UP, DOWN и SELECT все ok. Правда, при UP и DOWN x и y почему-то не выводятся. Код:
#include <LiquidCrystal.h> const int BUTTON_NONE = 0; const int BUTTON_RIGHT = 1; const int BUTTON_UP = 2; const int BUTTON_DOWN = 3; const int BUTTON_LEFT = 4; const int BUTTON_SELECT = 5; int x = 0; int y = 0; int button; int getPressedButton() { int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0) if (buttonValue < 100) { return BUTTON_RIGHT; } else if (buttonValue < 200) { return BUTTON_UP; } else if (buttonValue < 400){ return BUTTON_DOWN; } else if (buttonValue < 600){ return BUTTON_LEFT; } else if (buttonValue < 800){ return BUTTON_SELECT; } else return BUTTON_NONE; } LiquidCrystal lcd(8, 9, 4, 5, 6, 7 ); void setup() { lcd.begin(16, 2); } void loop() { button = getPressedButton(); lcd.setCursor(x,y); switch (button) { case BUTTON_RIGHT: x+=1; lcd.print(x, y); break; case BUTTON_LEFT: x-=1; lcd.print(x, y); break; case BUTTON_UP: y-=1; lcd.print(x, y); break; case BUTTON_DOWN: y+=1; lcd.print(x, y); break; case BUTTON_SELECT: lcd.print(0); break; } }Господа! Он сам никогда не догадается... я сегодня буду "добрым самаритянином"....
==============
2ТС:
Нужно понимать, что пока ты отпустишь кнопку, программа войдет в loop() тысячи раз.
Поэтому нужно в статик или глобальной переменной помнить ПРОШЛОЕ значение кнопки.
Войда в loop() и опросив кнопки нужно выполнять свой свич ТОЛЬКО, если прошлое нажатие было NO_BUTTON, или как-там-ты-его-назвал.
При выходе из loop() нужно запомнить текущее состояние, как прошлое.
----------------------------
Понятно? Если нет - сорри. У меня не прокачен коррекционный педагог.
А если предыдущее состояние не было равно NO_BUTTON, то цикл будет один раз отрабатывать вхолостую?
Теперь вообще ничего не работает...
Код:
#include <LiquidCrystal.h> const int BUTTON_NONE = 0; const int BUTTON_RIGHT = 1; const int BUTTON_UP = 2; const int BUTTON_DOWN = 3; const int BUTTON_LEFT = 4; const int BUTTON_SELECT = 5; int x = 0; int y = 0; int button; int previous_button; int getPressedButton() { int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0) if (buttonValue < 100) { return BUTTON_RIGHT; } else if (buttonValue < 200) { return BUTTON_UP; } else if (buttonValue < 400){ return BUTTON_DOWN; } else if (buttonValue < 600){ return BUTTON_LEFT; } else if (buttonValue < 800){ return BUTTON_SELECT; } else return BUTTON_NONE; } LiquidCrystal lcd(8, 9, 4, 5, 6, 7 ); void setup() { lcd.begin(16, 2); } void loop() { button = getPressedButton(); lcd.setCursor(x,y); if (previous_button = BUTTON_NONE){ switch (button) { case BUTTON_RIGHT: x+=1; break; case BUTTON_LEFT: x-=1; break; case BUTTON_UP: y-=1; break; case BUTTON_DOWN: y+=1; break; case BUTTON_SELECT: lcd.setCursor(x, y); lcd.print(0); break; } } previous_button = button; }Одаренный Вы человек!
Понятно ли то, что на ОДНО нажатие должно быть ОДНО действие программы?
Попробуйте думать! Просто представить себе как именно работает программа, вами же и написанная.
СТОРОКА 48 "=" вместо "=="
Спасибо. Отвык от си-синтаксиса, уж извините.
А это что бы вас еще запутать в Cи(Си++ и.т.д) Скетч рабочий
/*Cl_an_btn5.ino */ class Cl_Sys;// предварительно объявить о создании класса Sys для послед подключения к нему //-----Cl_an_btn5----------------- class Cl_an_btn5 { byte pin ; // нога аналог клавиатуры void (*Do_right)(), (*Do_up)(), (*Do_down)(), (*Do_left)(), (*Do_select)(); byte read() { const int Right = 60; // ниже = нажата кнопка Right const int Up = 200; // ниже = нажата кнопка Up const int Down = 400; // ниже = нажата кнопка Down const int Left = 600; // ниже = нажата кнопка Left const int Select = 800; // ниже = нажата кнопка Select static int a ; a = analogRead(pin); if (a < Right) return 1; else if (a < Up) return 2; else if (a < Down) return 3; else if (a < Left) return 4; else if (a < Select) return 5; else return 0; } byte abtn, abtn_old; // старый и новый номер нажатой клавиши bool bounce_abtn = 0; // антидребезговый флаг uint32_t past = 0 ; // временной отчет public: // указатель на следующий элемент Cl_an_btn5 *pnt; // конструктора Cl_an_btn5(Cl_Sys *Sys, byte _pin, void (* _Do_right)(), void (* _Do_up)(), void (* _Do_down)(), void (* _Do_left)(), void (* _Do_select)()); // setup() void setup() { if (this->pnt != NULL) this->pnt->setup(); abtn = read() ; // прочитать реальное значение на выводе } // loop() void loop() { if (this->pnt != NULL) this->pnt->loop(); if (! bounce_abtn && abtn != read()) { // если прошел фронт изм на выводн bounce_abtn = 1; // выставить флаг past = millis(); // сделать временую засветку } else if ( bounce_abtn && millis() - past >= 5 ) { // если прошло антидребезговое время bounce_abtn = 0; // то снять флаг abtn_old = abtn ; abtn = read() ; // прочитать реальное значение на выводе if (abtn_old == 0) { if (abtn == 1) Do_right() ; if (abtn == 2) Do_up() ; if (abtn == 3) Do_down() ; if (abtn == 4) Do_left() ; if (abtn == 5) Do_select() ; } } } }; //-----Cl_Sys----------------- class Cl_Sys { public: Cl_an_btn5 *Start_btn5 = NULL; Cl_Sys() {} // setup() void setup() { for (Cl_an_btn5 *i = Start_btn5; i != NULL; i = i->pnt) i->setup(); } void loop() { for (Cl_an_btn5 *i = Start_btn5; i != NULL; i = i->pnt) i->loop(); } } Sys; //---------описание классов------------ Cl_an_btn5::Cl_an_btn5(Cl_Sys *Sys, byte _pin, void (* _Do_right)(), void (* _Do_up)(), void (* _Do_down)(), void (* _Do_left)(), void (* _Do_select)()) : pin(_pin), Do_right(_Do_right), Do_up( _Do_up), Do_down(_Do_down), Do_left(_Do_left), Do_select(_Do_select) { pnt = Sys->Start_btn5; Sys->Start_btn5 = this; } //----------Компоновка--------------------- #include <LiquidCrystal.h> LiquidCrystal lcd(/*RS*/8,/*Enable*/9,/*D4*/ 4,/*D5*/5,/*D6*/6,/*D7*/7); void Do_right () { lcd.setCursor(10, 1); lcd.print ("Right "); } void Do_up () { lcd.setCursor(10, 1); lcd.print ("Up "); } void Do_down () { lcd.setCursor(10, 1); lcd.print ("Down "); } void Do_left () { lcd.setCursor(10, 1); lcd.print ("Left "); } void Do_select() { lcd.setCursor(10, 1); lcd.print ("Select"); } Cl_an_btn5 *A_Btn = new Cl_an_btn5(&Sys,/*пин*/A0, /*обработчик Right*/Do_right,/*обработчик Right*/Do_up, /*обработчик Down*/Do_down,/*обработчик Left*/Do_left,/*обработчик Select*/Do_select); //-----------Main()----------------------- void setup() { lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("LCD Key Shield"); lcd.setCursor(0, 1); lcd.print("Press Key:"); Sys.setup(); } void loop() { Sys.loop(); }Правильно ли я понимаю, что с BUTTON_NONE проверка в getPressedButton должна быть buttonValue = 0?
Блин, ну я же Вам писал: "после строки 32 напишите "else return NO_BUTTON;" " А Вы чего написали?
Ага, Вижу, Вам уже подсказали и со второго раза до Вас дошло :)
poolman,
я категорически отказываюсь продолжать попытки Вам помочь и прошу коллег присоединиться.
Я Вам ДВАЖДЫ писал - поставьте печать и смотрите, что выводится! ДВАЖДЫ! Где в Вашем скетче печать? Что выводится?
У меня ощущение, что я зря трачу время.
Хотите помощи, делайте, что Вам говорят - не хотите - идите нафиг!