Segger Logo Embedded Software Solutions
Software productsHardware productsDownloadsPricesCustomersOur PartnersSitemapForumAbout us
emWin: Touch screen support
| Samples | Simulation | Font Converter | Bitmap Converter | Memory devices | Window Manager | Widgets | Dialogs | Multiple Layer/Displays | VNC Support | Touch Screen | Antialiasing | Drivers | Starter Boards | Virtual Screen Support | emWin Applications | PC Evaluation Versions |

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
Screenshot simulation start Screenshot simulation keyboard

"C" source of the sample program


/*********************************************************************
*                SEGGER Microcontroller GmbH & Co.KG                 *
*        Solutions for real time microcontroller applications        *
**********************************************************************
*                                                                    *
*           (C) 2000    SEGGER Microcontroller GmbH & Co.KG          *
*                                                                    *
*        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
*
* Function description: 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)
*
* Function description: 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

Copyright SEGGER Microcontroller GmbH & Co.KG. All rights reserved.
For more information, please visit our web site www.segger.com or contact us at info@segger.com
Last update: December 7, 2007