Меню для сенсорного экрана

Sanya882
Offline
Зарегистрирован: 27.03.2016

Подскажите. Хочу сделать прибор. Нужно запрограмировать многоуровневое меню на сенсорном экране 3.5. Посоветуйте как сделать. Может у кого есть пример с меню. И куда вписать саму програму вызывающую от кнопок меню?

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Sanya882 пишет:

Подскажите. Хочу сделать прибор. Нужно запрограмировать многоуровневое меню на сенсорном экране 3.5. Посоветуйте как сделать. Может у кого есть пример с меню. И куда вписать саму програму вызывающую от кнопок меню?

Не далее как вчера видел тут где-то тему с сылкой, где один американский, показывал свою заготовку многоуровневого меню для 2.4" тача. А может и для большего дисплея, но когда я закачал скетч на ардуино, он пошёл с очень большими оговорками. Это касалось, в частности, инициализации дисплея, с которой у меня явные проблемы из-за очень китайского чипа управления.

Тач - тоже не работает, кстати. Но это всё особенности моего дисплея, у которого и чип непонятный и у тача выводы перепутаны некоторые. В общем я этот скетч буду ковырять и дальше. Сейчас поищу оригинал этого скетча у себя на компе, который отлично работал у того типа на видео... Ссылка на архив проекта

Вот, кстати, тоже интересная ссылка, может пригодится, мне пригодилась на 101% :Ссылка

Sanya882
Offline
Зарегистрирован: 27.03.2016

Спасибо. Вторая ссылка больше помогла. По первой у меня экран другой и библиотека UTFT. Есть тут тема тоже про сенсорное меню, но там проблема в том, что во втором меню сенсор остается как на главном. там надо делать метки, но я не в курсе как это делать. Может кто подскажет? http://arduino.ru/forum/programmirovanie/mnogostranichnoe-menyu-na-touch...

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Вот кстати если разобраться в тексте скетча того американского, то станет понятно что он организовал сброс областей считывания тача для каждого меню, с помощью подпрограммы (void - функции). Вообще-то очень интересный скетч. Я вот над ним сейчас ломаю голову...

Sanya882
Offline
Зарегистрирован: 27.03.2016

Чот не понял как там это реализованно.( А как сднлать в меню по моей ссылке, не в курсе?

Sanya882
Offline
Зарегистрирован: 27.03.2016

Неужели никто не знает, что нужно сделать чтоб сенсор переключался на другое меню, а не работал только на главном?

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Sanya882 пишет:

Неужели никто не знает, что нужно сделать чтоб сенсор переключался на другое меню, а не работал только на главном?

Подгляди концепцию , тут для символьного, но принцип перемещения по пунктам понятен.

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Sanya882 пишет:

Чот не понял как там это реализованно.( А как сднлать в меню по моей ссылке, не в курсе?

Я на 17 дней раньше тебя начал изучать IDE и только на пару дней опередил насчет меню. Так что для меня тут вопросов не меньше )))))

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Вот, кому требуется пример одноуровневого экранного меню для TFT дисплея с тачскрином писанный под "Adafruit_TFTLCD.h" с русскими комментами:

//*******************************************************************
//******  Пример использования тачскрина для управления меню  *******
//*******************************************************************

// Объявляем библиотеки
#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>

// Устанавливаем пины для тачскрина. Что куда - не знаю. Содрал))
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin

// Устанавливаем диапазон считывания в омах наверно. Точно не скажу
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

// Устанавливаем цвета для элементов меню
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define SPEC1   0x28E2

// Устанавливаем диапазон усилия нажатия на тачскрин
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
#define MINPRESSURE 1
#define MAXPRESSURE 1200

// Инициализируем дисплей
Adafruit_TFTLCD tft(A3, A2, A1, A0, A4);

// Инициализируем тачскрин
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

// Флаг выбранного меню. Пока не используется, но смысл - понятен
int ms = 0; 

void setup(void) {
  // запускаем экран:
  uint16_t identifier = 0x9341;
  tft.begin(identifier);
  
  // переворачиваем экран на 90град. и заливаем черным цветом
  tft.setRotation((tft.getRotation() - 1));
  tft.fillScreen(BLACK);

// устанавливаем размер текста, цвет, перемещаем курсор вниз экрана
// и пишем  X: и Y: , где будем показыаать координаты нажатого тача
  tft.setTextSize(3);
  tft.setTextColor(WHITE, BLACK);
  tft.setCursor(0, tft.height() - 20);
  tft.print("X: ");
  tft.setCursor(130, tft.height() - 20);
  tft.print("Y: ");

// Рисуем рамочки кнопок меню
  menu_draw();
}

void loop()
{
// в целях отладки я рисую зеленый квадратик в правом нижнем углу экрана
// который при считывании координат нажатия - мигает красным
  tft.fillRect(tft.width() - 20, tft.height() - 20, tft.width(), tft.height(), GREEN);
  
// Объявляем класс для считывания координат
  TSPoint p = ts.getPoint();

// Тут непонятно что делается, я просто скопировал, но - работает  
//pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
//pinMode(YM, OUTPUT);

// Переделываем омы в пиксели, 
// хотя в данном случае это непринципиально.
// Содрано с примера рисования, а там координаты
// нажатия нужны именно в пикселях, что бы под
// стиком сразу оставался след.
// Что бы вы не вздумали закомментить эти два оператора
// напомню, что проверка координат ведется
// именно по пиксельному диапазону и внизу,
// на нижней строке, отображаются координаты уже
// в пикселях!
  p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
  p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);

// Если элемент класса "р.z" укладывается в диапазон нажатия,
// будем считать что на тачскрин-таки нажали.
// Опять Рисуем рамочки кнопок меню, ждём немного
// и проверяем координаты нажатой точки

  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    menu_draw();
    delay (10);
    debug_P(p.x, p.y);
    }
}


