Программируемая кнопка
- Войдите на сайт для отправки комментариев
Ср, 28/06/2017 - 19:04
Доброго времени суток, уважаемые форумчане!
Прошу сразу не пинать, новичок в программировании Ардуинки.
Задача такая, на TFT экране есть программная кнопка ВКЛ/ВЫКЛ, при клике на нее надо,
чтобы цвет кнопки поменялся с зеленного на красный (это реализовано) и при повторном клике,
цвет менялся обратно, т.е. с красного на зеленный. Вот небольшой пример из скетча.
#include <UTFT.h> //*********
#include <UTouch.h> //* Подключаем библиотек
extern uint8_t Various_Symbols_32x32[];
UTFT myGLCD(17, 38,39,40,41);
UTouch myTouch(6,5,4,3,2);
int x, y;
boolean onoff;
void setup() {
myGLCD.InitLCD(); //Инициализируем экран
myGLCD.clrScr(); //Очищаем экран
myTouch.InitTouch(); //Инициализируем тачскрин
myTouch.setPrecision(PREC_MEDIUM);
onoff = false; // кнопка выключена
DrawHomeScreen(); //Инициализация программной кнопки
}
void DrawHomeScreen(){
//кнопка вкл/выкл
myGLCD.setColor(0, 255, 0);
myGLCD.fillRoundRect (252, 172, 312, 218);
myGLCD.setColor(255, 255, 255);
myGLCD.drawRoundRect (252, 172, 312, 218);
myGLCD.setBackColor(0, 255, 0);
myGLCD.setFont(Various_Symbols_32x32);
myGLCD.print("l", 268, 179);
}
void BtnOnOff(){
if (myTouch.dataAvailable())
{
myTouch.read();
x=myTouch.getX();
y=myTouch.getY();
if ((x >= 252) && (x <= 312))
{
if ((y>172) && (y<218) && (onoff == false)){
myGLCD.setColor(255, 0, 0);
myGLCD.fillRoundRect (252, 172, 312, 218);
myGLCD.setColor(255, 255, 255);
myGLCD.drawRoundRect (252, 172, 312, 218);
myGLCD.setBackColor(255, 0, 0);
myGLCD.setFont(Various_Symbols_32x32);
myGLCD.print("l", 268, 179);
onoff = true;
}
}
else
{
if ((y>172) && (y<218) && (onoff == true)){
myGLCD.setColor(0, 255, 0);
myGLCD.fillRoundRect (252, 172, 312, 218);
myGLCD.setColor(255, 255, 255);
myGLCD.drawRoundRect (252, 172, 312, 218);
myGLCD.setBackColor(0, 255, 0);
myGLCD.setFont(Various_Symbols_32x32);
myGLCD.print("l", 268, 179);
onoff = false;
}
}
}
}
void loop() {
BtnOnOff();
}При нажатии на кнопку меняется цвет, при повторном нажатии, цвет остается.
Подскажите пожалуйста, что не так сделано?
Перелопатил инет, решения так и не нашел.
Заранее, оргомное спасибо!
Я так понимаю, что в первый раз цвет меняется в строка 43-50.
А обратно Вы надеетесь поменять его в строках 55-63.
Но строки 55-63 находятся в ветке else оператора if из строки 40. Т.е. они будут выполняться, когда нажатие было ВНЕ кнопки по x - попробуйте!
А как попробуете, выставьте правильно условия.
я для этого добавил логический тип данных onoff, по умолчанию false;
далее в условиях прописал, что нажимая по координатам на кнопку и имея в условии либо false, либо true, выполнить условие 42, прорисовать код 46-49, перевести onoff в true, что бы можно было выполнить условие 55, т.е. по следующему тапу кнопки с указанными координатами и условием onoff=true, выполнился код 56-62.
но else не срабатывает.
Вы решили со мной поспорить? А может, лучше внимательно свой код почитать?
Хорошо, Выпишите мне ВСЕ условия при которых Вы фиксируете нажатие на кнопку.
Я правильно понимаю, что нажатие на кнопку фикисруется при выполнеии следующего:
(x >= 252) && (x <= 312) && (y>172) && (y<218)
что означет, что в кнопку "попали" пальцем, а промахнулись.
Правильно?
Если правильно, то перечитайте мой пост ещё раз и исправляйте ошибки.
Евгений!
Я спорить ни скем не собираюсь, только прошу помощи.
Голова уже кипит от всевозможных вариантов, вот мозги и замылились.
Правильно, координаты кнопки (252, 312, 172, 218)
И по условию, что если я тапну в этой области тачскрина, то попаду в кнопку.
А почему промахнулся?
Подправил пример, но мой мозг взорвался. Кнопка правильно не работает.Теперь при нажатие моргает, и как отпустишь, не угадаешь, каим она будет цветом.
#include <UTFT.h> //********* #include <UTouch.h> //* Подключаем библиотек extern uint8_t Various_Symbols_32x32[]; UTFT myGLCD(17, 38,39,40,41); UTouch myTouch(6,5,4,3,2); int x, y; boolean onoff; void setup() { myGLCD.InitLCD(); //Инициализируем экран myGLCD.clrScr(); //Очищаем экран myTouch.InitTouch(); //Инициализируем тачскрин myTouch.setPrecision(PREC_MEDIUM); onoff = false; // кнопка выключена DrawHomeScreen(); //Инициализация программной кнопки } void DrawHomeScreen(){ //кнопка вкл/выкл myGLCD.setColor(0, 255, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(0, 255, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); } void BtnOnOff(){ if (myTouch.dataAvailable()) { myTouch.read(); x=myTouch.getX(); y=myTouch.getY(); if ((x >= 252) && (x <= 312) && (y>172) && (y<218)) { if (onoff == false){ myGLCD.setColor(255, 0, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(255, 0, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); onoff = true; } else if (onoff == true){ myGLCD.setColor(0, 255, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(0, 255, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); onoff = false; } } } } void loop() { BtnOnOff(); }Я так понял, надо править loop?
Давайте вернёмся к Вашему первому коду. Он почти хороший.
Вы можете мой первый пост прочесть наконец внимательно? Там написано
Но строки 55-63 находятся в ветке else оператора if из строки 40. Т.е. они будут выполняться, когда нажатие было ВНЕ кнопки по x - попробуйте!
Внимательно читайте!
1. if в сороковой строке задаёт условие попадания по X
2. строки 55-63 находятся в ветке ELSE этого if. Значит эти строки будут выполняться ТОЛЬКО если Вы по X промахнулись!
Внимательно это прочитайте и осознайте. Вы просто запутались в условиях.
Получилось?
А еще учтите пожалуста, что МК(микроконтролер) и человек живут с разными скоростями . Там где МК сделает 100тыс операций для человека пойдет о,1 секунда. Так что надо ловить момент когда не было "тапа вообще" и "тап" появился в нужном месте(нужной площадке). Вот только тогда надо переключать цвет. "Нет тапа"-> "тап в нужном месте " == идет переключение
Условие подправил, только теперь моргает, как и раньше писал.
#include <UTFT.h> //********* #include <UTouch.h> //* Подключаем библиотек extern uint8_t Various_Symbols_32x32[]; UTFT myGLCD(17, 38,39,40,41); UTouch myTouch(6,5,4,3,2); int x, y; boolean onoff; void setup() { myGLCD.InitLCD(); //Инициализируем экран myGLCD.clrScr(); //Очищаем экран myTouch.InitTouch(); //Инициализируем тачскрин myTouch.setPrecision(PREC_MEDIUM); onoff = false; // кнопка выключена DrawHomeScreen(); //Инициализация программной кнопки } void DrawHomeScreen(){ //кнопка вкл/выкл myGLCD.setColor(0, 255, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(0, 255, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); } void BtnOnOff(){ if (myTouch.dataAvailable()) { myTouch.read(); x=myTouch.getX(); y=myTouch.getY(); if ((x >= 252) && (x <= 312)) { //if ((y>172) && (y<218)){ if ((y>172) && (y<218) && (onoff == false)){ myGLCD.setColor(255, 0, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(255, 0, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); onoff = true; } else { // if ((y>172) && (y<218)){ if ((y>172) && (y<218) && (onoff == true)){ myGLCD.setColor(0, 255, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(0, 255, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); onoff = false; } } } } } void loop() { BtnOnOff(); }Я больше не могу на этот изврат смотреть!
#include <UTFT.h> //********* #include <UTouch.h> //* Подключаем библиотек extern uint8_t Various_Symbols_32x32[]; UTFT myGLCD(17, 38, 39, 40, 41); UTouch myTouch(6, 5, 4, 3, 2); int x, y; boolean onoff; void setup() { myGLCD.InitLCD(); //Инициализируем экран myGLCD.clrScr(); //Очищаем экран myTouch.InitTouch(); //Инициализируем тачскрин myTouch.setPrecision(PREC_MEDIUM); onoff = false; // кнопка выключена DrawHomeScreen(); //Инициализация программной кнопки } void DrawHomeScreen() { //кнопка вкл/выкл myGLCD.setColor(0, 255, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(0, 255, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); } void BtnOnOff() { if (myTouch.dataAvailable()) { myTouch.read(); x = myTouch.getX(); y = myTouch.getY(); if ((x >= 252) && (x <= 312) && (y > 172) && (y < 218)) { if (onoff == false) { myGLCD.setColor(255, 0, 0); myGLCD.setBackColor(255, 0, 0); } else { myGLCD.setColor(0, 255, 0); myGLCD.setBackColor(0, 255, 0); } myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); onoff = !onoff; } } } void loop() { BtnOnOff(); }Да, может изврат, но это кусок кода, адаптированный под пример, на экране в реальном проекте находятся несколько кнопок, в один стлобец, поэтому код по координатам не оптимизировал. Евгений и не просил этого,
просил разобраться с первым примером.
Что касается результата Вашего скетча, то он искомого результата не дает. Кнопка при нажатии моргает, и меняет цвет рандомно, а не как надо - противоположный.
За Вас весь код дописать ?
Да нужен еще тригер отпускания пальца с тача, в простейшем варианте поставьте задержку после 52 строки.
#include <UTFT.h> //********* #include <UTouch.h> //* Подключаем библиотек extern uint8_t Various_Symbols_32x32[]; UTFT myGLCD(17, 38, 39, 40, 41); UTouch myTouch(6, 5, 4, 3, 2); int x, y; boolean onoff; void setup() { myGLCD.InitLCD(); //Инициализируем экран myGLCD.clrScr(); //Очищаем экран myTouch.InitTouch(); //Инициализируем тачскрин myTouch.setPrecision(PREC_MEDIUM); onoff = false; // кнопка выключена DrawHomeScreen(); //Инициализация программной кнопки } void DrawHomeScreen() { //кнопка вкл/выкл myGLCD.setColor(0, 255, 0); myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setBackColor(0, 255, 0); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); } void BtnOnOff() { static bool btn = 0; if ( !btn && myTouch.dataAvailable()) { btn = 1; myTouch.read(); x = myTouch.getX(); y = myTouch.getY(); if (x >= 252 && x <= 312 && y > 172 && y < 218) { if (onoff == false) { myGLCD.setColor(255, 0, 0); myGLCD.setBackColor(255, 0, 0); } else { myGLCD.setColor(0, 255, 0); myGLCD.setBackColor(0, 255, 0); } myGLCD.fillRoundRect (252, 172, 312, 218); myGLCD.setColor(255, 255, 255); myGLCD.drawRoundRect (252, 172, 312, 218); myGLCD.setFont(Various_Symbols_32x32); myGLCD.print("l", 268, 179); onoff = !onoff; } } else btn = 0; } void loop() { BtnOnOff(); }Криво. Надо программу строить через ООП.
Спасибо боьшое! Писать не надо, дальше буду разбираться сам.
В ардуино новичек, предупреждал же. После С++, РНР, туговато идет, тем более если день мозги ломать (((
После С++, РНР, туговато идет, тем более если день мозги ломать (((
Для С++ есть среда разработки, есть объекты (в т.ч. Buttons), здесь все условно.
О чем вы? А это что?
/* Cl_Mech_BTN.ino (Светодиод+R=1кОм) ардуина пин 1 <==> пин 13 пин 2 <==> GND кнопка1 ардуина пин 1 <==> пин 2 программная подтяжка пин 2 <==> GND кнопка2 ардуина пин 1 <==> пин 3 программная подтяжка пин 2 <==> GND кнопка3 ардуина пин 1 <==> пин 4 программная подтяжка пин 2 <==> GND кнопка4 ардуина пин 1 <==> пин 5 программная подтяжка пин 2 <==> GND */ class Cl_Sys;// предварительно объявить о создании класса Sys для послед подключения к нему //----------------Cl_LED------------------------------------------------------------ class Cl_LED { byte pin; // нога для подключения светодиода bool inv; // 0 светодиод горит при 1/ 1 светодиод горит при 0 bool stat_ON = 0, led = 0; uint32_t time = 500, past = 0; public: //указатель на следующий компонент Cl_LED *pnt_LED; //конструктор Cl_LED(Cl_Sys *Sys, byte _pin, bool _inv); // setup() void setup() { pinMode(pin, OUTPUT);// подключить светодиод led = 0; digitalWrite(pin, led ^ inv) ; // погасить светодиод } // loop() void loop() { if (stat_ON && millis() - past >= time)OFF(); } // включить светодиод void ON() { stat_ON = 0; led = 1; digitalWrite(pin, led ^ inv) ; // зажечь светодиод } // включить светодиод на время void ON( uint32_t _time) { time = _time; stat_ON = 1; past = millis(); led = 1; digitalWrite(pin, led ^ inv) ; // зажечь светодиод } // выключить светодиод void OFF() { stat_ON = 0; led = 0; digitalWrite(pin, led ^ inv) ; // погасить светодиод } }; //----------------Cl_Mech_BTN------------------------------------------------------------ // класс на механич кнопку подкл к кнопке Ардуины. class Cl_Mech_BTN { byte pin; // номер ноги на кнопке void (* Do)();// указатель на обработчик bool btn, btn_old; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: //указатель на следующий компонент Cl_Mech_BTN *pnt_Mech_BTN; //конструктор Cl_Mech_BTN(Cl_Sys *Sys, byte _pin, void (* _Do)()); void setup() { pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой btn = digitalRead(pin); // прочитать реальное значение на выводе}; } void loop () { if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = millis(); // сделать временую засветку } else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = digitalRead(pin) ; // прочитать реальное значение на выводе if (btn_old && ! btn) Do(); } } }; //----------------Cl_Sys------------------------------------------------------------ class Cl_Sys { public: // указатели на блоки однотипных классов в системе Cl_LED * Start_LED = NULL; Cl_Mech_BTN * Start_Mech_BTN = NULL; void setup() { for (Cl_LED *i = Start_LED; i != NULL; i = i->pnt_LED) i->setup(); for (Cl_Mech_BTN *i = Start_Mech_BTN; i != NULL; i = i->pnt_Mech_BTN) i->setup(); } void loop () { for (Cl_LED *i = Start_LED; i != NULL; i = i->pnt_LED) i->loop (); for (Cl_Mech_BTN *i = Start_Mech_BTN; i != NULL; i = i->pnt_Mech_BTN) i->loop (); } }; //-----------------конструкторы классов вход в систему------------------------------- Cl_LED::Cl_LED(Cl_Sys *Sys, byte _pin, bool _inv): pin(_pin), inv(_inv) { pnt_LED = Sys->Start_LED; Sys->Start_LED = this; } Cl_Mech_BTN::Cl_Mech_BTN(Cl_Sys *Sys, byte _pin, void (* _Do)()): pin(_pin), Do(_Do) { pnt_Mech_BTN = Sys->Start_Mech_BTN; Sys->Start_Mech_BTN = this; } //------------------компоновка------------------------------------------------------- Cl_Sys *Sys = new Cl_Sys(); Cl_LED *LED1 = new Cl_LED(Sys,/*пин*/13,/*инверсия*/0);// создать светодиод LED1 void Do_BTN1() { LED1->ON(); } void Do_BTN2() { LED1->ON(1000); } void Do_BTN3() { LED1->ON(2000); } void Do_BTN4() { LED1->OFF(); } Cl_Mech_BTN *BTN1 = new Cl_Mech_BTN(Sys,/*пин*/2,/*обработчик*/Do_BTN1);// создать кнопку BTN1 Cl_Mech_BTN *BTN2 = new Cl_Mech_BTN(Sys,/*пин*/3,/*обработчик*/Do_BTN2);// создать кнопку BTN2 Cl_Mech_BTN *BTN3 = new Cl_Mech_BTN(Sys,/*пин*/4,/*обработчик*/Do_BTN3);// создать кнопку BTN3 Cl_Mech_BTN *BTN4 = new Cl_Mech_BTN(Sys,/*пин*/5,/*обработчик*/Do_BTN4);// создать кнопку BTN4 //------------------ main()---------------------------------------------------------- void setup() { Sys->setup(); } void loop() { Sys->loop(); }Тоже самое можно организовать и с графическими кнопками.
Я же говорю, что здесь новичек)))
Ардуинку только вчера в руки взял, пока разобрался технически, а тут уже и в бой.
Надо успеть подарок сделать человеку.
Всем огромное спасибо! ЕвгенийП за терпенье и подсказку, xDriver за скетч и оптимизацию, Вам тоже за скетч и введение в програие на девайсе.