Projeto: Escrita/Desenho com Paleta de Cores

O Display LCD TFT 2,4″ é um display Touch que atua como uma shield para ser utilizado juntamente com Arduino, possui encaixe rápido e fácil permitindo ser utilizado de forma imediata, também possui slot de cartão SD que permite o armazenamento de dados e imagens para exibição. Conta com uma excelente resolução com 4 led’s de iluminação e 18 bits de cores vivas.
É comumente utilizado em projetos que necessitam a interação do sistema com o usuário, sendo possível utilizar elementos gráficos e respostas ao toque. Como possui fácil interação com qualquer microcontrolador, é uma opção viável e com excelente custo-benefício para estudantes e hobbystas.
Funcionalidades Suportadas
- Exibição de texto, formas geométricas e imagens BMP de 240×320 via cartão SD;
- Detecção de toque com coordenadas X/Y e pressão Z;
- Interface gráfica interativa (botões, slides, menus);
- Ideal para projetos como controle de acesso, painéis de status, jogos simples etc.
Dicas Importantes:
- Ao usar com Arduino Uno, quase todos os pinos ficam ocupados. Se tiver a necessidade de adicionar sensores ou outros módulos, o Arduino Mega é mais indicado.
- Evite que o conector USB do Uno encoste no Shield, pode causar curto.
- Para imagens estáveis, é melhor usar fonte externa do que só a USB do computador.
Projeto de Escrita/Desenho com Paleta de Cores:
Neste projeto foi utilizado o Arduino Uno, juntamente com o Display LCD TFT 2,4″ shield Touch para Arduino para a seleção de cores na paleta e ajuste da espessura do traço ao desenhar. Foram dispostos os botões para a seleção de cor (COLOUR), botão para limpar a tela (CLR), e para ajuste da espessura do traço (PENZISE).


