Using a Nextion LCD to create an Arcade control panel

//Using a Nextion LCD to create an Arcade control panel
TUTORIAL


Using a Nextion color display to create an Arcade Touch Controller

OVERVIEW

As you may already know, I love classic arcade games.  I’ve even built some for myself using the MAME emulator.

My friend also built one for himself, and one day he asked me if I could make him to touch panel that would enable him to Pause, Save the game without having to install extra buttons in is cabinet to do so.

So when I came across the Nextion Display I knew this would be perfect for this application.

The Nextion Displays come in different sizes ranging from 2.8″ all the way to 7″.

The great thing about these color displays is that you only need 2 wires to control them using an Arduino.

The way these work, is that you create the graphics you want to display using a regular graphic software like photoshop, and then you save those images on the Nextion display itself.

That way you don’t need to use the Arduino memory to store the images, which would be too big anyways.

In this tutorial I will go through the process of creating the images, saving them to the display, then create some touch point that will send back to the Arduino Leonardo, that will then send back some keyboard code through the USB to control the MAME software.

CONNECTIONS

Nextion Display Arduino Schematic

We are using the Arduino Leonardo for this project, since by default it can function as a regular keyboard.

The MAME arcade emulation software works by using a keyboard so this is a great option.

We only need 2 Digital Pins and provide 5V and GND to the Nextion Display:

Pin 11 is connected to the TX pin on the Display

Pin 10 is connected to the RX pin

5V and GND are connected to the 5V and GND on the Nextion.

*Note: Since we are only receiving data from the Nextion Display in this tutorial, technically you don’t need to connect the RX pin, which is used when your send commands from the Arduino to the Nextion Display.

THE CODE

In this case it’s easier for you to watch the tutorial video to understand what the Arduino code is actually doing.

But in short you have to declare every touch event that were created on the Nextion display and then decide what to do when one of those is received.

The code looks long but most of it is repetition of the same but for a different touch event.

Basically the Arduino Leonardo will receive a touch event from the Nextion Display and then send a keyboard code that corresponds to that event through it’s USB port and then the MAME emulator will Pause, Save, etc…

Also keep in mind that this code what written for the Nextion Display images that were created for this tutorial, so it would not work directly with your design.  The structure would be the same but the amount of Hotspot and names might be different.

Keep this in mind if you are creating your own.

#include <Nextion.h>          // Nextion Library
#include <SoftwareSerial.h>   // Library for Software Serial Port
#include <Keyboard.h>         // Keyboard Emulation

SoftwareSerial HMISerial(10, 11);  // Nextion TX to pin 10 and RX to pin 11 of Arduino


// This part is used to declare all the objects we can receive from the Nextion Display
// (page, ID, Object name)
NexHotspot m0 = NexHotspot(0, 8, "m0");  // "PAUSE"  HotSpot on Page 0
NexHotspot m1 = NexHotspot(0, 2, "m1");  // "LOAD"   HotSpot on Page 0
NexHotspot m2 = NexHotspot(0, 3, "m2");  // "ESC"    HotSpot on Page 0
NexHotspot m3 = NexHotspot(0, 4, "m3");  // "MENU"   HotSpot on Page 0
NexHotspot m4 = NexHotspot(0, 5, "m4");  // "SAVE"   HotSpot on Page 0
NexHotspot m5 = NexHotspot(0, 6, "m5");  // "RESET"  HotSpot on Page 0
NexPicture p2 = NexPicture(0, 9, "p2");  // "RESUME" Picture of 'Resume Button' on Page 0

NexHotspot m0page1 = NexHotspot(1, 2, "m0");  // "Back Arrow"  HotSpot on Page 1
NexHotspot m1page1 = NexHotspot(1, 3, "m1");  // "Up Arrow"    HotSpot on Page 1
NexHotspot m2page1 = NexHotspot(1, 4, "m2");  // "ENTER"       HotSpot on Page 1
NexHotspot m3page1 = NexHotspot(1, 5, "m3");  // "Down Arrow"  HotSpot on Page 1

NexHotspot m0page2 = NexHotspot(2, 2, "m0");   // "Back Arrow"  HotSpot on Page 2
NexHotspot m1page2 = NexHotspot(2, 3, "m1");   // "Number 1"    HotSpot on Page 2
NexHotspot m2page2 = NexHotspot(2, 4, "m2");   // "Number 2"    HotSpot on Page 2
NexHotspot m3page2 = NexHotspot(2, 5, "m3");   // "Number 3"    HotSpot on Page 2
NexHotspot m4page2 = NexHotspot(2, 6, "m4");   // "Number 4"    HotSpot on Page 2
NexHotspot m5page2 = NexHotspot(2, 7, "m5");   // "Number 5"    HotSpot on Page 2
NexHotspot m6page2 = NexHotspot(2, 8, "m6");   // "Number 6"    HotSpot on Page 2
NexHotspot m7page2 = NexHotspot(2, 9, "m7");   // "Number 7"    HotSpot on Page 2
NexHotspot m8page2 = NexHotspot(2, 10, "m8");  // "Number 8"    HotSpot on Page 2
NexHotspot m9page2 = NexHotspot(2, 11, "m9");  // "Number 9"    HotSpot on Page 2

