TFTLCD 2.8 with SD Card

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
rexo
 
Posts: 3
Joined: Sat Mar 22, 2014 2:19 pm

TFTLCD 2.8 with SD Card

Post by rexo »

Greetings,
Hope someone can help. I'm new to the forum and Arduino. I have a Uno with a version 1 TFTLCD shield. I have been able to get the TFTPaint and Graphics demos to work, so I started on my project. I am reading a digital input on pin 2, and am able to write to the screen, and use the touch screen interface.

My problem comes when I try to use the SD card. The SD card works in the above examples. And in my program I am able to initialize the SD card with the SD.begin(5) command. However, as soon as the SD card initializes, I can no longer write to the screen. The touch screen still works, but none of the graphics or text update. I have confirmed through the serial port that my code is still executing, it just seems to lock up the display. Any advice?

Thanks for any help.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: TFTLCD 2.8 with SD Card

Post by adafruit_support_rick »

Does the shield work with the tftbmp_shield example?

User avatar
rexo
 
Posts: 3
Joined: Sat Mar 22, 2014 2:19 pm

Re: TFTLCD 2.8 with SD Card

Post by rexo »

Yes, tftbmp_shield works fine.

Thanks for the response.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: TFTLCD 2.8 with SD Card

Post by adafruit_support_rick »

Then there must be something wrong with your code. If you post it, we can have a look.

User avatar
rexo
 
Posts: 3
Joined: Sat Mar 22, 2014 2:19 pm

Re: TFTLCD 2.8 with SD Card

Post by rexo »

OK, here is my code. The help is greatly appreciated?

Code: Select all

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <TouchScreen.h>
#include <Time.h>
#include <Wire.h>  
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
#include <SD.h>
#include <SPI.h>

// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
// There are examples in the sketch folder

boolean state;            // the state of the monitored pins
time_t  prevEventTime ;    // the time of the previous event
int count;
int rotation;
int onState;
int lastState;
int touched;
time_t duration;
time_t total;
time_t timeNow;
time_t resetTime;

#ifndef USE_ADAFRUIT_SHIELD_PINOUT 
#error "This sketch is intended for use with the TFT LCD Shield. Make sure that USE_ADAFRUIT_SHIELD_PINOUT is #defined in the Adafruit_TFTLCD.h library file."
#endif

// These are the pins for the shield!
#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 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define SD_CS 5 // Card select for shield use
File myFile;
File root;
Adafruit_TFTLCD tft;
uint8_t         spi_save;

void setup() {
  Serial.begin(9600);
  pinMode (10,OUTPUT);
 uint16_t identifier = tft.readID();
  tft.reset();
  tft.begin();
  
 //This is where I have problems. This code is from the examples, but if the SD.begin
 //is allowed to execute there is no refresh to the screen. The touch screen code
 //does execute fine. And I find the counters are all incrementing. If seems the 
 //tft.println and tft.fill commands are not working. 
 //I have the screen in landscape mode and am working in Arduino 1.03 IDE
 
 //Serial.println("Initializing SD card...");
 // if (!SD.begin(5)) {
 //Serial.println("failed!");
 //  return;
 // }
 // Serial.println("OK!");
 // spi_save = SPCR;

  setTime(0,0,0,1,1,1970); //Enter Date at Set Up
  tft.setRotation(3);
  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  tft.println("Bilge Monitor on ");
  showTime (timeNow);
  resetTime = now();
  tft.println();
  pinMode(3,OUTPUT); //Control backlight
  digitalWrite(3,1); //Write to pin 3(3,0) Off or (3,1) On
  onState=1;// State value for backlight is on
  lastState=1;
  touched=0;
  tft.fillRect(220, 0, 360, 40, RED);
  tft.setCursor(240,10);
  tft.setTextColor(BLACK);
  tft.print("Sleep");
  tft.setTextColor(WHITE);
  //pinMode(13,OUTPUT);
  
  #define MINPRESSURE 10
  #define MAXPRESSURE 1000
  
 }

void loop()
{
  digitalWrite(13, HIGH);
  Point p = ts.getPoint();
  digitalWrite(13, LOW);

  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

  // scale from 0->1023 to tft.width
  p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
  p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);


  if ((p.z > MINPRESSURE && p.z < MAXPRESSURE && p.x < 60 && p.y <80 && onState == 1) || 
      (p.z > MINPRESSURE && p.z < MAXPRESSURE&& onState == 0)) {
    touched=1;

  }
  if(touched==1){
    if(onState==1){
      digitalWrite(3,0); //Go into Sleep mode
      onState=0;
      touched=0;
      delay(500);
    }
    else {
      digitalWrite(3,1); //Wake up
      onState=1;
      touched=0;
      delay(500);
    }
  }  
  boolean val = digitalRead(2); 
  if(val != state)
  {
    //time_t duration = 0; // the time since the previous event
    state = val;
    time_t timeNow = now();
    if(prevEventTime > 0)  
      // if this was not the first state change, calculate the time from the previous change
      duration = timeNow - prevEventTime;
    logEvent(val, timeNow, resetTime, duration);  // log the event
    prevEventTime = timeNow;            // store the time for this event  
  }
}