Esse projeto é um ótimo exemplo para quem quer aprender:
- Manipulação gráfica: como desenhar formas, textos e cores na tela;
- Interação com o usuário: como capturar toques e responder a eles;
- Estrutura de menus: como criar interfaces com botões e navegação;
- Modularidade: o código está bem dividido em funções, o que facilita manutenção e expansão;
- Calibração de touchscreen: entender como mapear coordenadas físicas para coordenadas visuais;
Bibliotecas utilizadas:
/*************************************Eletrodex Eletronica**********************************************/
#include <TouchScreen.h> //Biblioteca de touch
#include <LCDWIKI_GUI.h> //Biblioteca de graficos
#include <LCDWIKI_KBV.h> //Biblioteca de Hardware especifico
LCDWIKI_KBV my_lcd(240,320,A3,A2,A1,A0,A4);//width,height,cs,cd,wr,rd,reset
#define YP A3
#define XM A2
#define YM 9
#define XP 8
//parametros de calibraçao
#define TS_MINX 124
#define TS_MAXX 906
#define TS_MINY 83
#define TS_MAXY 893
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
uint16_t color_mask[] = {0xF800,0xFFE0,0x07E0,0x07FF,0x001F,0xF81F}; //Seleçao de cor
#define COLORBOXSIZE my_lcd.Get_Display_Width()/6
#define PENBOXSIZE my_lcd.Get_Display_Width()/4
int16_t old_color, current_color,flag_colour;
int16_t old_pen,current_pen,flag_pen;
boolean show_flag = true;
void show_string(uint8_t *str,int16_t x,int16_t y,uint8_t csize,uint16_t fc, uint16_t bc,boolean mode)
{
my_lcd.Set_Text_Mode(mode);
my_lcd.Set_Text_Size(csize);
my_lcd.Set_Text_colour(fc);
my_lcd.Set_Text_Back_colour(bc);
my_lcd.Print_String(str,x,y);
}
//Visualizaçao do menu de cores
void show_color_select_menu(void)
{
uint16_t i;
for(i = 0;i<6;i++)
{
my_lcd.Set_Draw_color(color_mask[i]);
my_lcd.Fill_Rectangle(i*COLORBOXSIZE, 0, (i+1)*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
my_lcd.Set_Draw_color(GREEN);
my_lcd.Fill_Round_Rectangle(109, 21, 138,39, 5);
show_string("OK",113,23,2,RED, BLACK,1);
}
//Visualizaçao do menu da espessura da caneta
void show_pen_size_select_menu(void)
{
uint16_t i;
my_lcd.Set_Text_Mode(1);
my_lcd.Set_Text_Size(2);
my_lcd.Set_Text_colour(GREEN);
my_lcd.Set_Text_Back_colour(BLACK);
for(i = 0;i<4;i++)
{
my_lcd.Print_Number_Int(i+1, (PENBOXSIZE-50)/2+PENBOXSIZE*i, (COLORBOXSIZE/2-16)/2, 0, ' ',10);
}
my_lcd.Set_Draw_color(RED);
my_lcd.Fill_Rectangle(24, 9, 54, 9);
my_lcd.Fill_Rectangle(84, 8, 114, 10);
my_lcd.Fill_Rectangle(144, 7, 174, 11);
my_lcd.Fill_Rectangle(204, 6, 234, 12);
my_lcd.Set_Draw_color(GREEN);
my_lcd.Fill_Round_Rectangle(109, 21, 138,39, 5);
show_string("OK",113,23,2,RED, BLACK,1);
}
//Visualizaçao do menu principal
void show_main_menu(void)
{
my_lcd.Set_Draw_color(YELLOW);
my_lcd.Fill_Round_Rectangle(5, 0, 84,39, 5);
my_lcd.Fill_Round_Rectangle(145, 0, 234,39, 5);
show_string("COLOUR",10,12,2,BLUE, BLACK,1);
show_string("PENSIZE",149,12,2,BLUE, BLACK,1);
my_lcd.Set_Draw_color(MAGENTA);
my_lcd.Fill_Round_Rectangle(90, 0, 139,39, 5);
show_string("CLR",98,12,2,WHITE, BLACK,1);
}
void setup(void)
{
Serial.begin(9600);
my_lcd.Init_LCD();
Serial.println(my_lcd.Read_ID(), HEX);
my_lcd.Fill_Screen(BLACK);
show_main_menu();
current_color = RED;
current_pen = 0;
pinMode(13, OUTPUT);
/*
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
currentcolor = RED;
pinMode(13, OUTPUT);
//tft.fillRect(0, 80, 240, 20, RED);
tft.setCursor(0, 80);
tft.setTextColor(RED); tft.setTextSize(1);
tft.println("Hello World!");
tft.println(01234.56789);
*/
}
#define MINPRESSURE 10
#define MAXPRESSURE 1000
void loop()
{
comme:
digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
{
if (p.y < (TS_MINY-5))
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Fill_Rectangle(0, COLORBOXSIZE, my_lcd.Get_Display_Width()-1, my_lcd.Get_Display_Height()-1);
}
//p.x = my_lcd.Get_Display_Width()-map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
//p.y = my_lcd.Get_Display_Height()-map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
p.x = map(p.x, TS_MINX, TS_MAXX, 0, my_lcd.Get_Display_Width());
p.y = map(p.y, TS_MINY, TS_MAXY, 0,my_lcd.Get_Display_Height());
if(p.y < COLORBOXSIZE)
{
if(((p.x>5)&&(p.x < 84))&&!flag_pen) //select color
{
flag_colour = 1;
if(show_flag)
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Fill_Rectangle(0,0,239,39);
show_color_select_menu();
}
show_flag = false;
switch(current_color)
{
case RED:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(0, 0, COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case YELLOW:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(COLORBOXSIZE, 0, 2*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case GREEN:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(2*COLORBOXSIZE, 0, 3*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case CYAN:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(3*COLORBOXSIZE, 0, 4*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case BLUE:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(4*COLORBOXSIZE, 0, 5*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case MAGENTA:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(5*COLORBOXSIZE, 0, 6*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
default:
break;
}
}
if(flag_colour)
{
if(p.y < COLORBOXSIZE/2)
{
old_color = current_color;
if (p.x < COLORBOXSIZE)
{
current_color = RED;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(0, 0, COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if (p.x < COLORBOXSIZE*2)
{
current_color = YELLOW;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(COLORBOXSIZE, 0, 2*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if (p.x < COLORBOXSIZE*3)
{
current_color = GREEN;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(2*COLORBOXSIZE, 0, 3*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if (p.x < COLORBOXSIZE*4)
{
current_color = CYAN;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(3*COLORBOXSIZE, 0, 4*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if (p.x < COLORBOXSIZE*5)
{
current_color = BLUE;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(4*COLORBOXSIZE, 0, 5*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if (p.x < COLORBOXSIZE*6)
{
current_color = MAGENTA;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(5*COLORBOXSIZE, 0, 6*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
}
if(old_color != current_color)
{
switch(old_color)
{
case RED:
{
my_lcd.Set_Draw_color(RED);
my_lcd.Draw_Rectangle(0, 0, COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case YELLOW:
{
my_lcd.Set_Draw_color(YELLOW);
my_lcd.Draw_Rectangle(COLORBOXSIZE, 0, 2*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case GREEN:
{
my_lcd.Set_Draw_color(GREEN);
my_lcd.Draw_Rectangle(2*COLORBOXSIZE, 0, 3*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case CYAN:
{
my_lcd.Set_Draw_color(CYAN);
my_lcd.Draw_Rectangle(3*COLORBOXSIZE, 0, 4*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case BLUE:
{
my_lcd.Set_Draw_color(BLUE);
my_lcd.Draw_Rectangle(4*COLORBOXSIZE, 0, 5*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case MAGENTA:
{
my_lcd.Set_Draw_color(MAGENTA);
my_lcd.Draw_Rectangle(5*COLORBOXSIZE, 0, 6*COLORBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
default:
break;
}
}
}
else if(p.y < COLORBOXSIZE)
{
if((p.x>109)&&(p.x<138))
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Fill_Rectangle(0,0,239,39);
show_main_menu();
flag_colour = 0;
show_flag = true;
goto comme;
}
}
}
if(((p.x>145)&&(p.x < 234))&&!flag_colour) //select pen size
{
flag_pen = 1;
if(show_flag)
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Fill_Rectangle(0,0,239,39);
show_pen_size_select_menu();
}
show_flag = false;
switch(current_pen)
{
case 0:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(0, 0, PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case 1:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(PENBOXSIZE, 0, 2*PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case 2:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(2*PENBOXSIZE, 0, 3*PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case 3:
{
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(3*PENBOXSIZE, 0, 4*PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
default:
break;
}
}
if(flag_pen)
{
if(p.y < COLORBOXSIZE/2)
{
old_pen = current_pen;
if(p.x < PENBOXSIZE)
{
current_pen = 0;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(0, 0, PENBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if(p.x < 2*PENBOXSIZE)
{
current_pen = 1;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(PENBOXSIZE, 0, 2*PENBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if(p.x < 3*PENBOXSIZE)
{
current_pen = 2;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(2*PENBOXSIZE, 0, 3*PENBOXSIZE-1, COLORBOXSIZE/2-1);
}
else if(p.x < 4*PENBOXSIZE)
{
current_pen = 3;
my_lcd.Set_Draw_color(WHITE);
my_lcd.Draw_Rectangle(3*PENBOXSIZE, 0, 4*PENBOXSIZE-1, COLORBOXSIZE/2-1);
}
if(old_pen != current_pen)
{
switch(old_pen)
{
case 0:
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Draw_Rectangle(0, 0, PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case 1:
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Draw_Rectangle(PENBOXSIZE, 0, 2*PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case 2:
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Draw_Rectangle(2*PENBOXSIZE, 0, 3*PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
case 3:
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Draw_Rectangle(3*PENBOXSIZE, 0, 4*PENBOXSIZE-1, COLORBOXSIZE/2-1);
break;
}
default:
break;
}
}
}
else if(p.y < COLORBOXSIZE)
{
if((p.x>109)&&(p.x<138))
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Fill_Rectangle(0,0,239,39);
show_main_menu();
flag_pen = 0;
show_flag = true;
goto comme;
}
}
}
if(((p.x>90)&&(p.x < 139))&&!flag_colour&&!flag_pen)
{
my_lcd.Set_Draw_color(BLACK);
my_lcd.Fill_Rectangle(0,COLORBOXSIZE,my_lcd.Get_Display_Width()-1,my_lcd.Get_Display_Height()-1);
}
}
if (((p.y-current_pen) > COLORBOXSIZE) && ((p.y+current_pen) < my_lcd.Get_Display_Height())) //drawing
{
my_lcd.Set_Draw_color(current_color);
// if(1 == current_pen)
// {
// my_lcd.Draw_Pixel(p.x, p.y);
// }
// else
// {
my_lcd.Fill_Circle(p.x, p.y,current_pen);
// }
}
}
}