//********************************************
//* Проверка координат и подсветка выбранного*
//********************************************
void debug_P(int x, int y) {
  
// Делаем квадратик в нижнем правом углу красным,
// что бы было понятно что данные считались
  tft.fillRect(tft.width() - 20, tft.height() - 20, tft.width(), tft.height(), RED);
  
// Забиваем пробелами предидущие показания
// и пишем новые координаты нажатой точки.
// Этот раздел сделан чисто с точки зрения
// отладки, для описания диапазона координат
// отображаемых элементов меню.
  tft.setCursor(50, tft.height() - 20);
  tft.print("    ");
  tft.setCursor(50, tft.height() - 20);
  tft.print(x);
  tft.setCursor(190, tft.height() - 20);
  tft.print("   ");
  tft.setCursor(190, tft.height() - 20);
  tft.print(y);


  if (y > 190 && y < 220 && x > 0 && x < 52) {

// Если выбран первый элемент меню, то он 
// подсвечивается рамочкой цвета "MAGENTA"
// и заполняется цветом "SPEC1".
// Флаг меню устанавливается в еденицу

    ms = 1;
    tft.drawRect(0, 0, 60, 40, MAGENTA);
    tft.drawRect(70, 0, 60, 40, WHITE);
    tft.drawRect(140, 0, 60, 40, WHITE);
    tft.drawRect(210, 0, 60, 40, WHITE);
    
    tft.fillRect(1, 1, 58, 38, SPEC1);
    tft.fillRect(72, 1, 57, 38, BLACK);
    tft.fillRect(142, 1, 57, 38, BLACK);
    tft.fillRect(212, 1, 57, 38, BLACK);
    return;
  }
  if (y > 138 && y < 178 && x > 0 && x < 52) {
    
// Ну и так далее, для каждого из 4-х элементов
    
    ms = 2;
    tft.drawRect(0, 0, 60, 40, WHITE);
    tft.drawRect(70, 0, 60, 40, MAGENTA);
    tft.drawRect(140, 0, 60, 40, WHITE);
    tft.drawRect(210, 0, 60, 40, WHITE);
    
    tft.fillRect(1, 1, 58, 38, BLACK);
    tft.fillRect(72, 1, 57, 38, SPEC1);
    tft.fillRect(142, 1, 57, 38, BLACK);
    tft.fillRect(212, 1, 57, 38, BLACK);
    return;
  }
  if (y > 88 && y < 121 && x > 0 && x < 52) {
    ms = 3;
    tft.drawRect(0, 0, 60, 40, WHITE);
    tft.drawRect(70, 0, 60, 40, WHITE);
    tft.drawRect(140, 0, 60, 40, MAGENTA);
    tft.drawRect(210, 0, 60, 40, WHITE);
    
    tft.fillRect(1, 1, 58, 38, BLACK);
    tft.fillRect(72, 1, 57, 38, BLACK);
    tft.fillRect(142, 1, 57, 38, SPEC1);
    tft.fillRect(212, 1, 57, 38, BLACK);
    return;
  }
  if (y > 33 && y < 73 && x > 0 && x < 52) {
    ms = 4;
    tft.drawRect(0, 0, 60, 40, WHITE);
    tft.drawRect(70, 0, 60, 40, WHITE);
    tft.drawRect(140, 0, 60, 40, WHITE);
    tft.drawRect(210, 0, 60, 40, MAGENTA);
    
    tft.fillRect(1, 1, 58, 38, BLACK);
    tft.fillRect(72, 1, 57, 38, BLACK);
    tft.fillRect(142, 1, 57, 38, BLACK);
    tft.fillRect(212, 1, 57, 38, SPEC1);
    return;
  }
// Если не выбран ни один элемент меню
// закрашиваем все квадратики черным цветом
  menu_draw();
}

//********************************************
//*********** fill all items black  **********
//********************************************

void menu_draw() {

// Заполняем все элементы меню черным цветом.
// Требуется если координаты нажатой области
// не подпадают ни под один дипапзон координат
// описанный в предидущей процедуре.
  
  tft.drawRect(0, 0, 60, 40, WHITE);
  tft.drawRect(70, 0, 60, 40, WHITE);
  tft.drawRect(140, 0, 60, 40, WHITE);
  tft.drawRect(210, 0, 60, 40, WHITE);
  tft.fillRect(1, 1, 58, 38, BLACK);
  tft.fillRect(72, 1, 57, 38, BLACK);
  tft.fillRect(142, 1, 57, 38, BLACK);
  tft.fillRect(212, 1, 57, 38, BLACK);
}

Могу сделать еще под один уровень, но мне, лично, и одного за глаза хватит. Так что могу, чисто в целях самообразования, написать переключение в другое меню, тоже из нескольких подпунктов.

Sanya882
Offline
Зарегистрирован: 27.03.2016

У меня ругается если я делаю проверку на установку флага

if (myTouch.dataAvailable()){myTouch.read();x=myTouch.getX();y=myTouch.getY();

       //======================================

        if ((y>=35) && (y<=70)) {

           if ((x>=10) && (x<=195)){ ms = 1; 
           waitForIt(10, 35, 195, 70);clearScreen();dispScreen1();} // переход

           if ((x>205) && (x<=390)){waitForIt(205, 35, 390, 70);}

        }

     
           }
        
      }
      if (myTouch.dataAvailable()){myTouch.read();x=myTouch.getX();y=myTouch.getY();
        //======================================
           if ((y>=35) && (y<=70) && ms = 1) {

           if ((x>=10) && (x<=195)){waitForIt(10, 35, 195, 70);clearScreen();dispScreen2();} // переход

           if ((x>205) && (x<=390)){waitForIt(205, 35, 390, 70);}

    }