NexHotspot m0page3 = NexHotspot(3, 2, "m0");  //  "Back Arrow"  HotSpot on Page 3
NexHotspot m1page3 = NexHotspot(3, 3, "m1");  //  "Number 1"    HotSpot on Page 3
NexHotspot m2page3 = NexHotspot(3, 4, "m2");  //  "Number 2"    HotSpot on Page 3
NexHotspot m3page3 = NexHotspot(3, 5, "m3");  //  "Number 3"    HotSpot on Page 3
NexHotspot m4page3 = NexHotspot(3, 6, "m4");  //  "Number 4"    HotSpot on Page 3
NexHotspot m5page3 = NexHotspot(3, 7, "m5");  //  "Number 5"    HotSpot on Page 3
NexHotspot m6page3 = NexHotspot(3, 8, "m6");  //  "Number 6"    HotSpot on Page 3
NexHotspot m7page3 = NexHotspot(3, 9, "m7");  //  "Number 7"    HotSpot on Page 3
NexHotspot m8page3 = NexHotspot(3, 10, "m8");  // "Number 8"    HotSpot on Page 3
NexHotspot m9page3 = NexHotspot(3, 11, "m9");  // "Number 9"    HotSpot on Page 3


// This part is used to list the possible touchscreen events in an Array
NexTouch *nextion_touch_events[] = 
{
  &m0,  // Page 0 HotSpot
  &m1,  
  &m2,  
  &m3,  
  &m4, 
  &m5,
  &p2,
   
  &m0page1,  // Page 1 HotSpot
  &m1page1,  
  &m2page1,  
  &m3page1, 

  &m0page2,  // Page 2 HotSpot
  &m1page2,  
  &m2page2,  
  &m3page2, 
  &m4page2,  
  &m5page2,  
  &m6page2,  
  &m7page2,  
  &m8page2, 
  &m9page2,  
  
  &m0page3,  // Page 3 HotSpot
  &m1page3,  
  &m2page3,  
  &m3page3, 
  &m4page3,  
  &m5page3,  
  &m6page3,  
  &m7page3,  
  &m8page3, 
  &m9page3,    
  
  NULL  // End string
};



//  This part is for the different functions for Main Screen Touch events (page zero)
void m0PushCallback(void *ptr)
{
   Keyboard.press('p');  // 'P' for Pause Game
   delay(250);  //  Delay of 250ms is needed for Mame to register the key press
   Keyboard.release('p');  //  stop pressing the key
}

void m1PushCallback(void *ptr)
{
   Keyboard.press(200);  // 'F7' for Load Game
   delay(250);
   Keyboard.releaseAll();
}

void m2PushCallback(void *ptr)
{
   Keyboard.press(177);  // 'ESC' key
   delay(250);
   Keyboard.releaseAll();
}

void m3PushCallback(void *ptr)
{
   Keyboard.press(179);  // 'TAB' for Menu
   delay(250);
   Keyboard.releaseAll();
}

void m4PushCallback(void *ptr)
{
   Keyboard.press(129);  // 'LEFT SHIFT' key +
   Keyboard.press(200);  // 'F7' for Save Game
   delay(250);
   Keyboard.releaseAll();
}

void m5PushCallback(void *ptr)
{
   Keyboard.press(196);  // 'F3' for Reset Game
   delay(250);
   Keyboard.releaseAll();
}

void p2PushCallback(void *ptr)
{
   Keyboard.press('p');  // 'P' again for Resume Game (highlighted Pause button)
   delay(250);
   Keyboard.release('p');
}


//  This part is for the different functions for Page 1
void m0page1PushCallback(void *ptr)
{
//  Back Arrow on Nextion / No action required from Arduino
}

void m1page1PushCallback(void *ptr)
{ 
   Keyboard.press(218);  // 'UP ARROW KEY'
   delay(250);
   Keyboard.releaseAll();
}

void m2page1PushCallback(void *ptr)
{
   Keyboard.press(176);  // 'ENTER KEY'
   delay(250);
   Keyboard.releaseAll();
}

void m3page1PushCallback(void *ptr)
{
   Keyboard.press(217);  // 'DOWN ARROW KEY'
   delay(250);
   Keyboard.releaseAll();
}


//  This part is for the different functions for Page 2
void m0page2PushCallback(void *ptr)
{
   // Back Arrow on Nextion / No action required from Arduino
}

