| |
|
|
Segger
- emWin
- Touch Screen Support
emWin now supports touch screens.
Touch screen support for emWin is now available. This includes a low
level driver, which handles the analog input (from an 8 bit or better
AD-converter), debouncing and calibration of the touch screen. The window
manager deals with touch messages and widgets such as button objects.
It takes no more than one line of code to create a button or other widget,
which then automatically handles touch messages and reacts accordingly.
The widgets have different attributes, which makes them very flexible.
Because in most cases the default attributes are fine, they are easy to
use. Of course the touch screen support is written in plain ANSI-"C".
Touch screen simulation
The touch screen simulation is integrated into the regular emWin simulation.
The mouse events are used to simulate the touch screen. Pressing the left
mouse button anywhere in the display area has the same effect has touching
the touch panel in the real hardware. Needless to say that the real application
behaves exactly like the simulation. The simulation can be used to write
the user interface of your application and can be send as simple exe file
to anybody for discussion, demonstration or verification.
Do I need multitasking for the touch support ?
No. The touch screen has to be polled periodically (Usually 100 times
per second), but this does not have be done with the help of a real time
OS. You may also use a timer interrupt or simply poll the touch screen.
Sample program
Below you see 2 screenhots of the sample program. This sample program
is compact and easy to understand.
In about 300 lines of "C" code we show you how easy it is to create buttons,
how you may react to the events and how to calibrate the touch screen
(if necessary). The sample also creates an antire "touch" keyboard on
the display.
Download the sample simulation ! (150kb)
Screenshot touch screens

"C" source of the sample program
/*********************************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (C) 2000 SEGGER Microcontroller Systeme GmbH *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
File : Main.c
Purpose : Application program in windows simulator
---------------------------END-OF-HEADER------------------------------
*/
#include "GUI.h"
#include "GUITouch.h" /* Located in GUIx, will include GUITouch.conf.h */
#include "Button.h"
#include "Edit.h"
extern const GUI_BITMAP bmSeggerLogoBlue;
#define countof(Obj) (sizeof(Obj)/sizeof(Obj[0]))
/*
**********************************************************************
*
* ExecCalibration
*
**********************************************************************
*/
void ExecCalibration(void) {
int ax_Phys[2],ay_Phys[2];
/* calculate log. Positions */
const int ax[2] = { 15, LCD_XSIZE-1-15};
const int ay[2] = { 15, LCD_YSIZE-1-15};
GUI_TOUCH_SetDefaultCalibration();
/* Calibrate upper left */
GUI_SetBkColor(GUI_RED);
GUI_Clear();
GUI_SetColor(GUI_WHITE); GUI_FillCircle(ax[0], ay[0], 10);
GUI_SetColor(GUI_RED); GUI_FillCircle(ax[0], ay[0], 5);
GUI_SetColor(GUI_WHITE);
GUI_DispStringAt("Press here", ax[0]+20, ay[0]);
do {
GUI_TOUCH_tState State;
GUI_TOUCH_GetState(&State);
if (State.PressedCnt) {
ax_Phys[0] = GUI_TOUCH_GetxPhys();
ay_Phys[0] = GUI_TOUCH_GetyPhys();
break;
}
GUI_Delay (100);
} while (1);
/* Tell user to release */
GUI_Clear();
GUI_DispStringAt("OK", ax[0]+20, ay[0]);
do {
GUI_TOUCH_tState State;
GUI_TOUCH_GetState(&State);
if (State.PressedCnt==0) {
break;
}
GUI_Delay (100);
} while (1);
/* Calibrate lower right */
GUI_SetBkColor(GUI_RED);
GUI_Clear();
GUI_SetColor(GUI_WHITE); GUI_FillCircle(ax[1], ay[1], 10);
GUI_SetColor(GUI_RED); GUI_FillCircle(ax[1], ay[1], 5);
GUI_SetColor(GUI_WHITE);
GUI_SetTextAlign(GUI_TA_RIGHT);
GUI_DispStringAt("Press here", ax[1]-20, ay[1]);
do {
GUI_TOUCH_tState State;
GUI_TOUCH_GetState(&State);
if (State.PressedCnt) {
ax_Phys[1] = GUI_TOUCH_GetxPhys();
ay_Phys[1] = GUI_TOUCH_GetyPhys();
break;
}
GUI_Delay (100);
} while (1);
GUI_TOUCH_Calibrate(GUI_COORD_X, ax[0], ax[1], ax_Phys[0], ax_Phys[1]);
GUI_TOUCH_Calibrate(GUI_COORD_Y, ay[0], ay[1], ay_Phys[0], ay_Phys[1]);
}
/*
**********************************************************************
*
* TestCalibration
*
**********************************************************************
*/
void TestCalibration(void) {
int IdleCnt=0;
BUTTON_Handle hButton;
GUI_SetBkColor(GUI_RED);
GUI_SetColor(GUI_WHITE);
GUI_Clear();
hButton = BUTTON_Create( 235, 180, 80, 40, 1,0 );
BUTTON_SetText (hButton, "ABORT");
BUTTON_SetFont (hButton, &GUI_FontComic18);
while ((IdleCnt<50) && (WM_GetKey()==0)) {
static GUI_TOUCH_tState StateLast;
GUI_TOUCH_tState State;
GUI_TOUCH_GetState(&State);
if ((StateLast.PressedCnt != State.PressedCnt) && (State.PressedCnt==0)) {
GUI_Clear();
}
if ((StateLast.x != State.x) || ((StateLast.y != State.y))) {
if (State.PressedCnt) {
GUI_FillCircle(State.x, State.y, 5);
}
StateLast = State;
}
if (State.PressedCnt) {
IdleCnt =0;
} else {
IdleCnt++;
}
GUI_Delay (100);
}
EDIT_Delete(hButton);
}
/*
**********************************************************************
*
* ExecKeyboard
*
**********************************************************************
This creates a sample keyboard.
The routine returns after ENTER or ESC has been pressed.
*/
static char acText[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '='
,' ', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'
,' ', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Q'
,' ', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'Ö', 'Ä', 'Ü'
,' ', ' ', ' ', ' ', ' ', 0, 0
};
void ExecKeyboard(void) {
int i;
int Key;
BUTTON_Handle ahButton[52];
BUTTON_Handle hButtonESC;
EDIT_Handle hEdit;
GUI_RECT rText = {000,0, LCD_XSIZE, 20};
GUI_SetBkColor(GUI_RED);
GUI_Clear();
GUI_DrawBitmap(&bmSeggerLogoBlue, 0, 0);
GUI_SetFont(&GUI_FontComic18);
GUI_SetColor(GUI_WHITE);
GUI_DispStringInRect("emWin", &rText, GUI_TA_RIGHT | GUI_TA_VCENTER);
rText.y0 +=20;
rText.y1 +=20;
GUI_DispStringInRect("Touch screen demo", &rText, GUI_TA_RIGHT | GUI_TA_VCENTER);
//
// Create Keyboard Buttons
//
for (i=0; i< 51; i++) {
int Pos = (i < 47) ? i : i+4;
int x0 = 5 + 28*(Pos%11);
int y0 = 100 + 28*(Pos/11);
char c = acText[i];
int Id = c;
char ac[2] = {0};
char *s= ac;
ac[0] = c;
ahButton[i] = BUTTON_Create( x0, y0, 25, 25, Id,0 );
BUTTON_SetText (ahButton[i], s);
}
ahButton[i++] = BUTTON_Create( 89, 212, 109, 25, ' ',0 );
hButtonESC = BUTTON_Create( 230, 40, 80, 25, GUI_ID_CANCEL,0 );
BUTTON_SetText (hButtonESC, "ESC");
hEdit = EDIT_Create( 5, 70, 310, 25, ' ', 80, 0 );
EDIT_SetFont(hEdit, &GUI_Font8x16);
BUTTON_SetBkColor(ahButton[49], 0, GUI_RED);
BUTTON_SetBkColor(ahButton[50], 0, GUI_BLUE);
/*
Handle Keyboard until ESC or ENTER is pressed
*/
Loop:
Key = WM_WaitKey();
switch (Key) {
case GUI_ID_CANCEL:
break;
case 0:
default:
EDIT_AddKey(hEdit, Key);
goto Loop;
}
//
// Cleanup
//
for (i=0; i< countof(ahButton); i++) {
BUTTON_Delete(ahButton[i]);
}
BUTTON_Delete(hButtonESC);
EDIT_Delete(hEdit);
}
/*
**********************************************************************
*
* USER_Task
*
**********************************************************************
*/
void USER_Task(void) {
#define ID_KEYBOARD 1
#define ID_TESTCAL 2
#define ID_CALIBRATE 3
while (1) {
int i, r;
GUI_RECT rText = {0,80, 319, 120};
BUTTON_Handle ahButton[3];
GUI_SetBkColor(GUI_BLUE);
GUI_Clear();
GUI_DrawBitmap(&bmSeggerLogoBlue, (LCD_XSIZE-1-bmSeggerLogoBlue.XSize)/2, 15);
GUI_SetFont(&GUI_FontComic18);
GUI_DispStringInRect("emWin Touch screen demo", &rText, GUI_TA_HCENTER | GUI_TA_VCENTER);
ahButton[0] = BUTTON_Create( 110, 140, 100, 50, ID_CALIBRATE,0 );
ahButton[1] = BUTTON_Create( 70, 200, 80, 30, ID_KEYBOARD,0 );
ahButton[2] = BUTTON_Create( 170, 200, 80, 30, ID_TESTCAL,0 );
BUTTON_SetText (ahButton[0], "Calibrate");
BUTTON_SetBkColor(ahButton[0], 0, GUI_RED);
BUTTON_SetText (ahButton[1], "Keyboard");
BUTTON_SetText (ahButton[2], "Test calibration");
BUTTON_SetFont(ahButton[0], &GUI_FontComic18);
r = WM_WaitKey();
for (i=0; i< countof(ahButton); i++) {
BUTTON_Delete(ahButton[i]);
}
switch (r) {
case ID_KEYBOARD: ExecKeyboard(); break;
case ID_CALIBRATE: ExecCalibration(); break;
case ID_TESTCAL: TestCalibration(); break;
}
}
}
/*
**********************************************************************
*
* TouchMan: Touch manger (task)
*
**********************************************************************
This task is only used in case of a multitasking system. Its purpose
is to call the periodic touch handler GUI_TOUCH_Exec().
*/
#ifndef _WIN32
static int StackTouch[512]; /* Stack-space */
OS_TASK TCBTouch; /* Task-control-blocks */
static void TouchMan(void) {
while (1) {
GUI_TOUCH_Exec();
OS_Delay(10);
}
}
#endif
/*
*******************************************************************
*
* main() in target system
*
*******************************************************************
*/
#ifndef _WIN32
int Stack0[512]; /* Stack-space */
OS_TASK TCB0; /* Task-control-blocks */
void main(void) {
OS_InitKern();
OS_InitHW();
/* Common */
GUI_Init();
/* Create tasks */
OS_CREATETASK(&TCB0, "USER_Task", USER_Task, 100, Stack0); /* Create Task0 */
OS_CREATETASK(&TCBTouch, "TouchMan", TouchMan, 200, StackTouch); /* Touchman task */
/* Start multitasking */
OS_Start(); // Start multitasking
}
#endif
/*
*******************************************************************
*
* main() in Simulation
*
*******************************************************************
*/
#ifdef _WIN32
void main(void) {
GUI_Init();
USER_Task();
}
#endif
|
Return to main emWin page...
You can download an evaluation
version of emWin from our Literature/Download section....




|
|
 |
Segger News |
 |
 |
NEWS: Tools |
 |
 |
30-day free evaluation |
 |
 |
Literature Centre |
 |
|
|