Uno + Waveshare 2.8 tft no digital output

I've made a pretty cool graphical controller for my reflow oven with a Uno and a Waveshare 2.8 inch tft which are working a treat, however I've just hit a brick wall. Try as I might I cannot get an output on D13 (or get the led to light).

The thermocouple is on A5 and works perfectly, am I correct in thinking that D10 - D13 aren't used by the tft shield so should be free for use?

If I upload the blink sketch the led flashes so the Uno is ok.

I've tried setting the pinMode and output high at the very start in setup with a 3 second delay before tft.begin however the led just flickers a few times while the Arduino resets, am I missing something? I believe this is an old version of the Waveshare tft.

Please insert your code and show the schematic

There is no schematic as such as its still at stage of the board + shield powered by the usb lead and a 10K pot supplying 0-5V to the analog input. The digital output will operate a solid-state relay once in service.

Here is the code, it's very much work in progress just to get all the elements tested, after it will be completely re-written, in fact at the moment the code is uglier than I am!

// Reflow oven controller using 2.8" waveshare touch display
//improved version with target programs

#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

#include <SPI.h>          // f.k. for Arduino-1.5.2
#include "Adafruit_GFX.h"// Hardware-specific library
#include <HX8347D_kbv.h>
HX8347D_kbv tft;

#include <XPT2046_Touchscreen.h>
#define XPT_CS  4
#define XPT_IRQ 255       //use 3 if you fix interrupts in library source code


XPT2046_Touchscreen ts(XPT_CS, XPT_IRQ);


// 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

#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif

unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 100;           // interval at which to blink (milliseconds)

int ledPin = 13;// led - output pin


int ledState = LOW;             // ledState used to set the LED for debugging only
int counter = 0;

int temperature = 190;
int ramp = 15;
int target = 200;
int tempPin = A5;
int tempRaw = 0;
int graphTemp = 0;
int graphSeconds = 0;
int lastTemperature = 0;
int lastGraphSeconds = 0;
int lastGraphTemp = 0;
int barSecond = 0;
int secondsCount = 0;
int segmentTime = 0;
int rampTime = 0;
int rampCount = 50;
int soakTime = 0;
int soakCount = 150;
int rampTarget = 0;
int soakTarget = 0;
int flowRamp = 0;
int flowRampTime = 0;
int flowTime = 0;
int coolTime = 0;
int coolTemp = 0;

int temperatureReal = 0;
int graphStart = 0;
int graphTimeStart = 0;





void setup() {



  //  pinMode(ledPin, OUTPUT);      //
  //  digitalWrite(ledPin, HIGH);   // for debugging digital output
  //  delay (3000);                 //


  tft.begin();            //initialize tft
  ts.begin();             //.kbv XPT2046_Touchscreen needs to start
  tft.setRotation(2);     //LANDSCAPE

  pinMode(ledPin, OUTPUT);

  setupLoop(); // draw background graphics


  //set flow  profile----------------------------------

  rampTarget = 150;  //degrees
  rampTime = 50;     //seconds
  soakTarget = 180;  //dgrees
  soakTime = 100;    //seconds
  flowRamp = 250;   //degrees
  flowRampTime = 20;    //seconds
  flowTime = 10;  //seconds
  coolTemp = 100; //degrees
  coolTime = 60; //seconds

  drawTargetGraph();  //draw the target graph

}


