Smart Restaurant Menu Ordering System using Arduino

Arduino

ByAshish Choudhary 1

Smart Restaurant Menu Ordering System using Arduino

Now day’s automation systems are everywhere whether its home, office or any big industry, all are equipped with automation systems. Restaurants/Hotels are also adopting recent automation trends and are installing robots to deliver food and tablets for taking orders. Using these digital menu cards like tablets, customers can easily select the items. This information will be sent to the kitchen of the Restaurant and also displayed on the display.

In this project, we are building a Smart Restaurant Project using Arduino, TFT display, and 433MHz RF transmitter/receiver module. Here the transmitter section will consist of Arduino Uno, TFT display, and an RF transmitter, using which customers can select the food items and place the order. While the receiver section consists of an Arduino Uno, LCD module, RF receiver, and a Buzzer, which will be installed in the restaurant kitchen to track the order items.

Components Required

  • Arduino Uno (2)
  • 433MHz RF Transmitter & Receiver
  • 2.4" TFT LCD Touch shield
  • 16*2 LCD Module
  • I2C Module

Interfacing TFT LCD Touch shield with Arduino

2.4" TFT LCD Touch shield is a multicolored Arduino UNO/ Mega compatible TFT display that comes with touch-screen and SD card socket as well. This TFT display module has a bright backlight and a colorful 240X320 pixels display. It also consists of individual RGB pixel control that gives it a much better resolution than the black and white displays.

Interfacing the TFT display with Arduino is very simple and explained in the previous tutorial. You only need to mount the TFT display over the Arduino Uno board, as shown in the below image.

TFT LCD Touch Shield

TFT LCD is very useful in building portable applications like:

Also, check all the TFT LCD based projects here.

Circuit Diagram

Smart Restaurant Menu Ordering System project consists of RF Transmitter and Receiver section. Both the transmitter and receiver side uses Arduino Uno for data processing. We previously used the same 433 MHz RF modules with Arduino for building projects like a wireless doorbell, hand gesture controlled robot, etc. The circuit diagram for the transmitter and receiver section is given below.

Transmitter Section Circuit 

The transmitter section of this project consists of an Arduino Uno, RF Transmitter, and TFT display shield. This section is used for ordering from the menu that is shown on the TFT display. Arduino Uno is the brain of the transmitter side that processes all the data, and the RF transmitter module is used to transmit the selected data to the receiver. The data pin of the RF transmitter module is connected to digital pin 12 of Arduino while VCC and GND pins are connected to 5V and GND pin of Arduino.

Arduino Smart Restaurant RF Transmitter Circuit Diagram

Arduino Based Smart Restaurant Menu Ordering System Transmitter

Receiver Section Circuit 

The receiver section of this project consists of an Arduino Uno, RF Receiver, 16*2 LCD module, and I2C module. RF receiver is used to receive the data from the transmitter section, and the LCD module is used to display the received data. A buzzer is used to make a sound whenever a new order is placed. The data pin of the RF receiver is connected to digital pin 11 of Arduino while VCC and GND pin is connected to the 5V and GND pin of Arduino. The positive pin of Buzzer is connected to the digital pin 2 of Arduino, and the negative pin is connected to the GND pin of Arduino. SCL and SDA pins of the I2C module is connected to analog pins A5 & A4 Arduino while VCC and GND pins are connected to 5V and GND pins of Arduino.

Smart Restaurant Menu Ordering System using Arduino Circuit Diagram

Arduino Based Smart Restaurant Menu Ordering System Receiver

Code Explanation

Complete code for RF Transmitter and Receiver sides for this Smart Ordering System in Restaurant are given at the end of the document. All the libraries used in this project can be downloaded from the given links.

RadioHead library is used for the RF transmitter/Receiver module, while the SPFD5408 library is used for TFT display.

Transmitter Section Code: 

Start the code by including all the required libraries. RH_ASK.h library is used for communication between transmitter and receiver modules. SPFD5408_Adafruit_GFX.h is a Core graphics library for TFT display.

#include <RH_ASK.h>
#include <SPI.h>
#include <SPFD5408_Adafruit_GFX.h>   
#include <SPFD5408_Adafruit_TFTLCD.h>
#include <SPFD5408_TouchScreen.h>

After that, create an object called ‘driver’ for RH_ASK.

RH_ASK driver;

After that define the minimum and maximum calibrated X & Y-axis values for your TFT display. 

#define TS_MINX 125
#define TS_MINY 85
#define TS_MAXX 965
#define TS_MAXY 905