void logEvent(boolean state, time_t timeNow, time_t resetTime, int duration)
{ 
   if( state == HIGH){
    tft.setCursor(0,0);
    tft.fillRect(0,70,700,700,BLACK);
    tft.println();
    tft.setCursor(0,70);
    tft.print("Pump off at ");
    showTime(timeNow);
    tft.println();

    if(duration>0){
      tft.println();
      tft.print("Last cycle ");
      showDuration(duration);
      tft.println();
      tft.println();
      total = total + duration;
      tft.print("ON ");
      showTotal(total);
      tft.println( "since reset");
      tft.println();
      tft.print ("Cycles since reset = ");
      tft.println (count);
      time_t timeOn = (timeNow - resetTime);
      tft.println ();
      showResetDuration (timeOn);
      tft.println ("since reset");
    }  
  }  

  if (state == LOW){
    tft.println();
    count = count + 1;
    tft.setCursor(0,0);
    tft.fillRect(0,70,700,700,BLACK);
    tft.println();
    tft.setCursor(0,70);
    tft.print("Pump on at ");
    showTime(timeNow);
  }
  tft.println();
}

void showTime(time_t t){
  // display the given time 
  tft.print(hour(t));
  printDigits(minute(t));
  //printDigits(second(t));
  tft.print(" ");
  tft.print(month(t));
  tft.print("/");
  //tft.print(" ");
  tft.print(day(t));
  //tft.print(" ");
  //tft.print(year(t)); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  tft.print(":");
  if(digits < 10)
    tft.print('0');
  tft.print(digits);
}

void showDuration(time_t duration){
  // prints the duration in days, hours, minutes and seconds
  if(duration >= SECS_PER_DAY){
    tft.print(duration / SECS_PER_DAY);
    tft.print(" day "); 
    duration = duration % SECS_PER_DAY;     
  }
  if(duration >= SECS_PER_HOUR){
    tft.print(duration / SECS_PER_HOUR);
    tft.print(" hr "); 
    duration = duration % SECS_PER_HOUR;     
  }
  if(duration >= SECS_PER_MIN){
    tft.print(duration / SECS_PER_MIN);
    tft.print(" min "); 
    duration = duration % SECS_PER_MIN;     
  }
  tft.print(duration);
  tft.print(" sec ");   
}

void showResetDuration(time_t duration){
  // prints the duration in days, hours, minutes and seconds
  //if(duration >= SECS_PER_DAY){
  tft.print(duration / SECS_PER_DAY);
  tft.print(" day "); 
  duration = duration % SECS_PER_DAY;     
}
void showTotal (time_t total){
  if(total >= SECS_PER_DAY){
    tft.print(total / SECS_PER_DAY);
    tft.print(" day "); 
    total = total % SECS_PER_DAY;     
  }
  if(total >= SECS_PER_HOUR){
    tft.print(total / SECS_PER_HOUR);
    tft.print(" hr "); 
    total = total % SECS_PER_HOUR;     
  }
  if(total >= SECS_PER_MIN){
    tft.print(total / SECS_PER_MIN);
    tft.print(" min "); 
    total = total % SECS_PER_MIN;     
  }
  tft.print(total);
  tft.print(" sec ");   
}

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: TFTLCD 2.8 with SD Card

Post by adafruit_support_rick »

OK. The problem is that the SD.begin changes the hardware SPCR (SPI Control Register) to be different than the way tft.begin sets it up. The libraries don't manage this register properly, so you have to do it yourself.

The rule is, before you start a sequence of tft operations, set SPCR to 0. Before you start a sequence of SD operations, set SPCR to spi_save:

Code: Select all

 Serial.println(F("Initializing SD card..."));
  if (!SD.begin(5)) {
 Serial.println(F("failed!"));
   return;
  }
  Serial.println(F("OK!"));
  spi_save = SPCR;
  
  SPCR = 0;     //do this before we start a bunch of tft operations.
  setTime(0,0,0,1,1,1970); //Enter Date at Set Up
  tft.setRotation(3);
  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  tft.println(F("Bilge Monitor on "));
When you get around to adding some SD operations, you'll have to do the same sort of thing:

Code: Select all

  SPCR = 0;
  tft.println(F("Some message "));
  < more tft stuff >

  SPCR = spi_save;
  < do something with the SD card here >
  . . . etc . . .

  SPCR = 0;
  < do something with the tft here >
  . . . etc . . 

Also, you should be passing the tft driver chip identifier to tft.begin. I had to add that before your code would work on my screen.

Code: Select all

void setup() {
  Serial.begin(9600);
  pinMode (10,OUTPUT);
 uint16_t identifier = tft.readID();
  tft.reset();
  tft.begin(identifier);   // pass tft chip identifier as argument

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”