Here's the demo file I've promised, Hope you enjoy.
Allows the user to scroll between bmp images on a SD card using SD Class and Custom event handlers to suit the non genuine chip on the Sainsonic Screen.
Works with the 3.2" Touchscreen Provided by sainsonic with the
/*
Arduino Mega Sainsmart 3.2 TFT Touchscreen Demo
Written & Adaption of demo Source from Sainsmart
By BJ Smith
http://technomungo.blogspot.com.au
If this Helped you, donate me a few feathercoins @
6tCqWb5C65BfXXEw6yrKBHP8uMx8imW68Y
Explanation:
Cycle through all bitmap images in /images on flash card
Images must be even in dimensions and have 24bit colour
Will explore this glitch at some point.
Demonstrates seeking to data bits to display Bitmap display.
Was written due to the limitation of SDFAT Not allowing me to
load images out of the root directory.
Known Issues:
Images must be even in dimensions.
Doesn't white out the screen before displaying next image,
so if next image is smaller it'll leave some portion of the old image.
Will cover over the menu if the image is too big.
If you need consultation or help on your project I am available
at reasonable rates.
*/
#include "UTFT.h"
#include "SD.h"
//TOUCH SCREEN PINS
#define DCLK 6
#define CS 5
#define DIN 4
#define DOUT 3
#define IRQ 2
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define SD_PIN 53
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
int Image_Current = 0;
File root;
boolean isloading = false;
boolean backwards = false;
int lastfile = -1;
volatile boolean screenpressed = false;
unsigned int TP_X,TP_Y;
UTFT myGLCD(GEEE32, 38, 39, 40, 41);
void ShowMessage(const char* msg1, const char* msg2 = 0)
{
myGLCD.setColor(255, 0, 0);
myGLCD.fillRoundRect(55, 190, 265, 230);
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(255, 0, 0);
myGLCD.print(msg1, CENTER, 196);
if (msg2) myGLCD.print(msg2, CENTER, 210);
}
void LoadImage(File& file) //This does have a glitch, you need to have images with even dimensions.
{
//READ THE HEADER
int header = file.read();
int header2 = file.read();
int xoff = 0;
int yoff = 0;
if (header == 66 && header2 == 77) //Check if header = BM
{
file.seek(0x1C); //OFFSET FOR COLOR BITS
word BPP = read32(file);
if ( BPP ==0x18) //CHECK IF 24bit for TFT
{
file.seek(0x12); //OFFSET TO DIMENSIONS
word height = read32(file);
word width = read32(file);
xoff = SCREEN_WIDTH/2-(int)width/2; //USED TO CENTER THE IMAGE
yoff = SCREEN_HEIGHT/2-(int)height/2;
file.seek(0xA); //OFFSET TO DATA OFFSET
word bitmapOffset = read32(file);
file.seek(bitmapOffset); //SEEK TO READ POSITION
for (int y = (int)width; y > 0 ; y--)
{
for (int x = 0; x < (int)height ; x++)
{
byte b = file.read();
byte g = file.read();
byte r = file.read();
myGLCD.setColor(r,g,b);
myGLCD.drawPixel(x+xoff,y+yoff);
}
}
}
}
else
{
if (backwards)
{
previmage();
}
else
{
nextimg();
}
}
}
void WalkDirectory(File dir)
{
File entry = dir.openNextFile();
if (! entry) {
// no more files
lastfile = Image_Current;
}
if (entry.isDirectory()) {
WalkDirectory(entry);
}
else {
if (lastfile != Image_Current)
{
ShowMessage(entry.name());
}
LoadImage(entry);
}
entry.close();
}
void spistar() //SPI Start
{
digitalWrite(CS,HIGH);
digitalWrite(DCLK,HIGH);
digitalWrite(DIN,HIGH);
digitalWrite(DCLK,HIGH);
}
//**********************************************************
void WriteCharTo7843(unsigned char num) //SPI Write Data
{
unsigned char count=0;
unsigned char temp;
unsigned nop;
temp=num;
digitalWrite(DCLK,LOW);
for(count=0;count<8;count++)
{
if(temp&0x80)
digitalWrite(DIN,HIGH);
else
digitalWrite(DIN,LOW);
temp=temp<<1;
digitalWrite(DCLK,LOW);
nop++;
nop++;
digitalWrite(DCLK,HIGH);
nop++;
nop++;
}
}
//**********************************************************
unsigned int ReadFromCharFrom7843() //SPI Read Data
{
unsigned nop;
unsigned char count=0;
unsigned int Num=0;
for(count=0;count<12;count++)
{
Num<<=1;
digitalWrite(DCLK,HIGH);//DCLK=1; _nop_();_nop_();_nop_();
nop++;
digitalWrite(DCLK,LOW);//DCLK=0; _nop_();_nop_();_nop_();
nop++;
if(digitalRead(DOUT)) Num++;
}
return(Num);
}
void AD7843(void)
{
digitalWrite(CS,LOW);
WriteCharTo7843(0x90);
digitalWrite(DCLK,HIGH);
digitalWrite(DCLK,LOW);
TP_Y=ReadFromCharFrom7843();
WriteCharTo7843(0xD0);
digitalWrite(DCLK,HIGH);
digitalWrite(DCLK,LOW);
TP_X=ReadFromCharFrom7843();
digitalWrite(CS,HIGH);
}
void setup()
{
Serial.begin(9600);
for(int p=22;p<42;p++)
{
pinMode(p,OUTPUT);
}
for(int p=2; p<7;p++)
pinMode(p,OUTPUT);
pinMode(DOUT,INPUT);
pinMode(IRQ,INPUT);
// Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
myGLCD.fillScr(255, 255, 255);
//BACK BUTTON
myGLCD.setColor(255, 0, 0);
myGLCD.fillRoundRect(10, 190, 50, 230);
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(255, 0, 0);
myGLCD.print("<", 25, 202);
//FORWARD BUTTON
myGLCD.setColor(255, 0, 0);
myGLCD.fillRoundRect(270, 190, 310, 230);
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(255, 0, 0);
myGLCD.print(">", 285, 202);
spistar(); //setup the Touchscreen
pinMode(SD_PIN, OUTPUT);
if (!SD.begin(SD_PIN))
{
ShowMessage("SD not ready");
return;
}
attachInterrupt(0, screentouched, FALLING);
root = SD.open("/images");
WalkDirectory(root);
}
void screentouched() //TOUCH SCREEN EVENT HANDLER
{
noInterrupts();
if (!screenpressed)
{
screenpressed = true;
}
interrupts();
}
void checkscreen()
{
unsigned int lx,ly;
int runningy =0; //Cumlative total
int ycount =0; //Divisor
int runningx =0; //Cumlative total
int xcount=0; //Divisor
int dud = 0; // Count of out of range data
while (xcount <10 ||ycount <10) //This performorms multpile measurements, throws out the duds and
{
if (dud >5) break; //bail if press is glitchy
AD7843();
int yavg =((TP_X-340)*10/144)+2; //Landscape, so the Vals are swapped
int xavg =((TP_Y-320)/11);
if (yavg >=0&& yavg <=240)
{
runningy+=yavg;
ycount++;
}
else
{
dud++;
}
if (xavg >=0&& xavg <= 320)
{
runningx+=xavg;
xcount++;
}
else
{
dud++;
}
}
ly = (int)runningy/ycount;
lx = (int)runningx/xcount;
Serial.print("X,Y:");
Serial.print(lx);
Serial.print(",");
Serial.println(ly);
if (lx >= 270 && lx <= 310 && ly >= 190 && ly <= 230) //IF NEXT BUTTON 270, 190, 310, 230
{
backwards =false;
nextimg();
}
else
{
if (lx >= 10 && lx <= 50 && ly >= 190 && ly <= 230) //IF BACK BUTTON 10, 190, 50, 230
{
backwards = true;
previmage();
}
}
}
void loop()
{
if (screenpressed)
{
checkscreen();
delay(100); //Wait to remove double press in some circumstances (not on this example)
screenpressed= false;
}
}
void nextimg()
{
myGLCD.setColor(24, 0, 255);
myGLCD.print(">", 285, 202);
WalkDirectory(root);
if (lastfile >0) //Don't overrun the bounds of folder.
{
if (lastfile != Image_Current)
{
Image_Current++;
}
}
else
{
Image_Current++;
}
myGLCD.setColor(255, 255, 255);
myGLCD.print(">", 285, 202);
}
void previmage()
{
if (Image_Current >0/*&&!isloading*/)
{
Image_Current--;
myGLCD.setColor(24, 0, 255);
myGLCD.print("<", 25, 202);
root.rewindDirectory();
for (int i = 0; i <Image_Current; i++)
{
root.openNextFile();
}
WalkDirectory(root);
myGLCD.setColor(255, 255, 255);
myGLCD.print("<", 25, 202);
}
}
uint16_t read16(File f)
{
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File f)
{
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
What does it mean when the screen appears white with two red buttons and does nothing else?
ReplyDeleteWhat board are you using? This is very specific code to the sainsonic.
ReplyDelete