void loop() {//main operation loop
  //untimed code

  //no untimed code at present



  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    //timed code----------------------------------------------------------------------------------------

    tempRaw = analogRead(tempPin);  //anaolg input (0-5V from pot for testing)

    temperature = (tempRaw / 3);   // very rough int to temperature conversion


    secondsCount ++; // increment seconds


    tft.fillRect(80, 22, 60, 25, BLACK);//----------- this is a box that deletes previously writen temperature on screen

    //   tft.fillRect(110, 290, 60, 25, BLACK);//----------count down



    tft.drawLine(barSecond, 260, barSecond, 270, YELLOW); // time bar showing cycle progress


    barSecond ++;// increment seconds for time bar


  }


  //--------------- temperature graph --------------------

  tempRaw = analogRead(tempPin);
  graphTempConvert();


  tft.drawLine(barSecond, graphTemp, barSecond, graphTemp + 2, YELLOW); // temperature grapg


  //---ramp segment---------------------------------------------------------

  if (barSecond == 1) {
    tft.setTextColor(WHITE);//------------ display the segmnent of the cycle on the screen (ramp)
    tft.setCursor(5, 290);
    tft.setTextSize(3);
    tft.println("Ramp");

    tft.setTextColor(WHITE);//------------ display the time of the ramp segment
    tft.setCursor(185, 290);
    tft.setTextSize(3);
    tft.println(rampTime);

    tft.setTextColor(WHITE);//------------ display target temperature of the  ramp segment
    tft.setCursor(168, 22);
    tft.setTextSize(3);
    tft.println(rampTarget);


  }

  if (barSecond < rampTime) {


    tft.setTextColor(WHITE);//------------ time
    tft.setCursor(185, 290);
    tft.setTextSize(3);
    tft.println(rampTime);


    tft.fillRect(110, 290, 60, 25, BLACK);
    tft.setTextColor(WHITE);//------------ elapsed time displayed on screen
    tft.setCursor(110, 290);
    tft.setTextSize(3);
    tft.println(rampCount - barSecond);


    if (temperature < rampTarget ) {
      tft.fillRect(5, 20, 50, 20, RED); //heating indicator colour to red
      // digitalWrite(ledPin, HIGH);    //turn heating relay on
    }

    if (temperature > rampTarget ) {
      tft.fillRect(5, 20, 50, 20, BLACK); //heating indicator clout to black
      // digitalWrite(ledPin, LOW);       //turn heater relay off
    }


    // tft.fillRect(80, 22, 60, 25, BLACK);//----------- display temperature on screen
    tft.setTextColor(WHITE);
    tft.setCursor(80, 22);
    tft.setTextSize(3);
    tft.println(temperature);


  }


  //---soak segment----------------------------------------------------------------


  if (barSecond == rampTime) {

    tft.fillRect(5, 290, 288, 27, BLACK);
    tft.setTextColor(WHITE);//------------ display segment mode
    tft.setCursor(5, 285);
    tft.setTextSize(3);
    tft.println("Soak");

    tft.setTextColor(WHITE);//------------ display soak time
    tft.setCursor(182, 285);
    tft.setTextSize(3);
    tft.println(soakTime);

    tft.fillRect(168, 22, 60, 27, BLACK);
    tft.setTextColor(WHITE);//------------ display target temperature
    tft.setCursor(168, 22);
    tft.setTextSize(3);
    tft.println(soakTarget);




  }


  if (barSecond > rampTime && barSecond < rampTime + soakTime) {

    if (temperature < soakTarget ) {

      tft.fillRect(5, 20, 50, 20, RED); //heating indicator colour to red
      // digitalWrite(ledPin, HIGH);    //turn on heater relay
    }
    if (temperature > soakTarget ) {

      tft.fillRect(5, 20, 50, 20, BLACK); //heating indicator soak
      // digitalWrite(ledPin, LOW);    //turn on heater relay
    }



    //   tft.fillRect(80, 22, 60, 25, BLACK);//----------- display current temperature on screen
    tft.setTextColor(WHITE);
    tft.setCursor(80, 22);
    tft.setTextSize(3);
    tft.println(temperature);


    tft.fillRect(110, 290, 60, 25, BLACK);//----------soak time count down display on screen
    //  tft.fillRect(110, 290, 60, 25, BLACK);
    tft.setTextColor(WHITE);//------------ display elapsed time on screen
    tft.setCursor(110, 290);
    tft.setTextSize(3);
    tft.println(soakTime - (barSecond - rampTime));


  }

  //---flow segment------------------------------------------------------------------------


  if (barSecond == rampTime + soakTime) {

    tft.fillRect(5, 288, 300, 27, BLACK);

    tft.setTextColor(WHITE);//------------ display flow mode on screen
    tft.setCursor(5, 290);
    tft.setTextSize(3);
    tft.println("Flow");


    tft.setTextColor(WHITE);//------------ display flow time on screen
    tft.setCursor(185, 290);
    tft.setTextSize(3);
    tft.println(flowRampTime + flowTime);

    tft.fillRect(168, 22, 60, 27, BLACK);
    tft.setTextColor(WHITE);//------------ display target
    tft.setCursor(168, 22);
    tft.setTextSize(3);
    tft.println(flowRamp);


  }



  if (barSecond > rampTime + soakTime && barSecond < rampTime + soakTime + flowRampTime + flowTime ) {

    if (temperature < flowRamp)tft.fillRect(5, 20, 50, 20, RED); //heating indicator flow
    if (temperature > flowRamp)tft.fillRect(5, 20, 50, 20, BLACK); //heating indicator flow


    tft.fillRect(80, 22, 60, 25, BLACK);//----------- display temp
    tft.setTextColor(WHITE);
    tft.setCursor(80, 22);
    tft.setTextSize(3);
    tft.println(temperature);

    tft.fillRect(110, 290, 60, 25, BLACK);//----------count down
    //  tft.fillRect(110, 290, 60, 25, BLUE);
    tft.setTextColor(WHITE);//------------ elapt time
    tft.setCursor(110, 290);
    tft.setTextSize(3);
    tft.println(flowRampTime + flowTime - (barSecond - rampTime - soakTime));

  }

  //---cool segment---------------------------------------------------------------------------------
  if (barSecond == rampTime + soakTime + flowRampTime + flowTime) {

    tft.fillRect(5, 285, 295, 27, BLACK);

    tft.setTextColor(WHITE);//------------ display mode
    tft.setCursor(5, 290);
    tft.setTextSize(3);
    tft.println("   Cooling");

    tft.fillRect(155, 3, 80, 40, BLACK);//-----------------------

  }

  if (barSecond > rampTime + soakTime + flowRampTime + flowTime) {


    tft.fillRect(5, 20, 50, 20, BLACK); //heating indicator cooling

    //  tft.fillRect(80, 22, 60, 25, BLACK);//----------- display temp
    tft.setTextColor(WHITE);
    tft.setCursor(80, 22);
    tft.setTextSize(3);
    tft.println(temperature);


  }



  if (secondsCount > rampTime + soakTime + flowRampTime + flowTime + coolTime) {


    tft.setTextColor(GREEN);//------------ time
    tft.setCursor(20, 150);
    tft.setTextSize(4);
    tft.println("Complete");





    while (1) { //cycle has ended, put program in a loop that just updates the temperature as the oven cools


      tempRaw = analogRead(tempPin);

      temperature = (tempRaw / 3);


      tft.fillRect(80, 22, 60, 25, BLACK);//----------- display temp
      tft.setTextColor(WHITE);
      tft.setCursor(80, 22);
      tft.setTextSize(3);
      tft.println(temperature);

      delay (250);



    }

  }





}


