Работа с сенсорным экраном на Arduino DUE

в 18:12, , рубрики: arduino due, tft, UTFT, Программинг микроконтроллеров, сенсорный дисплей, сенсорный экран, метки: , , ,

В предыдущей статье http://habrahabr.ru/post/196600/ мы подробно рассмотрели команды базовой библиотеки UTFT, предназначенной для работы с TFT дисплеями на Arduino. В этой статье мы рассмотрим Utouch – дополнение к базовой библиотеке, позволяющее работать с сенсорным экраном.

Работа с сенсорным экраном на Arduino DUE

1. Общие сведения

Это дополнение разработано тем же автором, что и базовая библиотека. Свежую версию можно скачать здесь:
http://www.henningkarlsen.com/electronics/library.php?id=55
Это дополнение не является самостоятельным и требует подключения базовой библиотеки UTFT.

Итак, рассмотрим более подробно дополнение Utouch, предназначенное для работы с сенсорным экраном, которым оборудовано большинство TFT дисплеев.

2. Начало работы с сенсорным экраном

Для работы с дополнением Utouch необходимо подгрузить его в Вашу программу и выполнить инициализацию. Естественно, при этом должна быть подгружена и инициализирована базовая библиотека UTFT. Напоминаем, что для нашего дисплея, о котором шла речь в предыдущей статье, инициализация выглядит следующим образом:
#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);

Теперь подгружаем дополнение и создаем объект – сенсорный экран с именем myTouch. В качестве параметров команде инициализации передаются номера пинов, к которым подключены сигналы TCLK, TCS, TDIN, TDOUT и IRQ. Эти параметры следует выяснить у производителя дисплея или шильда, посредством которого дисплей подключен к контроллеру.

В нашей модели сенсорного экрана вышеупомянутые сигналы подключены, соответственно, к пинам 6, 5, 4, 3 и 2. Напоминаем, что схему шильда, при помощи которого подключается дисплей можно найти здесь:
http://coldtears.lin3.siteonlinetest.com/files/CTE_DUE_shield.zip
а схему самого дисплейного модуля – здесь:
http://coldtears.lin3.siteonlinetest.com/files/3.2b.zip

Итак для нашего дисплея мы должны вставить в программу следующие строки:
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);

Далее необходимо проинициализировать в процедуре void setup() дисплей и сенсорный экран:
void setup() {
myGLCD.InitLCD();
myTouch.InitTouch();
}

Команда InitTouch также, как и команда InitLCD базовой библиотеки, задает вертикальную или горизонтальную ориентацию дисплея. По умолчанию задается горизонтальная ориентация. Все, теперь можно работать с нашим сенсорным экраном. Рассмотрим совсем простой пример, при помощи которого мы сможем убедиться, что сенсорный экран заработал. Скомпилируем следующую программу и загрузим ее в память контроллера:

#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);
void setup() {
  myGLCD.InitLCD();
  myTouch.InitTouch();
  myGLCD.clrScr();
  myGLCD.fillScr(255,0,0);
}
void loop() {
if (myTouch.dataAvailable()) {
myGLCD.fillScr(0,255,0);
}else {myGLCD.fillScr(255,0,0);}
}

При старте программы дисплей закрашивается красным цветом. Теперь коснемся экрана в любой точке – и дисплей окрасится в зеленый цвет.

3. Калибровка сенсорного экрана

Прежде чем продолжить работу необходимо выполнить еще одну важную процедуру – калибровку сенсорного экрана. В примерах программ, поставляемых с дополнением Utouch есть один очень важный пример, который называется UTouch_Calibration.
Для выполнения калибровки необходимо открыть этот пример через меню:
«Файл->Примеры->UTouch->Arduino->UTouch_Calibration».

ВНИМАНИЕ! Перед компиляцией не забудьте заменить строки UTFT myGLCD(….) и UTouch myTouch(….) на те, что нужны для нашего дисплея.

Также при калибровке необходимо правильно выбрать параметр TOUCH_ORIENTATION. Информацию о значении этого параметра для используемой модели дисплея можно найти в файле UTouch_Supported_display_modules.pdf, который поставляется вместе с библиотекой Utouch и размещается в ее корневой папке. Для нашего дисплея, например, должно быть установлено значение PORTRAIT, несмотря на то, что сам дисплей ориентирован горизонтально.

ВНИМАНИЕ! Это значение необходимо устанавливать только при калибровке сенсорного экрана, в дальнейшем ориентация экрана должна совпадать с ориентацией дисплейного модуля.