void m1page2PushCallback(void *ptr)
{
   Keyboard.press(49);  // Number '1' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m2page2PushCallback(void *ptr)
{
   Keyboard.press(50);  // Number '2' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m3page2PushCallback(void *ptr)
{
   Keyboard.press(51);  // Number '3' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m4page2PushCallback(void *ptr)
{
   Keyboard.press(52);  // Number '4' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m5page2PushCallback(void *ptr)
{ 
   Keyboard.press(53);  // Number '5' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m6page2PushCallback(void *ptr)
{
   Keyboard.press(54);  // Number '6' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m7page2PushCallback(void *ptr)
{
   Keyboard.press(55);  // Number '7' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m8page2PushCallback(void *ptr)
{
   Keyboard.press(56);  // Number '8' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m9page2PushCallback(void *ptr)
{
   Keyboard.press(57);  // Number '9' key for Load slot selection
   delay(250);
   Keyboard.releaseAll();
}


//  This part is for the different functions for Page 3
void m0page3PushCallback(void *ptr)
{
   // Back Arrow on Nextion / No action required from Arduino
} 

void m1page3PushCallback(void *ptr)
{
   Keyboard.press(49);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m2page3PushCallback(void *ptr)
{
   Keyboard.press(50);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m3page3PushCallback(void *ptr)
{
   Keyboard.press(51);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m4page3PushCallback(void *ptr)
{
   Keyboard.press(52);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m5page3PushCallback(void *ptr)
{
   Keyboard.press(53);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m6page3PushCallback(void *ptr)
{
   Keyboard.press(54);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m7page3PushCallback(void *ptr)
{
   Keyboard.press(55);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m8page3PushCallback(void *ptr)
{
   Keyboard.press(56);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}

void m9page3PushCallback(void *ptr)
{
   Keyboard.press(57);  // Number '1' key for Save slot selection
   delay(250);
   Keyboard.releaseAll();
}




// Main Setup 
void setup() {
  
  HMISerial.begin(9600);  // Start Software Serial at 9600bauds
    
  nexInit();  //  Nextion Display initalize

  Keyboard.begin();  // Start Keyboard emulation


// Link the touchscreen events to their relative functions in the code
// attachPush for press events or attachPop for release events  
  m0.attachPush(m0PushCallback);
  m1.attachPush(m1PushCallback); 
  m2.attachPush(m2PushCallback); 
  m3.attachPush(m3PushCallback);  
  m4.attachPush(m4PushCallback);  
  m5.attachPush(m5PushCallback); 
  p2.attachPush(p2PushCallback);
 
  m0page1.attachPush(m0page1PushCallback);
  m1page1.attachPush(m1page1PushCallback); 
  m2page1.attachPush(m2page1PushCallback); 
  m3page1.attachPush(m3page1PushCallback); 
   
  m0page2.attachPush(m0page2PushCallback);  
  m1page2.attachPush(m1page2PushCallback); 
  m2page2.attachPush(m2page2PushCallback); 
  m3page2.attachPush(m3page2PushCallback); 
  m4page2.attachPush(m4page2PushCallback); 
  m5page2.attachPush(m5page2PushCallback); 
  m6page2.attachPush(m6page2PushCallback); 
  m7page2.attachPush(m7page2PushCallback);   
  m8page2.attachPush(m8page2PushCallback); 
  m9page2.attachPush(m9page2PushCallback);   

  m0page3.attachPush(m0page3PushCallback);  
  m1page3.attachPush(m1page3PushCallback); 
  m2page3.attachPush(m2page3PushCallback); 
  m3page3.attachPush(m3page3PushCallback); 
  m4page3.attachPush(m4page3PushCallback); 
  m5page3.attachPush(m5page3PushCallback); 
  m6page3.attachPush(m6page3PushCallback); 
  m7page3.attachPush(m7page3PushCallback);   
  m8page3.attachPush(m8page3PushCallback); 
  m9page3.attachPush(m9page3PushCallback);    
}


// Main Loop
void loop() {

delay(100); // small delay before checking again for touch events
nexLoop(nextion_touch_events);  // Check for any touch event and run the associated function
 
}
TUTORIAL VIDEO PART 1
TUTORIAL VIDEO PART 2
DOWNLOAD

Copy the above Sketch code you want to use above in your Arduino IDE software to program your Arduino.

You can find the latest Nextion Library for Arduino here:

https://www.itead.cc/blog/nextion-arduino-library-a-basic-introduction

You will also need to download the latest Nextion Editor software to create the graphics.

By | 2018-03-07T19:44:26+00:00 October 30th, 2017|Tutorials|

2 Comments

  1. Chris June 30, 2018 at 6:29 pm - Reply

    Hello, Nice tutorial

    Just wondering is it possible to use a Bluetooth connection rather than USB. I have an idea for a project but I would like to make it wireless rather than a long USB cable running to the computer?

  2. Marcel May 31, 2018 at 12:13 pm - Reply

    My Nextion(s) are in the mail.
    Can’t wait to start playing.

Leave A Comment