Add a Multi-Touch Display Module to Arduino Mega

28 Sep.,2022

 

Touch Display Module

This project demonstrates how to use Pmod MTDSPmod MTDS, a capacitive touchscreen, with multi-touch support, with Arduino Mega. In this demonstration, after displaying some text messages, different shapes will be displayed. By touching the display with two fingers, the shape can be changed, and by swiping across the screen with one finger, the color of the shape can be set.

 

Parts list

Required software

Note: you can also find the necessary libraries and their documentation in the attachments.

 

Pmod MTDS

The Pmod MTDS is a 2.8" capacitive touchscreen with multi-touch support up to 2 fingers. The display has QVGA (320x240) resolution, a micro-SD card slot and is controlled by an on-board PIC32MZ microcontroller,  which is running the firmware. The microSD connector allows the MTDS firmware to draw and save images to an attached microSD card. In order to work properly, the microSD card must be formatted as FAT32. Image files should be saved as Windows Bitmap files (.bmp). Communication with the on-board microcontroller can be realized by using the SPI interface. Thanks to the Multi-Touch Display System (MTDS) Firmware and associated libraries (linked under the required software and in the attachment), you can get started with Pmod MTDS easily.

Installing and using the libraries

To install the libraries, you have to copy the content of the Libraries folder to the path which is given in the Arduino IDE (%userprofile%\Documents\Arduino\libraries on Windows). The MTDS library package contains four folders: Documentation, Libraries, Resources and Sketches:

  1. Two libraries: mtds.h and MyDisp.h. The mtds.h library contains the full set of available functions for the Pmod MTDS, while the MyDisp.h library contains a limited set, but easier to use functions.

  2. The Documentation folder contains reference manuals for both libraries, with detailed description of each function and constant.

  3. The Sketches folder contains ten examples, where the usage of several functions is demonstrated while performing different tasks, including, but not limited to: drawing lines, drawing shapes, creating custom brushes, creating off-screen bitmaps and moving them on the screen, saving/reading bitmaps to/from the SD card, handling different touches and swipes, displaying text, or using the display in landscape/portrait mode. Before starting a new project with the Pmod MTDS, it's advised to read through these examples.

 

 

Interfacing Pmod MTDS with Arduino Mega

The Pmod MTDS communicates with Arduino Mega via SPI. However, the implementation of this physical interface is handled by the MTDS libraries, so the user doesn't have to directly use this protocol. The module is powered by 3.3V supplied by the Arduino Mega. The backlight of the display can also be powered from an external power supply, with the help of the J2 connector and the JP1 jumper. If an external power supply is used, it should be connected to J2 and the JP1 jumper should be put in the upper position. The pinout of the Pmod is presented in the following table:

 

J1 pinsDescription 1 - CSChip Select2 - MOSIMaster Out - Slave In3 - MISOMaster IN - Slave Out4 - SCLKSerial Clock5 - GNDPower Supply Ground6 - VCC

Power supply (3.3V/5V)

7 - NCnot connected8 - RESETActive-Low Reset9 - NCnot connected10 - NCnot connected11 - GNDPower Supply Ground12 - VCCPower supply (3.3V/5V)J2 pinsDescription1 - VEXTExternal Power supply Positive Connection2 - GNDPower Supply GroundJP1 pinsDescription1 - EXTUse External Power Supply Power Backlight2To Backlight3 - VCCUse VCC to Power Backlight

To connect the Pmod to the Arduino Mega, connect:

  • VCC to 3V3

  • GND to GND

  • SCLK to 52 (SCK)

  • MISO to 50 (MISO)

  • MOSI to 51 (MOSI)

  • CS to 53 (SS)

Note: you can also find the Fritzing file containing the wiring diagram in the attachments.

 

Adruino Sketch

A text message will be displayed on the screen, using the Console font, the text being green  and the background being black (Matrix-style). After three seconds this text is deleted, then a red rectangle is displayed. In the main loop, in every iteration, it is checked if the display was touched or not. If a new action is detected, the type of the touch is determined based on the MTDS's default messaging system (an object stores the touch type and the position coordinates). The shape and the color of the object are then determined from these actions, finally the screen is refreshed.

 

Including the library, defines, global variables and function prototypes:

/************************************************************************


  Using the Pmod MTDS multi-touch, colored display with Arduino Mega


*************************************************************************


  Description: Pmod_MTDS, Arduino_Mega
  The image wil be modified according to captured gestures


  Material
  1. Arduino Mega
  2. Pmod MTDS


  Wiring
  Pmod <----------> Arduino
  VCC       to        3V3
  GND       to        GND
  SCK       to        52 (SCK)
  MISO      to        50 (MISO)
  MOSI      to        51 (MOSI)
  CS        to        53 (SS)


   You can use any other Arduino board with an AVR processor (and with enough memory)


************************************************************************/


//include the mtds library
#include <mtds.h>


//define object size
#define size 200   //200*200 px object size
#define width 320  //screen width (px)
#define height 240 //screen height (px)


//global variables
bool square_shape = true; //store the shape (square/circle)
CLR shape_color = clrRed; //store the color of the shape


/*---------------------------------------------------------------------*/


//function prototypes
void display_text(char *message); //display a string on the screen
void draw_square(CLR color);      //draws a square
void draw_circle(CLR color);      //draws a circle
void calculate_color(int x);      //recalculate the color according to a distance

The setup function:

void setup()
{
  Serial.begin(115200); //initialize the Serial monitor


  //try to initialize the display
  while (true) //repeat until the initialization succeeds
  {
    bool init_state = mtds.begin(pinMtdsSelStd, frqMtdsSpiDefault); //initialize with default SPI frequency on default pins (50-53 on Mega)
    if (init_state)                                                 //check if it succeeded or not
    {
      Serial.println("initialization succeeded"); //print message
      break;                                      //exit the loop
    }
    else
    {
      Serial.println("initialization failed"); //print message
      delay(1000);                             //wait before the next iteration
    }
  }


  //set display orientation (landscape mode)
  mtds.SetDisplayOrientation(dsoLandscape);         //the default would be portrait
  Serial.println("orientation changed: landscape"); //print message


  //clear display
  mtds.ClearDisplay(clrBlack);      //set the background to black
  Serial.println("screen cleared"); //print message


  //display text
  display_text("initialization done"); //display a message on the screen
  delay(3000);                         //wait 3 seconds


  mtds.ClearDisplay(clrBlack); //set the background to black
  draw_square(shape_color);    //draw a square
}

The loop function:

void loop()
{
  if (mtds.GetMsgStatus() != 0) //if there is a new action
  {
    MTCH action;                             //variable for action type
    mtds.GetMsg((MEVT *)&action);            //get action type
    Serial.println("\nnew action detected"); //print message


    if ((action.msg >= msgFingerFirst) && (action.msg <= msgFingerLast)) //if the action is valid
    {
      Serial.print("the action is valid - "); //print a message
      switch (action.msg)                     //set color and shape accordinig to action
      {
        case msgFinger2Down:
          Serial.println("finger 2 down"); //print a message
          mtds.ClearDisplay(clrBlack);     //set the background to black
          square_shape = !square_shape;    //change the variable keeping the shape
          if (square_shape)                //draw according to the shape
          {
            draw_square(shape_color); //draw a square
          }
          else
          {
            draw_circle(shape_color); //draw a circle
          }
          break; //change the shape on double touch
        case msgFinger1Down:
          Serial.println("finger 1 down"); //print a message
          calculate_color(action.xco);     //recalculate the color according to location
          if (square_shape)                //draw according to the shape
          {
            draw_square(shape_color); //draw a square
          }
          else
          {
            draw_circle(shape_color); //draw a circle
          }
          break; //calculate new color according to finger 1 position
        case msgFinger1Move:
          Serial.println("finger 1 move"); //print a message
          calculate_color(action.xco);     //recalculate the color according to location
          if (square_shape)                //draw according to the shape
          {
            draw_square(shape_color); //draw a square
          }
          else
          {
            draw_circle(shape_color); //draw a circle
          }
          break; //calculate new color according to finger 1 position
        default:
          Serial.println("unspecified"); //print a message
          break;                         //just quit if no action is specified
      }
    }
  }
}

User defined functions:

/*
    displays a string on the screen
    parameters: string to display
    returns: none
*/
void display_text(char *message)
{
  HDS display = mtds.GetDisplayDs();                     //get display handle
  mtds.SetFgColor(display, clrGreen);                    //set text color
  mtds.SetBgColor(display, clrBlack);                    //set background color
  mtds.SetDrwRop(display, drwCopyPen);                   //don't combine pen and background
  mtds.SetFont(display, hfntConsole);                    //set font
  mtds.TextOut(display, 2, 2, strlen(message), message); //display the string
  mtds.ReleaseDs(display);                               //free dynamic memory
  return;
}