При запуске программа выводит на дисплей пояснительный текст и ждет прикосновения к сенсорному экрану. Затем на дисплее отображается 8 меток-крестиков по краям дисплея и красное окно с надписью PRESS в центре. Инструкция разработчиков сообщает, что необходимо коснуться подсвеченного крестика и удерживать касание до тех пор, пока подсветка на нем не погаснет, а на красном поле в центре не появится сообщение «RELEASE». Эту несложную операцию необходимо повторить для всех крестиков по очереди.
Кстати, разработчики советуют выполнять эту операцию стилусом или заостренной палочкой, не используя пальцы, это позволит повысить точность калибровки. По окончании калибровки на дисплей будут выведены три числа в 16-ричном формате. Например, вот такие:

CAL_X 0xBD95ECC8UL
CAL_Y 0x5EBC8000UL
CAL_S 0x0013F1DFUL

Эти три значения необходимо поместить в файл UTouch_CD.h, находящийся в корневой папке дополнения UTouch вместо тех значений CAL_X, CAL_Y и CAL_S, которые там указаны изначально. После этого дисплей будет работать правильно.

Теперь рассмотрим более подробно команды дополнения UTouch:

UTouch – создает базовый класс сенсорного экрана с заданным именем, в качесте параметров указывается способ подключения.

Команда имеет следующий вид:
Utouch _NAME_ (TCLK, TCS, TDIN, TDOUT, IRQ);

где _NAME_ — произвольное имя объекта «сенсорный экран», которое будет использоваться в качестве префикса при любом обращении к нему, а TCLK, TCS, TDIN, TDOUT и IRQ – номера пинов, которым подключаются соответствующие сигналы сенсорного дисплея.

Строка с этой командой размещается в области определений и должна предшествовать любым другим командам UTouch. Заданное имя объекта должно использоваться в качестве префикса ко всем последующим командам UTouch.

InitTouch – инициализирует сенсорный экран и задает горизонтальную или вертикальную ориентацию. В качестве параметра указывается идентификатор ориентации.

Если в этой команде указать PORTRAIT или 0 – будет выбрана вертикальная ориентация, если указать LANDSCAPE или 1 – горизонтальная. Обратите внимание, что ориентация сенсорного экрана должна совпадать с ориентацией дисплея. По умолчанию (без параметров) команда устанавливает горизонтальную ориентацию.

setPrecision – задает точность определения координат точки прикосновения к сенсорному дисплею. В качестве параметра передается идентификатор точности.

Всего определено четыре уровня точности, кодируемые числами от 1 до 4:

PREC_LOW – низкая точность;
PREC_MEDIUM – средняя точность;
PREC_HI – высокая точность;
PREC_EXTREME – очень высокая точность.

Естественно, уровень точности обратно пропорционален времени, затрачиваемому на определение координат. Оптимальным для большинства задач является уровень PREC_MEDIUM. Разработчики не рекомендуют использовать высокую и очень высокую точность для операций, требующих быстрого реагирования.

Разница между уровнями точности может быть проиллюстрирована примером UTouch_QuickDraw, поставляемым вместе с библиотекой UTouch. Эта программа позволяет рисовать на дисплее при помощи сенсорного экрана:

#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);
void setup() {
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myTouch.InitTouch(PORTRAIT);
  myTouch.setPrecision(PREC_MEDIUM);
}
void loop() {
  long x, y;
  while (myTouch.dataAvailable() == true)  {
    myTouch.read();
    x = myTouch.getX();
    y = myTouch.getY();
    if ((x!=-1) and (y!=-1)) {
      myGLCD.drawPixel (x, y);
    }
  }
}

Попробуйте скомпилировать этот пример с различными значениями параметра команды setPrecision и вы сразу же почувствуете разницу.

dataAvailable – функция, возвращающая логическое значение true, eсли в момент ее вызова зафиксировано касание сенсорного экрана. В остальное время – возвращает значение false.

Эта функция может быть использована как для определения момента касания, так и его продолжительности. В нашем первом примере, который мы приводили в разделе 2, конструкция:
if (myTouch.dataAvailable()) {
myGLCD.fillScr(0,255,0);
}else {myGLCD.fillScr(255,0,0);}

содержала вызов функции dataAvailable, по срабатыванию которой происходило изменение цвета дисплея, которое сохранялось на все время касания. Рассмотрим еще один пример – измерение времени касания в миллисекундах:

#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);
extern uint8_t BigFont[];
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);
void setup() {
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
myTouch.InitTouch();
myGLCD.clrScr();
}
void loop() {
unsigned long timeOld;
unsigned long timeNew;
if (myTouch.dataAvailable() == true){
timeOld=millis();
while (myTouch.dataAvailable() == true) {
timeNew=millis();
}
myGLCD.clrScr();
myGLCD.printNumI(timeNew-timeOld, 100, 100);
}
}