//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

void setupLoop() { // draw the background graphics on the screen




  tft.fillScreen(BLACK);
  tft.drawRect(0, 0, 240, 320, WHITE);//outline frame around screen


  tft.setTextColor(WHITE);//---------- display ramp
  tft.setCursor(5, 3);
  tft.setTextSize(2);
  tft.println("Heat");

  tft.setTextColor(WHITE);//----------- display temp
  tft.setCursor(80, 3);
  tft.setTextSize(2);
  tft.println("Temp");


  tft.setTextColor(WHITE);//------------ display target
  tft.setCursor(160, 3);
  tft.setTextSize(2);
  tft.println("Target");


  tft.drawRect(0, 50, 240, 200, WHITE); //graph frame


  int gratStart = 0;//---------- draw time graduations
  int gratSpace = 0;

  for (int i = 0; i < 6;  i++) {
    tft.drawLine(i + gratSpace, 240, i + gratSpace, 250, WHITE); // grat1
    gratSpace = (gratSpace + 40);
  }


  tft.drawLine(0, 83, 10, 83, WHITE); // vgrat1
  tft.drawLine(0, 116, 10, 116, WHITE); // vgrat2
  tft.drawLine(0, 149, 10, 149, WHITE); // vgrat3
  tft.drawLine(0, 182, 10, 182, WHITE); // vgrat4
  tft.drawLine(0, 215, 10, 215, WHITE); // vgrat5


}

//---------------------------------------------------

void graphTempConvert() {

  graphTemp = map(tempRaw, 0, 1023, 247, 50);


}

//-------------------------------------------------------

void drawTargetGraph() {

  //draw profile target graph-------------------

  graphTemp = map(rampTarget, 0, 350, 247, 50);
  tft.drawLine(0, 250, rampTime, graphTemp, GREEN); //  ramp

  graphStart = graphTemp;
  graphTimeStart = rampTime;
  graphTemp = map(soakTarget, 0, 350, 247, 50);
  tft.drawLine(graphTimeStart, graphStart, graphTimeStart + soakTime, graphTemp, GREEN); //  soak

  graphStart = graphTemp;
  graphTimeStart = rampTime + soakTime;
  graphTemp = map(flowRamp, 0, 350, 247, 50);
  tft.drawLine(graphTimeStart, graphStart, graphTimeStart + flowRampTime, graphTemp, GREEN); //  flow ramp

  graphStart = graphTemp;
  graphTimeStart = rampTime + soakTime + flowRampTime;
  graphTemp = map(flowRamp, 0, 350, 247, 50);
  tft.drawLine(graphTimeStart, graphStart, graphTimeStart + flowTime, graphTemp, GREEN); //  flow

  graphStart = graphTemp;
  graphTimeStart = rampTime + soakTime + flowRampTime;
  graphTemp = map(coolTemp, 0, 350, 247, 50);
  tft.drawLine(graphTimeStart + flowTime, graphStart, graphTimeStart + flowTime + coolTime, graphTemp, GREEN); //  cool


}

Yes, it looks like. But if you would provide a link to the display, it would be clear.
But obviously your touch uses XPT2046, which uses HW SPI.

#define PIN_SPI_SS    (10)
#define PIN_SPI_MOSI  (11)
#define PIN_SPI_MISO  (12)
#define PIN_SPI_SCK   (13)

Jean-Marc

I think that's the reason, this is on older waveshare tft, it looks like the newer type might have D10 - D13 free.

It looks like D0,1,2 and 3 might be free, I 'll see if I can get an out put on D2 or D3 (avoiding 0 an 1 as they are needed for programming).

2.8inch Touch LCD Shield for Arduino (waveshare.com)

Success!

Pin D2 working a treat, Thanks for your help.

  • Controlled via SPI, only a few Arduino pins are used