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:
- 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.
- The Documentation folder contains reference manuals for both libraries, with detailed description of each function and constant.
- 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 pins | Description |
---|---|
1 - CS | Chip Select |
2 - MOSI | Master Out - Slave In |
3 - MISO | Master IN - Slave Out |
4 - SCLK | Serial Clock |
5 - GND | Power Supply Ground |
6 - VCC | Power supply (3.3V/5V) |
7 - NC | not connected |
8 - RESET | Active-Low Reset |
9 - NC | not connected |
10 - NC | not connected |
11 - GND | Power Supply Ground |
12 - VCC | Power supply (3.3V/5V) |
J2 pins | Description |
---|---|
1 - VEXT | External Power supply Positive Connection |
2 - GND | Power Supply Ground |
JP1 pins | Description |
---|---|
1 - EXT | Use External Power Supply Power Backlight |
2 | To Backlight |
3 - VCC | Use 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: