Project in progress

Unique TFT Shield for Arduino Uno (Start) © GPL3+

A unique TFT shield expanding the capabilities of an Arduino Uno.

  • 1,675 views
  • 5 comments
  • 16 respects

Components and supplies

About this project

Introduction

This article is the first article, with which I would like to begin a story about the unique TFT shield designed for the Arduino Uno platform, which makes it possible to significantly expand the capabilities of Arduino Uno. Despite the fact that this TFT shield is still under development, at the moment there is already a working device.

Hardware

Brief characteristics of TFT shield:

  • Size 3.5 " diagonal,
  • Resolution 320x240,
  • Number of colors 65536 (16-bit),
  • Resistive touch screen (XPT2046 controller),
  • 5 buttons,
  • RTC IC DS1307 with 3V lithium battery CR1220,
  • Slot for connecting a micro SD card,
  • 4-pin (2.54 mm) connector for connecting the Bluetooth module HC-05 (-06),
  • 20-pin (2.54 mm) connector for camera (OV7670).

Software

At the moment, the following library functions are implemented for working with graphics: drawing points, lines, circles, rectangles.The most popular library from Adafruit Industries was adapted for working with fonts. Additionally, work with the touch screen and buttons is implemented.Demo sketch to demonstrate the work with graphics and fonts:

#include <YATFT.h>                       // Hardware-specific library
#include <Adafruit_GFX.h>                // Include Adafruit-GFX library
#include <Fonts/FreeSerif9pt7b.h>        // Include Adafruit fonts
#include <Fonts/FreeSerifItalic24pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
YATFT tft(0);
uint32_t  total_time;
uint16_t  Color[4] = {BRIGHTBLUE, BRIGHTGREEN, BRIGHTRED, BRIGHTYELLOW};
uint16_t  Gray[7] = {GRAY0, GRAY1, GRAY2, GRAY3, GRAY4, GRAY5, GRAY6};
/*************************************************************************************************/
void ClearScreen (void)
{
   tft.SetColor(BLACK);   // Set fone color
   tft.ClearDevice();     // Fill all screen
}
void setup()
{
   Serial.begin(115200);  // initialize the serial port
   Serial.println("Arduino TFT_shield Example 1!");
   tft.begin();           // initialize the display
}
void loop()
{
   uint16_t  x, y, x2, y2, mask_gray;
   uint16_t  i;
   ClearScreen();
   // Fonts
   Serial.print("1) View Fonts (");
   total_time = millis();
   tft.SetColor(BRIGHTBLUE);
   tft.SetFont(NULL);
   tft.OutTextXY(5, 5, "Demonstration of work with the TFT display.");
   tft.SetColor(BRIGHTGREEN);
   tft.SetFont(&FreeSerif9pt7b);
   tft.OutTextXY(5, 20, "The   example   uses   fonts   from   Adafruit.");
   tft.SetFont(&FreeSerifItalic24pt7b);
   tft.SetColor(BRIGHTCYAN);
   tft.OutTextXY(5, 45, "3,5''");
   tft.SetColor(BRIGHTRED);
   tft.OutTextXY(90, 45, "QVGA");
   tft.SetColor(BRIGHTMAGENTA);
   tft.OutTextXY(230, 45, "disp.");
   tft.SetColor(BRIGHTYELLOW);
   tft.SetFont(&FreeSans24pt7b);
   tft.OutTextXY(5, 100, "A R D U I N O      +  T F T");
   tft.SetFont(NULL);
   for (i = 0; i < 7; i++)
   {
       tft.SetColor(Gray[i]);
       tft.OutTextXY(5, 170+10*i, "Demonstration of work with the TFT display.");
   }
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(3000);
   ClearScreen();
   // Circle
   Serial.print("2) Draw circle (");
   total_time = millis();
   tft.SetColor(BRIGHTRED);
   for (i = 10; i < GetMaxY()>>1; i += 10) {
       tft.DrawCirc(GetMaxX()>>1, GetMaxY()>>1, i);
   }
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
   // DrawFillCircle & DrawFillRect
   Serial.print("3) Draw FillCircle and FillRect (");
   total_time = millis();
   tft.SetColor(BRIGHTRED);
   tft.DrawFillCirc(GetMaxX()>>1,GetMaxY()>>1,110);
   tft.SetColor(BRIGHTCYAN);
   tft.DrawFillRect(GetMaxX()/2-77,GetMaxY()/2-77, GetMaxX()/2+77,GetMaxY()/2+77);
   tft.SetColor(BRIGHTGREEN);
   tft.DrawFillCirc(GetMaxX()>>1,GetMaxY()>>1,77);
   tft.SetColor(BRIGHTMAGENTA);
   tft.DrawFillRect(GetMaxX()/2-54,GetMaxY()/2-54, GetMaxX()/2+54,GetMaxY()/2+54);
   tft.SetColor(BRIGHTBLUE);
   tft.DrawFillCirc(GetMaxX()>>1,GetMaxY()>>1,54);
   tft.SetColor(BRIGHTYELLOW);
   tft.DrawFillRect(GetMaxX()/2-37,GetMaxY()/2-37, GetMaxX()/2+37,GetMaxY()/2+37);
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
   ClearScreen();
   // Arc
   Serial.print("4) Draw Arc (");
   total_time = millis();
   ClearScreen();
   tft.SetColor(BRIGHTBLUE);
   tft.DrawArc((GetMaxX()>>1)-60,(GetMaxY()>>1)-60,(GetMaxX()>>1)+60,(GetMaxY()>>1)+60,20,30,0xFF);
   tft.SetColor(BRIGHTGREEN);
   tft.DrawArc((GetMaxX()>>1)-40,(GetMaxY()>>1)-40,(GetMaxX()>>1)+40,(GetMaxY()>>1)+40,20,30,0xFF);
   tft.SetColor(BRIGHTRED);
   tft.DrawArc((GetMaxX()>>1)-20,(GetMaxY()>>1)-20,(GetMaxX()>>1)+20,(GetMaxY()>>1)+20,20,30,0xFF);
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
   Serial.print("5) Draw FillBevel (");
   total_time = millis();
   tft.SetColor(BRIGHTBLUE);
   tft.DrawFillBevel((GetMaxX()>>1)-60,(GetMaxY()>>1)-60,(GetMaxX()>>1)+60,(GetMaxY()>>1)+60,30);
   tft.SetColor(BRIGHTGREEN);
   tft.DrawFillBevel((GetMaxX()>>1)-40,(GetMaxY()>>1)-40,(GetMaxX()>>1)+40,(GetMaxY()>>1)+40,30);
   tft.SetColor(BRIGHTRED);
   tft.DrawFillBevel((GetMaxX()>>1)-20,(GetMaxY()>>1)-20,(GetMaxX()>>1)+20,(GetMaxY()>>1)+20,30);
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
   ClearScreen();
   Serial.print("6) Draw Arc (");
   total_time = millis();
   for (i = 0; i < 4; i++) {
       tft.SetColor(Color[i]);
       tft.DrawArc((GetMaxX()>>1),(GetMaxY()>>1)-50,(GetMaxX()>>1),(GetMaxY()>>1)+50,50,60,0x11<<i);
   }
   for (i = 0; i < 4; i++) {
       tft.SetColor(Color[i]);
       tft.DrawArc((GetMaxX()>>1),(GetMaxY()>>1)-30,(GetMaxX()>>1),(GetMaxY()>>1)+30,35,45,0x11<<i);
   }
   for (i = 0; i < 4; i++) {
       tft.SetColor(Color[i]);
       tft.DrawArc((GetMaxX()>>1),(GetMaxY()>>1),(GetMaxX()>>1),(GetMaxY()>>1),20,30,0x11<<i);
   }
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
   ClearScreen();
   // Draw 1000 random lines
   Serial.print("7) Draw 1000 random lines (");
   total_time = millis();
   for (i = 0; i < 1000; i++) {
       tft.SetColor(random(65535));
       x  = random(GetMaxX());
       y  = random(GetMaxY());
       x2 = random(GetMaxX());
       y2 = random(GetMaxY());
       tft.DrawLine(x, y, x2, y2);
   }
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
   // Draw 1000 random lines
   Serial.print("8) ReDraw 10 Fill Screen (");
   total_time = millis();
   tft.SetColor(BLACK);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BRIGHTBLUE);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(YELLOW);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BRIGHTGREEN);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BRIGHTRED);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BRIGHTCYAN);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(GREEN);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BRIGHTYELLOW);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BRIGHTCYAN);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   tft.SetColor(BLACK);   // Set fone color
   tft.ClearDevice();     // Fill all screen
   total_time = millis() - total_time;
   Serial.print(total_time);
   Serial.println(" ms)");
   delay(1000);
}

A demo sketch to demonstrate how to work with fonts and a touch screen:

#include <YATFT.h>                       // Hardware-specific library
#include <SPI.h>                         // Include SPI library
#include <XPT2046_Touchscreen.h>         // Include Touchscreen library
#include <Adafruit_GFX.h>                // Include Adafruit-GFX library
#include <Fonts/FreeSerif9pt7b.h>        // Include Adafruit fonts
#include <Fonts/FreeSerifItalic24pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
// Touchscreen: MOSI=11, MISO=12, SCK=13, CS=2
#define CS_PIN  2
XPT2046_Touchscreen ts(CS_PIN, 255);
YATFT tft(0);
#define  Y_BAR_TOP      (GetMaxY()-50)
#define  Y_BAR_BOT      GetMaxY()
#define  BUTTON1_MASK   0x01
#define  BUTTON2_MASK   0x02
#define  BUTTON3_MASK   0x04
#define  BUTTON4_MASK   0x08
#define  BUTTON5_MASK   0x10
/* 
  If using the shield, all control and data lines are fixed, and
  a simpler declaration can optionally be used:
*/
//uint32_t  total_time;
uint16_t  pos_x[] = {0,0,0,0};
uint16_t  pos_y[] = {0,0,0,0};
uint8_t   pos_x_cnt = 0;
uint8_t   pos_y_cnt = 0;
uint16_t  pos_x_mid = 0;
uint16_t  pos_y_mid = 0;
uint16_t  color_paint = WHITE;
uint8_t   buttons = 0;
uint16_t  Color[4] = {BRIGHTBLUE, BRIGHTGREEN, BRIGHTRED, BRIGHTYELLOW};
uint16_t  Gray[7] = {GRAY0, GRAY1, GRAY2, GRAY3, GRAY4, GRAY5, GRAY6};
/*************************************************************************************************/
void ClearScreen (void)
{
   tft.SetColor(BLACK);   // Set fone color
   tft.ClearDevice();     // Fill all screen
}
void setup()
{
   Serial.begin(115200);  // initialize the serial port
   Serial.println("Arduino TFT_shield Example1!");
   ts.begin();            // Init Touchscreen
   SPI.end();             // Disable SPI for correct work DB2 (SS) pin 
   tft.begin();           // initialize the display
   RefreshWindow();
}
void loop()
{
   uint16_t  x, y;
   // Touch
   // When the SS pin is set as OUTPUT, it can be used as
   // a general purpose output port (it doesn't influence
   // SPI operations).
   SPI.begin();
   if (ts.touched())
   {
       TS_Point p = ts.getPoint();
       Serial.print(F("Pressure = "));
       Serial.print(p.z);
       Serial.print(F(", x = "));
       Serial.print(p.x);
       Serial.print(F(", y = "));
       Serial.print(p.y);
       Serial.println();
       delay(3);     // Delay for filtering
       SPI.end();  // Disable SPI for correct work DB2 (SS) pin 
       // Calculate coordinates x, y from code ADC
       if (p.x < 200) p.x = 200;
       if (p.y < 250) p.y = 250;
#if 0
       x = (uint16_t)(320L - ((uint32_t)p.x - 200L)*10L/115L);
       y = (uint16_t)(((uint32_t)p.y - 250L)/15L);
#else
       x = (uint16_t)(0 + ((uint32_t)p.y - 200L)*10L/115L);
       y = (uint16_t)(((uint32_t)p.x - 250L)/15L);
#endif
       // Filtering 
       pos_x_mid = (pos_x[0] + pos_x[1] + pos_x[2] + pos_x[3])/4;
       pos_y_mid = (pos_y[0] + pos_y[1] + pos_y[2] + pos_y[3])/4;
       pos_x[pos_x_cnt++] = x;
       pos_y[pos_y_cnt++] = y;
       pos_x_cnt &= 0x03;
       pos_y_cnt &= 0x03;
       if (x > (pos_x_mid - 10) && x < (pos_x_mid + 10) && y > (pos_y_mid - 10) && y < (pos_y_mid + 10 )) {
           if (y > Y_BAR_TOP && y < Y_BAR_BOT) {
               if (x < 1*(GetMaxX()+1)/5) {  // Touch Bar 1
                   color_paint = Color[0];
                   RefreshTitle();
               } else
               if (x < 2*(GetMaxX()+1)/5) {  // Touch Bar 2
                   color_paint = Color[1];
                   RefreshTitle();
               } else
               if (x < 3*(GetMaxX()+1)/5) {  // Touch Bar 3
                   color_paint = Color[2];
                   RefreshTitle();
               } else
               if (x < 4*(GetMaxX()+1)/5) {  // Touch Bar 4
                   color_paint = Color[3];
                   RefreshTitle();
               } else {                     // Clear screen
                   RefreshWindow();
               }
           } else {
               tft.SetColor(color_paint);
               tft.DrawFillRect(x-1, y-1, x+1, y+1);
           }
       }
   }
   SPI.end();  // Disable SPI for correct work DB2 (SS) pin 
   ScanKey();
}
void  RefreshWindow(void)
{
   color_paint = WHITE;
   ClearScreen();
   for (uint8_t i = 0; i < 4; i++) {
       tft.SetColor(Color[i]);
       tft.DrawFillRect((i+1)*((GetMaxX()+1)/5), Y_BAR_TOP, (i)*((GetMaxX()+1)/5), Y_BAR_BOT);
   }
   RefreshTitle();
   tft.SetColor(WHITE);
   tft.OutTextXY(GetMaxX() - 50, GetMaxY() - 45, "Clear");
   tft.OutTextXY(GetMaxX() - 55, GetMaxY() - 25, "screen");
}
void  RefreshTitle(void)
{
   tft.SetColor(color_paint);
   tft.SetFont(&FreeSerif9pt7b);
   tft.OutTextXY(3, 20, "Touch     color     bar     and     screen     or     press     key.");
}
void  ScanKey(void)
{
   static uint8_t buttons_last = 0;
   buttons = tft.scanButtons();
   if (buttons != buttons_last) {
       if (buttons & BUTTON1_MASK) {  // Bar 1
           color_paint = Color[0];
           RefreshTitle();
       }
       if (buttons & BUTTON2_MASK) {  // Bar 2
           color_paint = Color[1];
           RefreshTitle();
       }
       if (buttons & BUTTON3_MASK) {  // Bar 3
           color_paint = Color[2];
           RefreshTitle();
       }
       if (buttons & BUTTON4_MASK) {  // Bar 4
           color_paint = Color[3];
           RefreshTitle();
       }
       if (buttons & BUTTON5_MASK) {  // Clear screen
           RefreshWindow();
       }
   }
   buttons_last = buttons;
}

Demo sketch of the logical game "Columns" for demonstration of work with graphics, text and buttons:

#include <YATFT.h>
#include <XPT2046_Touchscreen.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
#include <Fonts/FreeSerif9pt7b.h>
YATFT tft(0);
long randNumber;
#define KEY_EMPTY            0
#define KEY_SWAP             1
#define KEY_FALL             2
#define KEY_LEFT             3
#define KEY_RIGHT            4
#define DISPLAY_MAX_X 320
#define DISPLAY_MAX_Y 240
#define MaxCol       8 
#define MaxRow       17
#define SmeX         3
#define SmeY         3
#define razmer       15
#define LL           250
#define NumCol       6
#define MaxLevel     8
#define PeriodLevel  80
#define DISP_LEFT    ((DISPLAY_MAX_X - MaxCol*razmer)/2 - 2)
#define DISP_RIGHT   ((DISPLAY_MAX_X + MaxCol*razmer)/2 + 2)
#define DISP_TOP     ((DISPLAY_MAX_Y - (MaxRow-4)*razmer)/2 - 2 - 10)
#define DISP_BOT     ((DISPLAY_MAX_Y + (MaxRow-4)*razmer)/2 + 2 - 10)
uint8_t  MasSt[MaxCol][MaxRow], MasTmp[MaxCol][MaxRow], MasOld[MaxCol][MaxRow], fignext[3];
uint8_t  Level=1, OldLevel, tr, flfirst=1;
uint16_t MasCol[]={WHITE, BLACK, BRIGHTRED, BRIGHTBLUE, BRIGHTGREEN, BRIGHTYELLOW, BRIGHTMAGENTA, BRIGHTCYAN};
unsigned long  Counter,Score=0, TScore=0, Record=0, OldRecord, OldScore, myrecord;
uint16_t tempspeed;
bool     fl, Demo=true, myfl=false, Arbeiten=false, FlNew, FlZ=false;
int8_t   VAL, Mp, x,y;
int8_t   mmm [4][2]={{-1,0},{0,-1},{1,0},{0,1}};
uint16_t MasSpeed[MaxLevel]={500,450,400,350,300,250,200,100};
/*********************************************************************/
void  setup(void)
{
   // initialize the serial port
   Serial.begin(115200);
   Serial.println("TFT_shield_Game1 example!");
   tft.begin(); // initialize the display
   randomSeed(analogRead(5));
   tft.SetColor(WHITE);
   tft.ClearDevice();
   tft.SetColor(RED);
   tft.SetFont(&FreeSerif9pt7b);
   tft.OutTextXY( 20,  20, "LEVEL");
   tft.OutTextXY(240,  20, "NEXT");
   tft.OutTextXY( 20,  75, "SCORE");
   tft.OutTextXY( 25, 130, "TOP");
   FlNew = true;
   ViewStacan();
   GetNext();
   delay(100);
   tft.SetColor(BLACK);
   tft.DrawLine(DISP_LEFT + 1, DISP_TOP + 0, DISP_LEFT + 1, DISP_BOT - 1);
   tft.DrawLine(DISP_LEFT + razmer*MaxCol+5-MaxCol,DISP_TOP + 0,DISP_LEFT + razmer*MaxCol+5-MaxCol, DISP_BOT - 1);
   tft.DrawLine(DISP_LEFT + 1, DISP_BOT - 1, DISP_LEFT + 1+razmer*MaxCol+5-MaxCol-1, DISP_BOT - 1);
   // Key
   tft.SetColor(BRIGHTBLUE);
   tft.DrawCirc( 32,228, 8);                                                                    // ROTATE
   tft.DrawLine( 88,220, 96,236); tft.DrawLine( 88,220,104,220); tft.DrawLine( 96,236,104,220); // DROP
   tft.DrawRect(152,220,157,236); tft.DrawRect(163,220,168,236);                                // PAUSE
   tft.DrawLine(232,220,232,236); tft.DrawLine(232,220,216,228); tft.DrawLine(232,236,216,228); // LEFT
   tft.DrawLine(280,220,280,236); tft.DrawLine(280,220,296,228); tft.DrawLine(280,236,296,228); // RIGHT
}
void  loop(void)
{
   if (Demo)  ProcDemo();
   else {
       if (Arbeiten) {
           mydelay(tempspeed);
           figmove(0,1);
       } else  if (mypush()==KEY_SWAP/*ShortPush*/) NewGame();
   }
}
uint8_t  mypush(void)
{
   unsigned long tpr = millis();
   uint8_t res = KEY_EMPTY;//NotPush;
   uint8_t button = 0;
   static uint8_t button_old;
   static uint8_t cnt = 0;
   button = tft.scanButtons();
   if (button) {
     cnt = 5;
     Serial.print("Scan Button: ");
     Serial.print(button, HEX);
     Serial.println();
     if (button != button_old) {
       if (button & 0x01) res = KEY_SWAP;
       if (button & 0x02) res = KEY_FALL;
       if (button & 0x04) {};
       if (button & 0x08) res = KEY_LEFT;
       if (button & 0x10) res = KEY_RIGHT;
       button_old = button;
     }
   }
   if (!cnt) {
     button_old = button;
   } else {
     cnt--;
   }
   return(res); 
}
void  ViewQuad(uint8_t i,uint8_t  j,uint8_t mycolor)
{
   if (j<3) return; 
   uint16_t wy = DISP_TOP + SmeY + (j-3)*razmer - j;
   uint16_t wx = DISP_LEFT + SmeX + i*razmer - i;
   if (mycolor!=0) {
       tft.SetColor(BLACK);
       tft.DrawRect(wx, wy, wx+razmer-1, wy+razmer-1);
       tft.SetColor(MasCol[mycolor]);
       tft.DrawFillRect(wx+1, wy+1, wx+1+razmer-3, wy+1+razmer-3);
   } else {
       tft.SetColor(WHITE);
       tft.DrawFillRect(wx+1, wy+0, wx+1+razmer-3, wy+1+razmer-3);
   }
}
void  ViewStacan(void)
{
   char myStr2[5];
   uint8_t h = tft.GetTextHeight(&FreeMonoBoldOblique12pt7b);
   tft.SetFont(&FreeMonoBoldOblique12pt7b);
   if (OldScore!=Score || FlNew) {
       sprintf(myStr2,"%05d",Score);
       int16_t w = tft.GetTextWidth(myStr2, &FreeMonoBoldOblique12pt7b);
       tft.SetColor(WHITE);
       tft.DrawFillRect(20,100,20+w+5,100+h);
       tft.SetColor(GREEN);
       tft.OutTextXY(20,100,myStr2);
       OldScore=Score;
   }
   if (OldRecord!=Record || FlNew)  {
       sprintf(myStr2,"%05d",Record );
       int16_t w = tft.GetTextWidth(myStr2, &FreeMonoBoldOblique12pt7b);
       tft.SetColor(WHITE);
       tft.DrawFillRect(20,155,20+w+5,155+h);
       tft.SetColor(GREEN);
       tft.OutTextXY(20,155,myStr2);
       OldRecord=Record;
   }
   if (OldLevel!=Level || FlNew)  {
       sprintf(myStr2,"%01d",Level );
       int16_t w = tft.GetTextWidth(myStr2, &FreeMonoBoldOblique12pt7b);
       tft.SetColor(WHITE);
       tft.DrawFillRect(25,45,25+w+5,45+h);
       tft.SetColor(GREEN);
       tft.OutTextXY(25,45,myStr2);
       OldLevel=Level;
   }
   FlNew=false;
   for (byte j=3;j<MaxRow;j++)
       for (byte i=0;i<MaxCol;i++)
           if (MasSt[i][j]!=MasOld[i][j]) ViewQuad(i,j,MasSt[i][j]);
   for (byte j=3;j<MaxRow;j++)
       for (byte i=0;i<MaxCol;i++)
           MasOld[i][j]=MasSt[i][j];
}
void  ClearMas(byte MasStx[MaxCol][MaxRow])
{
   for (byte j=0;j<MaxRow;j++)
       for (byte i=0;i<MaxCol;i++)
           (MasStx[i][j]=0);
}
void  Sosed (int i,int j,int dx,int dy, byte mode)
{
   int nx=i+dx;
   int ny=j+dy;
   if (nx>=0 && ny>=0 && nx<MaxCol && ny<MaxRow && MasSt[nx][ny]==MasSt[i][j]) {
       if (mode==1) MasTmp[i][j]++;
       else
       if (mode==2 && (MasTmp[nx][ny]>1 || MasTmp[i][j]>2 )) {
           MasTmp[nx][ny]=3; 
           MasTmp[i][j]=3;
       } else
       if (mode==3 && MasTmp[nx][ny]==3) {
           if (MasTmp[i][j]!=3) {
               MasTmp[i][j]=3; 
               fl=true;
           }
       }
   }
}
void  Sos(int i,int j, byte mode)
{
   for (byte k=0;k<4;k++) Sosed(i,j,mmm[k][0],mmm[k][1],mode);      
}
bool  FindFull(void)
{
   byte  i,j,k; bool  res; 
   res = false; 
   for (byte k=2;k<8;k++) {
       ClearMas(MasTmp);
       for (j=3;j<MaxRow;j++)
           for (i=0;i<MaxCol;i++)
               if (MasSt[i][j]==k) Sos(i,j,1);
       for (j=3;j<MaxRow;j++)
           for (i=0;i<MaxCol;i++)
               if (MasTmp[i][j]>1) Sos(i,j,2);
       do {
           fl=false;
           for (j=3;j<MaxRow;j++)
               for (i=0;i<MaxCol;i++)
                   if (MasTmp[i][j]>0) Sos(i,j,3);
       } while (fl);
       for (j=3;j<MaxRow;j++)
           for (i=0;i<MaxCol;i++)
               if (MasTmp[i][j]==3) {
                   MasSt[i][j]=1;
                   TScore++;
               }
   }
   if (TScore>0) {
       ViewStacan();
       FlZ=true;
       mydelay(500);
   }
   for (j=0;j<MaxRow;j++)
       for (i=0;i<MaxCol;i++) {
           while (MasSt[i][MaxRow-1-j]==1) {
               for (k=0;k<MaxRow-2-j;k++) MasSt[i][MaxRow-1-k-j]= MasSt[i][MaxRow-2-k-j];
               res=true;  
           }
       }
   return(res);
}
void  GetNext(void)
{
   byte dx=255;
   byte dy=60;
   x=3;
   y=0;
   for (byte i=0;i<3;i++) {
       //fig[i]=fignext[i];
       if (!Demo) MasSt[x][i]=fignext[i];
       fignext[i]=random(NumCol)+2;
       tft.SetColor(BLACK);
       tft.DrawRect(dx,dy+(razmer-1)*i,dx+razmer, dy+(razmer-1)*(i+1)+1);
       tft.SetColor(MasCol[fignext[i]]);
       tft.DrawFillRect(dx+1,dy+(razmer-1)*i+1, dx+razmer-1, dy+(razmer-1)*(i+1));
   }
   if (!Demo) {
       Counter++;
       if (Counter==PeriodLevel) {
           Counter=0; 
           Level++; 
           if (Level>MaxLevel) Level=MaxLevel;
       }
       tempspeed=MasSpeed[Level-1];
   }
}
void  MyScore(void)
{
   TScore=0;
   while(FindFull()) {
       if (TScore>7) Score=Score+TScore+(TScore-8)*2;
       else Score=Score+TScore;
       ViewStacan();
       FlZ=true;
       mydelay(1000);
   }
   FlZ=false;
}
void  ProcDemo(void)
{
   Score=0;
   GetNext();
   for (byte j=3;j<MaxRow;j++)
       for (byte i=0;i<MaxCol;i++)
           MasSt[i][j]=random(6)+2;
   ViewStacan();
   mydelay(1000);
   if (!Demo) return;
   MyScore();
   if (Record<Score) Record=Score;
}
void  mydelay(int md)
{
   unsigned long starttime=millis();  
   while (millis()-starttime < md) {
       VAL=0;
       Mp=mypush();
       if (Mp==KEY_RIGHT) {
           VAL=1;
       } else
       if (Mp==KEY_LEFT) {
           VAL=-1;
       }
       if ((VAL!=0 || Mp!=KEY_EMPTY/*NotPush*/) && Demo) {
           Demo=false; 
           NewGame();
       }
       if (VAL!=0 && figmove(VAL, 0) && !FlZ) {
           for (byte i=0;i<3;i++) {
               MasSt[x+VAL][y+i]=MasSt[x][y+i];
               MasSt[x][y+i]=0; 
           }
           ViewStacan(); 
           if (MasSt[x][y+3]==0) {
               tft.SetColor(WHITE);
               tft.DrawLine(DISP_LEFT+SmeX+x*(razmer-1)+1, DISP_TOP+SmeY+y*(razmer-1)-3, DISP_LEFT+SmeX+(x+1)*(razmer-1)-1, DISP_TOP+SmeY+y*(razmer-1)-3);
           }
           x=x+VAL; 
       }
       if (Mp==KEY_SWAP/*ShortPush*/ && !FlZ) {
           byte aa=MasSt[x][y];
           MasSt[x][y]=MasSt[x][y+2];
           MasSt[x][y+2]=MasSt[x][y+1];
           MasSt[x][y+1]=aa;
           ViewStacan();
       }
       if (Mp==KEY_FALL && !FlZ) tempspeed=50;
   }
}
void  NewGame(void)
{
   for (byte i=0; i<(MaxCol+1); i++) {
       tft.SetColor(BLACK);
       tft.DrawLine(DISP_LEFT+3+(razmer-1)*i, DISP_TOP, DISP_LEFT+3+(razmer-1)*i, DISP_BOT-3);
   }
   for (byte j=3;j<MaxRow;j++)
       for (byte i=0;i<MaxCol;i++)
           MasOld[i][j]=255;
   Score=0;
   FlNew=true;
   OldScore=Score;
   ClearMas(MasSt);
   Arbeiten=true;
   GetNext();
   Counter=0;
   Level=1;
   tempspeed=MasSpeed[0];
   Record=myrecord;
   ViewStacan();
}
void  gameover(void)
{
   Arbeiten=false;
   tft.SetColor(BLACK);
   tft.DrawRect(112,90,202,145);
   tft.SetColor(RED);
   tft.DrawFillRect(113,91,201,144);
   tft.SetFont(&FreeSerif9pt7b);
   tft.SetColor(WHITE);
   tft.OutTextXY(132, 100, "GAME");
   tft.OutTextXY(135, 120, "OVER");
}
bool  figmove(int dx, int dy)
{
   bool fff=false;
   if (x+dx<0 || x+dx>MaxCol-1) return(false);
   if (dx!=0) if (MasSt[x+dx][y+dy+2]==0) return(true); else return(false);
   if  (dy>0) {
       if (y+dy+2>MaxRow-1  || MasSt[x+dx][y+dy+2]>0) {
           if (y<3) gameover(); 
           else fff=true;
       } else {
           for (byte i=0;i<3;i++) MasSt[x][y+2-i+dy]=MasSt[x][y+2-i];
           MasSt[x][y]=0;                                 
           y=y+dy;
       }
       if (fff) {
           MyScore();
           GetNext(); 
       }
       ViewStacan(); 
   }
   return(true);
}

Demonstration

Below is added a video demonstrating the work of sketches.

Unique Arduino TFT shield

Thanks for attention.

Comments

Similar projects you might like

Simple LCD Timer With Arduino UNO

Project showcase by Hugo Blanc

  • 10,537 views
  • 7 comments
  • 25 respects

Programming ATtiny85 with Arduino Uno

Project tutorial by Arjun Ganesan

  • 213,036 views
  • 74 comments
  • 184 respects

Connect to Blynk using ESP8266 as Arduino Uno wifi shield

Project tutorial by Nolan Mathews

  • 73,611 views
  • 11 comments
  • 56 respects

Controlling an LED Matrix with Arduino Uno

Project tutorial by Igor Fonseca Albuquerque

  • 33,113 views
  • 5 comments
  • 28 respects

4x4x4 LED cube with Arduino Uno and 1sheeld

Project tutorial by Hassan Ibrahim

  • 31,045 views
  • 7 comments
  • 61 respects
Add projectSign up / Login