Now inside the drawHome function draw a layout for your TFT screen. Here tft.fillScreen is used to set the background color.

tft.drawRoundRect function is used to create a filled Rectangle. Syntax for tft.drawRoundRect function is given below:

tft.drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color)

Where:

 x0= X co-ordinate of the starting point of rectangular

y0= Y coordinate of the starting point of rectangular

w = Width of the rectangular

h = Height of the Rectangular

radius= Radius of the round corner

color = Colour of the Rect.

tft.fillRoundRect function is used to draws a filled Rectangle. Syntax of tft.fillRoundRect function is given below:

tft.fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color)
tft.fillScreen(WHITE);
tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border
  tft.fillRoundRect(30, 40, 100, 40, 8, GOLD);
  tft.drawRoundRect(30, 40, 100, 40, 8, WHITE);  //Dish1​
  tft.fillRoundRect(30, 90, 100, 40, 8, GOLD);
  tft.drawRoundRect(30, 90, 100, 40, 8, WHITE);  //Dish2​
  tft.fillRoundRect(30, 140, 100, 40, 8, GOLD);   //Dish3
  tft.drawRoundRect(30, 140, 100, 40, 8, WHITE);

After creating the buttons on the TFT screen, now display the text on the buttons. tft.setCursor is used to set the cursor from where you want to start the text.

  tft.setCursor(60, 0);
  tft.setTextSize(3);
  tft.setTextColor(LIME);
  tft.print("   Menu");
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  tft.setCursor(37, 47);
  tft.print(" Dish1");

Inside the void transmit function, send the data to the receiver side every 1 second.

void transmit()
{ 
  driver.send((uint8_t *)msg, strlen(msg));
  driver.waitPacketSent();
  delay(1000);
  }

Inside the void loop function, read the Raw ADC value using the ts.getPoint function.

TSPoint p = ts.getPoint();

Now use the map function to convert the Raw ADC values to Pixel Co-ordinates.

p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
p.y = map(p.y, TS_MAXY, TS_MINY, 0, 240);

After converting the Raw ADC values into pixel co-ordinate, enter the pixel coordinates for the Dish1 button and if someone touches the screen between this area then send the message to the receiver side.