/*---------------------------------------------------------------------*/


/*
    draws a square
    parameters: color of the bitmap, size of the bitmap (default is 200*200px)
    returns: none
*/
void draw_square(CLR color)
{
  HDS display = mtds.GetDisplayDs();                                                                         //get display handle
  HBMP drawing_area = mtds.GetDisplayBitmap();                                                               //the drawing will be rendered on the screen
  mtds.SetDrawingSurface(display, drawing_area);                                                             //make this bitmap active to edit it
  mtds.SetDrwRop(display, drwCopyPen);                                                                       //don't combine pen and background
  mtds.SetPen(display, penSolid);                                                                            //use solid line when drawing
  color = mtds.GetNearestColor(color);                                                                       //truncate color to usable value
  HBR brush = mtds.CreateSolidBrush(color);                                                                  //create a colored brush for filling shapes
  mtds.SetBrush(display, brush);                                                                             //set brush
  mtds.SetFgColor(display, color);                                                                           //set line color
  mtds.Rectangle(display, (width - size) / 2, (height - size) / 2, (width + size) / 2, (height + size) / 2); //draw a square
  mtds.ReleaseDs(display);                                                                                   //free dynamic memory
  return;
}


/*---------------------------------------------------------------------*/


/*
    draws a circle
    parameters: color of the bitmap, size of the bitmap (default is 200*200px)
    returns: none
*/
void draw_circle(CLR color)
{
  HDS display = mtds.GetDisplayDs();                                                                       //get display handle
  HBMP drawing_area = mtds.GetDisplayBitmap();                                                             //the drawing will be rendered on the screen
  mtds.SetDrawingSurface(display, drawing_area);                                                           //make this bitmap active to edit it
  mtds.SetDrwRop(display, drwCopyPen);                                                                     //don't combine pen and background
  mtds.SetPen(display, penSolid);                                                                          //use solid line when drawing
  color = mtds.GetNearestColor(color);                                                                     //truncate color to usable value
  HBR brush = mtds.CreateSolidBrush(color);                                                                //create a colored brush for filling shapes
  mtds.SetBrush(display, brush);                                                                           //set brush
  mtds.SetFgColor(display, color);                                                                         //set line color
  mtds.Ellipse(display, (width - size) / 2, (height - size) / 2, (width + size) / 2, (height + size) / 2); //draw a circle
  mtds.ReleaseDs(display);                                                                                 //free dynamic memory
  return;
}


/*---------------------------------------------------------------------*/


/*
    recalculate the color according to swipe distance
    parameters: x coordinate of finger 1 position
    returns: none
*/
void calculate_color(int x)
{
  int part = width / 6; //calculate the 1/6 part of the width of the screen
  if (x < part)         //red-yellow
  {
    shape_color = 0xFF0000 | (map(x, 0, part, 0x00, 0xFF) << 8); //map to red-yellow
  }
  else if (x < 2 * part) //yellow-green
  {
    shape_color = (map(x, part, part * 2, 0xFF, 0x00) << 16) | 0xFF00; //map to yellow-green
  }
  else if (x < 3 * part) //green-cyan
  {
    shape_color = map(x, part * 2, part * 3, 0xFF00, 0xFFFF); //map to green-cyan
  }
  else if (x < 4 * part) //cyan-blue
  {
    shape_color = (map(x, part * 3, part * 4, 0xFF, 0x00) << 8) | 0xFF; //map to cyan-blue
  }
  else if (x < 5 * part) //blue-magenta
  {
    shape_color = (map(x, part * 4, part * 5, 0x00, 0xFF) << 16) | 0x00FF; //map to blue-magenta
  }
  else //magenta-red
  {
    shape_color = map(x, part * 5, width, 0xFF00FF, 0xFF0000); //map to magenta-red
  }
  return;
}

Note: you can also find the Arduino sketch in the attachments.

 

Results

Pmod MTDS in use:

You don't have permission to edit metadata of this video.

Edit media

Subject (required) Brief Description Tags (separated by comma) Video visibility in search results Parent content Poster Upload Preview