#include <SD.h>
#include <SPI.h>
#include "TFTv2.h"
#include <stdint.h>
#include <TouchScreen.h>
File bmpFile;
//screen number-screen name-bmp file name
//1 HOME NIRTOUS OFF home.bmp
//2 HOME NIRTOUS ON homeblue.bmp
//3 TRACK COMPUTER APPS trkcomp.bmp
//4 ZERO TO 60 APP zero60.bmp
//5 1/8 MILE APP 18mile.bmp
//6 1/4 MILE APP 14mile.bmp
//7 NITROUS ON nitron.bmp
//8 NITROUS OFF nitroff.bmp
//9 NITROUS SETTINGS nitroset.bmp
//10 TPS WOT CALIBRATE wotcalb.bmp
//11 RPM N20 ON SET rpmonset.bmp
//12 RPM N20 OFF SET rpmofset.bmp
//13 OBDII DATA getdata.bmp
//14 LIVE obdii DATA livedata.bmp
unsigned char saved_spimode;
int bmpWidth, bmpHeight;
uint8_t bmpDepth, bmpImageoffset;
#define chipSelect 4
//set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
int imagedrawn = 0;
int buttonpress = 0;
int nitrous = 0;
int firstpress = 0;
#define TS_MINX 116*2
#define TS_MAXX 890*2
#define TS_MINY 83*2
#define TS_MAXY 913*2
TouchScreen ts = TouchScreen(XP, YP, XM, YM); //init TouchScreen port pins
void setup()
{
Tft.TFTinit(); //init TFT library
pinMode(11,INPUT);
pinMode(12,INPUT);
pinMode(13,INPUT);
TFT_CS_HIGH;
pinMode(chipSelect,OUTPUT);
digitalWrite(chipSelect,HIGH);
Serial.begin(9600);
SPI.begin();
Tft.TFTinit();
//SPI.setClockDivider(SPI_CLOCK_DIV4);
//SDcard_info();
/**/
DDRB |= 0x04;
card.init(SPI_FULL_SPEED,chipSelect);//SPI_QUARTER_SPEED SPI_HALF_SPEED, SPI_FULL_SPEED,
if(!SD.begin(chipSelect))//SPI_QUARTER_SPEED,
{ //53 is used as chip select pin
Serial.println("failed!");
while(1);
}
Serial.println("SD OK!");
}
void loop()
{
Serial.print("Nitrous:");
Serial.print(nitrous);
Serial.print(", ");
Serial.print("Button:");
Serial.print(buttonpress);
Serial.print(", ");
Serial.print("Screen:");
Serial.println(imagedrawn);
buttonpress = 0;
//Serial.print(buttonpress);
//DRAW HOME SCREEN ONCE
if(imagedrawn <= 0){ //LINES CONTAINED IN THE "IF" STATEMENT DRAW AN IMAGE FROM THE SD CARD
bmpFile = SD.open("home.bmp");
if (! bmpReadHeader(bmpFile)) {
Serial.println("bad bmp");
return;
}
bmpdraw(bmpFile, 0, 0);
bmpFile.close();
imagedrawn = 1;
}
//GET TOUCH COORDINATE
Point p = ts.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
if (p.z > __PRESURE) {
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.println(p.y);
}
//DETERMINE ACTION FROM COORDINATE
if (p.x >= 10 && p.x <= 230 && p.y >= 10 && p.y <= 310 && imagedrawn == 1)
{
buttonpress = 100; //exit home screen
}
if (p.x >= 120 && p.x <= 180 && p.y >= 20 && p.y <= 120)
{
Serial.println("NITROUS ON/OFF");
buttonpress = 5;
}
if (p.x >= 190 && p.x <= 233 && p.y >= 4 && p.y <= 75)
{
Serial.println("NEXT");
buttonpress = 4;
}
if (p.x >= 190 && p.x <= 233 && p.y >= 85 && p.y <= 150)
{
Serial.println("HOME/RETURN");
buttonpress = 3;
}
if (p.x >= 190 && p.x <= 233 && p.y >= 175 && p.y <= 235)
{
Serial.println("SELECT");
buttonpress = 2;
}
if (p.x >= 190 && p.x <= 233 && p.y >= 240 && p.y <= 311)
{
Serial.println("PREVIOUS");
buttonpress = 1;
}
if (imagedrawn == 1 && buttonpress == 100 && firstpress == 1){
displaybmp(1); //track comp
imagedrawn = 3;
}
if (imagedrawn == 3 && buttonpress == 4 && nitrous == 0){
displaybmp(2); //nitrous off
imagedrawn = 8;
}
if (imagedrawn == 3 && buttonpress == 4 && nitrous == 1){
displaybmp(3); //nitrous on
imagedrawn = 8;
}
if (imagedrawn == 3 && buttonpress == 2){
displaybmp(5); //0-60
imagedrawn = 4;
}
if (imagedrawn == 4 && buttonpress == 3){
displaybmp(1); //track comp
imagedrawn = 3;
}
if (imagedrawn == 4 && buttonpress == 4){
displaybmp(6); //1/4mile
imagedrawn = 5;
}
if (imagedrawn == 5 && buttonpress == 3){
displaybmp(1); //track comp
imagedrawn = 3;
}
if (imagedrawn == 5 && buttonpress == 4){
displaybmp(5); //0-60
imagedrawn = 4;
}
if (imagedrawn == 5 && buttonpress == 3){
displaybmp(1); //track comp
imagedrawn = 3;
}
if (imagedrawn == 8 && buttonpress == 3 && nitrous == 0){
displaybmp(0); //nitrous off home
imagedrawn = 1;
}
if (imagedrawn == 8 && buttonpress == 3 && nitrous == 1){
displaybmp(4); //nitrous on home
imagedrawn = 1;
}
if (imagedrawn == 8 && buttonpress == 4){
displaybmp(1);
imagedrawn = 3;
}
if (imagedrawn == 3 && buttonpress == 3 && nitrous == 0){
displaybmp(0); //nitrous off home
imagedrawn = 1;
}
if (imagedrawn == 3 && buttonpress == 3 && nitrous == 1){
displaybmp(4); //nitrous on home
imagedrawn = 1;
}
if (imagedrawn == 8 && buttonpress == 5 && nitrous == 0){
displaybmp(3);
imagedrawn = 8;
nitrous = 1;
}
if (imagedrawn == 8 && buttonpress == 5 && nitrous == 1){
displaybmp(2);
imagedrawn = 8;
nitrous = 0;
}
delay(50);
firstpress = 1;
}
void displaybmp(int i)
{
char bmpfiles[][18]=
{
"home.bmp","trkcomp.bmp","nitroff.bmp","nitron.bmp","homeblue.bmp","zero60.bmp","14mile.bmp"
};
Serial.println(bmpfiles[i]);
bmpFile = SD.open(bmpfiles[i]);
// if (! bmpFile)
// {
// Serial.println("didnt find image:");
// Serial.println(bmpfiles[i]);
// while (1);
// }
//
if (! bmpReadHeader(bmpFile)) {
Serial.println("bad bmp");
return;
}
bmpdraw(bmpFile, 0, 0);
bmpFile.close();
buttonpress = 0;
}
/*********************************************/
// This procedure reads a bitmap and draws it to the screen
// its sped up by reading many pixels worth of data at a time
// instead of just one pixel at a time. increading the buffer takes
// more RAM but makes the drawing a little faster. 20 pixels' worth
// is probably a good place
#define BUFFPIXEL 20
void bmpdraw(File f, int x, int y)
{
bmpFile.seek(bmpImageoffset);
uint32_t time = millis();
uint16_t p;
uint8_t g, b;
int i, j;
uint8_t sdbuffer[3 * BUFFPIXEL]; // 3 * pixels to buffer
uint8_t buffidx = 3*BUFFPIXEL;
for (i=0; i< bmpHeight; i++)
{
for (j=0; j<bmpWidth; j++)
{
// read more pixels
if (buffidx >= 3*BUFFPIXEL)
{
bmpFile.read(sdbuffer, 3*BUFFPIXEL);
buffidx = 0;
}
// convert pixel from 888 to 565
b = sdbuffer[buffidx++]; // blue
g = sdbuffer[buffidx++]; // green
p = sdbuffer[buffidx++]; // red
p >>= 3;
p <<= 6;
g >>= 2;
p |= g;
p <<= 5;
b >>= 3;
p |= b;
// write out the 16 bits of color
Tft.sendData(p);
}
}
Serial.print(millis() - time, DEC);
Serial.println(" ms");
}
boolean bmpReadHeader(File f) {
// read header
uint32_t tmp;
if (read16(f) != 0x4D42) {
// magic bytes missing
return false;
}
// read file size
tmp = read32(f);
Serial.print("size 0x");
Serial.println(tmp, HEX);
// read and ignore creator bytes
read32(f);
bmpImageoffset = read32(f);
Serial.print("offset ");
Serial.println(bmpImageoffset, DEC);
// read DIB header
tmp = read32(f);
Serial.print("header size ");
Serial.println(tmp, DEC);
bmpWidth = read32(f);
bmpHeight = read32(f);
if (read16(f) != 1)
return false;
bmpDepth = read16(f);
Serial.print("bitdepth ");
Serial.println(bmpDepth, DEC);
if (read32(f) != 0) {
// compression not supported!
return false;
}
Serial.print("compression ");
Serial.println(tmp, DEC);
return true;
}
/*********************************************/
// These read data from the SD card file and convert them to big endian
// (the data is stored in little endian format!)
// LITTLE ENDIAN!
uint16_t read16(File f)
{
uint16_t d;
uint8_t b;
b = f.read();
d = f.read();
d <<= 8;
d |= b;
return d;
}
// LITTLE ENDIAN!
uint32_t read32(File f)
{
uint32_t d;
uint16_t b;
b = read16(f);
d = read16(f);
d <<= 16;
d |= b;
return d;
}