в момент касания сенсорного дисплея программа сохраняет текущее значение функции millis в переменной timeOld. Далее, до тех пор, пока касание сохраняется, программа постоянно обновляет текущее значение millis в переменной timeNew. Как только касание прекратилось – на дисплей выводится разность между этими двумя переменными, которая и будет равна времени касания в миллисекундах.

Итак, теперь мы умеем работать с событием «касание сенсорного экрана», можем определить момент касания, его продолжительность и момент отпускания. Осталось совсем немного – получить координаты точки касания. Для этого предназначены следующие команды:

read – запускает процедуру определения координат точки касания.

Эта команда не передает никаких параметров и не возвращает никакого значения. Ее следует запускать, когда функция dataAvailable принимает значение true. Полученные координаты в «сыром» виде сохраняются во внутренних переменных TP_X и TP_Y. Однако, эти данные не приведены к размерам дисплея и его разрешающей способности, поэтому для получения координат точки касания используются специальные функции getX и getY.

getX – возвращает значение X-координаты точки касания в пикселях относительно левого края дисплея.

getY – возвращает значение Y-координаты точки касания в пикселях относительно верхнего края дисплея.

При условии правильно выполненной калибровки и достаточной точности сенсорного экрана, координаты точки касания должны совпадать с координатами конкретного пикселя. Тип возвращаемых значений для этих двух функций – int.

Следующий пример при касании сенсорного экрана выводит на дисплей координаты точки касания в пикселях и в «сыром» формате:

#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);
extern uint8_t BigFont[];
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);
void setup() {
  myGLCD.InitLCD();
  myGLCD.setFont(BigFont);
  myTouch.InitTouch();
  myGLCD.clrScr();
}
void loop() {
int X_RAW;
int Y_RAW;
int X;
int Y;
if (myTouch.dataAvailable() == true){
myTouch.read();
X_RAW=myTouch.TP_X;
Y_RAW=myTouch.TP_Y;
X=myTouch.getX();
Y=myTouch.getY();
myGLCD.clrScr();
myGLCD.print("X", 100,80);
myGLCD.print("Y", 200,80);
myGLCD.print("PIX", 20,100);
myGLCD.print("RAW", 20,120);
myGLCD.printNumI(X, 100, 100);
myGLCD.printNumI(Y, 200, 100);
myGLCD.printNumI(X_RAW, 100, 120);
myGLCD.printNumI(Y_RAW, 200, 120);
}
}

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

#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);
extern uint8_t BigFont[];
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);
void setup() {
  myGLCD.InitLCD();
  myGLCD.setFont(BigFont);
  myTouch.InitTouch();
  myGLCD.clrScr();
}
void loop() {
int X;
int Y;
myGLCD.drawRect(100,100,150,150);
if (myTouch.dataAvailable() == true){
myTouch.read();
X=myTouch.getX();
Y=myTouch.getY();
if (X>100 && X<150 && Y>100 && Y<150) {
myGLCD.print("PRESSED", 100,200);
}else{myGLCD.print("       ",100,200);}
}
}

Программа рисует на дисплее прямоугольник-кнопку. При касании сенсорного экрана в области кнопки на дисплей выводится надпись «PRESSED», при касании за пределами прямоугольника надпись гаснет.

Еще один интересный пример. Эта программа рисует на дисплее прямоугольное «окно» и позволяет изменять его размеры путем перетаскивания нижнего правого угла. Конечно, это не полноценный Drag&Drop но очень похоже:

#include <UTFT.h>
UTFT myGLCD(CTE32HR,25,26,27,28);
extern uint8_t BigFont[];
#include <UTouch.h>
UTouch myTouch(6,5,4,3,2);
int X=100;
int Y=100;
void setup() {
  myGLCD.InitLCD();
  myGLCD.setFont(BigFont);
  myTouch.InitTouch();
  myTouch.setPrecision(PREC_EXTREME);
  myGLCD.clrScr();
  myGLCD.drawRect(0,0,X,Y);
}
void loop() {
if (myTouch.dataAvailable() == true){
myGLCD.setColor(0,0,0);
myGLCD.drawRect(0,0,X,Y);
myTouch.read();
X=myTouch.getX();
Y=myTouch.getY();
myGLCD.setColor(255,255,255);
myGLCD.drawRect(0,0,X,Y);
}
}

4. Заключение

Итак, теперь мы умеем пользоваться сенсорным экраном, можем определять момент касания и определять координаты точки касания, работать с простыми элементами управления, отображаемыми на дисплее. В следующей статье мы планируем рассмотреть еще одно дополнение к библиотеке UTFT – UTFT_Buttons, которое позволяет организовать работу с текстовыми и графическими экранными кнопками.

Автор: VadimEliseev

Источник

Поделиться

* - обязательные к заполнению поля