if (p.x > 180 && p.x < 280 && p.y > 190 && p.y < 230  && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      {
        Serial.println("Dish1");
        msg = "Dish1";
        transmit();
        tft.fillRoundRect(30, 40, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(30, 40, 100, 40, 8, GOLD);
        tft.drawRoundRect(30, 40, 100, 40, 8, WHITE);
        tft.setCursor(37, 47);
        tft.println(" Dish1");
        delay(70);
        }

Follow the same procedure for all other buttons.

Receiver Section Code 

For the RF receiver section code, include the libraries for RF receiver and LCD module. Also include the SPI.h library for establishing an SPI communication between Arduino and RF receiver.

#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile
#include <LiquidCrystal_I2C.h>

Inside the void loop function, continuously check for transmitted messages. And if the receiver module receives a message, then display the message on the LCD module and make a beep sound.

    if (driver.recv(buf, &buflen)) // Non-blocking
    {
      int i;
      digitalWrite(buzzer, HIGH);
      delay(1000);
      digitalWrite(buzzer, LOW);.
      lcd.print("T1:");
      lcd.print((char*)buf);

Testing the Smart Restaurant Project using Arduino

Smart Restaurant Menu Ordering System using Arduino

After connecting all the hardware and uploading the code for both the transmitter and receiver section, now it’s time to test the project. To test the project, press a button on the TFT display, it should display the dish name with table number that is T1 on the LCD module connected to the receiver side. If the receiver side LCD doesn’t display anything, then check whether your TFT screen is working or not.

This is how you can build a Smart Restaurant Menu Ordering System project using Arduino and TFT display. You can also change the orientation of the screen to add more buttons.

A working video with the complete code is given below.

Code

Code for Transmitter (TFT LCD)

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile
#include <SPFD5408_Adafruit_GFX.h>    // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPFD5408_TouchScreen.h>
const char *msg ;
RH_ASK driver;
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define TS_MINX 125
#define TS_MINY 85
#define TS_MAXX 965
#define TS_MAXY 905
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4
#define REDBAR_MINX 80
#define GREENBAR_MINX 130
#define BLUEBAR_MINX 180
#define BAR_MINY 30
#define BAR_HEIGHT 250
#define BAR_WIDTH 30
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
#define BLACK   0x0000
int BLUE = tft.color565(50, 50, 255);
#define DARKBLUE 0x0010
#define VIOLET 0x8888
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define GREY   tft.color565(64, 64, 64);
#define GOLD 0xFEA0
#define BROWN 0xA145
#define SILVER 0xC618
#define LIME 0x07E0
void drawHome()
{
  tft.fillScreen(WHITE);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border
  tft.fillRoundRect(30, 40, 100, 40, 8, GOLD);
  tft.drawRoundRect(30, 40, 100, 40, 8, WHITE);  //Dish1
  tft.fillRoundRect(30, 90, 100, 40, 8, GOLD);
  tft.drawRoundRect(30, 90, 100, 40, 8, WHITE);  //Dish2
  tft.fillRoundRect(30, 140, 100, 40, 8, GOLD);   //Dish3
  tft.drawRoundRect(30, 140, 100, 40, 8, WHITE);
  tft.fillRoundRect(10, 190, 190, 40, 8, CYAN);
  tft.drawRoundRect(10, 190, 190, 40, 8, WHITE); //Call Waiter
  tft.fillRoundRect(180, 40, 100, 40, 8, GOLD);
  tft.drawRoundRect(180, 40, 100, 40, 8, WHITE);  //Dish4
  tft.fillRoundRect(180, 90, 100, 40, 8, GOLD);
  tft.drawRoundRect(180, 90, 100, 40, 8, WHITE); //Dish5
  tft.fillRoundRect(180, 140, 100, 40, 8, GOLD);
  tft.drawRoundRect(180, 140, 100, 40, 8, WHITE); //Dish6
  tft.fillRoundRect(210, 190, 100, 40, 8, GREEN);
  tft.drawRoundRect(210, 190, 100, 40, 8, WHITE); //Bill
  tft.setCursor(60, 0);
  tft.setTextSize(3);
  tft.setTextColor(LIME);
  tft.print("   Menu");
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  tft.setCursor(37, 47);
  tft.print(" Dish1");
  tft.setCursor(37, 97);
  tft.print(" Dish2");
  tft.setCursor(37, 147);
  tft.print(" Dish3");
  tft.setCursor(23, 197);
  tft.print(" Call Waiter");
  tft.setCursor(187, 47);
  tft.print(" Dish4");
  tft.setCursor(187, 97);
  tft.print(" Dish5");
  tft.setCursor(187, 147);
  tft.print(" Dish6");
  tft.setCursor(227, 197);
  tft.print(" Bill");
  //  delay(500);
}
int oldcolor, currentcolor, currentpcolour;
void setup(void) { 
  tft.reset();
  tft.begin(tft.readID());
  Serial.begin(9600);
  Serial.println();
  Serial.print("reading id...");
  delay(500);
  Serial.println(tft.readID(), HEX);  
  tft.fillScreen(BLACK);
  tft.setRotation(1);
  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.setCursor(50, 140);
  tft.print("Loading...");
  tft.setTextColor(tft.color565(255, 255, 0));
  tft.setCursor(30, 70);
  tft.print("By:");
  tft.setCursor(10, 100);
  tft.print("CircuitDigest.Com");
  for (int i; i < 250; i++)
  {
    tft.fillRect(BAR_MINY - 10, BLUEBAR_MINX, i, 10, RED);
    delay(0.000000000000000000000000000000000000000000000000001);
  }
  tft.fillScreen(BLACK);
  if (!driver.init())
      Serial.println("init failed");
  drawHome();
  pinMode(13, OUTPUT);
}
#define MINPRESSURE 10
#define MAXPRESSURE 1000
void transmit()
{  
  driver.send((uint8_t *)msg, strlen(msg));
  driver.waitPacketSent();
  delay(1000);
  }
void loop()
{  
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);
  // if sharing pins, you'll need to fix the directions of the touchscreen pins
  //pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  //pinMode(YM, OUTPUT);
  if (p.z > ts.pressureThreshhold)
    {
      p.x = map(p.x, TS_MAXX, TS_MINX, 0, 320);
      p.y = map(p.y, TS_MAXY, TS_MINY, 0, 240);      
      if (p.x > 180 && p.x < 280 && p.y > 190 && p.y < 230  && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      {
        Serial.println("Dish1");
        msg = "Dish1 Ordered";
        transmit();
        tft.fillRoundRect(30, 40, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(30, 40, 100, 40, 8, GOLD);
        tft.drawRoundRect(30, 40, 100, 40, 8, WHITE);
        tft.setCursor(37, 47);
        tft.println(" Dish1");
        delay(70);
        }
      if (p.x > 180 && p.x < 280 && p.y > 140 && p.y < 180)
      {
        Serial.println("Dish2");
        msg = "Dish2 Ordered";
        transmit();
        tft.fillRoundRect(30, 90, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(30, 90, 100, 40, 8, GOLD);
        tft.drawRoundRect(30, 90, 100, 40, 8, WHITE);
        tft.setCursor(37, 97);
        tft.println(" Dish2");
        delay(70);      
      }
      if (p.x > 180 && p.x < 280 && p.y > 90 && p.y < 130)
      {
        Serial.println("Dish3");
        msg = "Dish3 Ordered";
        transmit();
        tft.fillRoundRect(30, 140, 100, 40, 8, WHITE);   //rgb led
        delay(70);
        tft.fillRoundRect(30, 140, 100, 40, 8, GOLD);   //rgb led
        tft.drawRoundRect(30, 140, 100, 40, 8, WHITE);   //rgb led
        tft.setCursor(37, 147);
        tft.print(" Dish3");
        delay(70);       
      }
      if (p.x > 210 && p.x < 310 && p.y > 40 && p.y < 80)
      {
        Serial.println("Call Waiter");
        msg = "CallingWaiter";
        transmit();
        tft.fillRoundRect(10, 190, 190, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(10, 190, 190, 40, 8, CYAN);
        tft.drawRoundRect(10, 190, 190, 40, 8, WHITE);
        tft.setCursor(23, 197);
        tft.print(" Call Waiter");
        delay(70);
      }
      if (p.x > 30 && p.x < 130 && p.y > 190 && p.y < 230)
      {
        Serial.println("Dish4");
        msg = "Dish4 Ordered";
        transmit();
        tft.fillRoundRect(30, 40, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(30, 40, 100, 40, 8, GOLD);
        tft.drawRoundRect(30, 40, 100, 40, 8, WHITE);
        tft.setCursor(187, 47);
        tft.print(" Dish4");
        delay(70);
      }
      if (p.x > 30 && p.x < 130 && p.y > 140 && p.y < 180 )
      {
        Serial.println("Dish5");
        msg = "Dish5 Ordered";
        transmit();
        tft.fillRoundRect(180, 90, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(180, 90, 100, 40, 8, GOLD);
        tft.drawRoundRect(180, 90, 100, 40, 8, WHITE);
        tft.setCursor(187, 97);
        tft.print(" Dish5");
        delay(70);
      }
      if (p.x > 30 && p.x < 130 && p.y > 90 && p.y < 130)
      {
        Serial.println("Dish6");
        msg = "Dish6 Ordered";
        transmit();
        tft.fillRoundRect(180, 140, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(180, 140, 100, 40, 8, GOLD);
        tft.drawRoundRect(180, 140, 100, 40, 8, WHITE);
        tft.setCursor(187, 147);
        tft.print(" Dish6");
        delay(70);
      }

      if (p.x > 10 && p.x < 210 && p.y > 40 && p.y < 80)
      {
        Serial.println("Bill");
        msg = "Customer Bill";
        transmit();
        tft.fillRoundRect(210, 190, 100, 40, 8, WHITE);
        delay(70);
        tft.fillRoundRect(210, 190, 100, 40, 8, GREEN);
        tft.drawRoundRect(210, 190, 100, 40, 8, WHITE);
        tft.setCursor(227, 197);
        tft.print(" Bill");
        delay(70);
      }
    }
}

 

Code for Receiver

#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile
#include <LiquidCrystal_I2C.h>
//String msg;
LiquidCrystal_I2C lcd(0x27, 16, 2);
RH_ASK driver;
#define buzzer 2
void setup()
{
    Serial.begin(9600);  // Debugging only
    pinMode(buzzer, OUTPUT);
    lcd.begin();
    lcd.clear(); 
    if (!driver.init())
         Serial.println("init failed");
}
void loop()
{
    uint8_t buf[17];
    uint8_t buflen = sizeof(buf);
    if (driver.recv(buf, &buflen)) // Non-blocking
    {
      int i;
      digitalWrite(buzzer, HIGH);
      delay(1000);
      digitalWrite(buzzer, LOW);
      // Message with a good checksum received, dump it.
      Serial.print("Message: ");
      Serial.println((char*)buf);
      lcd.clear(); 
      lcd.setCursor(0,0);
      lcd.print("T1:");
      lcd.print((char*)buf);            
    }
}

Video

Get Our Weekly Newsletter!

Subscribe below to receive most popular news, articles and DIY projects from Circuit Digest

Comments

  • ivan's picture
    ivan
    Mar 16, 2020

    1. hi can you send the circuit diagram and the final source code in my email?

Log in or register to post Comment