errors with readPixel for HX8357 TFT (Adafruit 3.5") [solved]

I couldn’t find “readPixel” code on-line for the HX8357D controller, so I wrote the code below. It is intended to read the color code of a pixel on the Adafruit 3.5" TFT.

In the uppermost code window:

With “red” in the code (btwn the *****), the red, dark green, and yellow pixel color codes are correct, but magenta and grey are wrong (equal to zero).

Without “red” in the code, the magenta, dark green, and yellow pixels are correct, but grey is still 0x0.

In the lower code window, magenta, yellow, dark green, and grey are all correct, regardless whether “red” is in the code or out.

Same results with 1.6.5-r5 and 1.0.5. Windows 7 64-bit. Nano w/ 328

HX8357D controller datasheet Memory read command is on page 149 of 254.

HX8357 Library My “read” code is based on their readcommand8 function (near bottom of the .cpp)

I would appreciate some help figuring this out.

This works, sometimes:

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"

const byte TFT_DC = 9;
const byte TFT_CS = 10;
const byte TFT_CLK = 13;

// RGB565 colors
const unsigned int GREY = 0xDF1C; // 1101111100011100
const unsigned int DKGREEN = 0x1BE0; // 0001101111100000

Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);

void setup() {
  Serial.begin(115200);
  Serial.println("HX8357D Test"); 
  Serial.println();

  tft.begin(HX8357D);
  tft.fillScreen(HX8357_BLACK);
  
  /****************************************
  TEST by deleting this code
  tft.drawPixel(15,15,HX8357_RED);  
  readPixA(15,15);
  Serial.println(F("Red    : 1111100000000000")); // <- should be this
  Serial.println();
  ******************************************/
  

  tft.drawPixel(10,10,HX8357_MAGENTA);
  readPixA(10,10);
  Serial.println(F("Magenta: 1111100000011111")); // <- should be this
  Serial.println();

  tft.drawPixel(5,5,HX8357_YELLOW);
  tft.drawPixel(7,3,GREY);
  tft.drawPixel(10,10,DKGREEN); // change 10,10 to dark green

  readPixA(10,10);
  Serial.println(F("DkGreen: 0001101111100000"));
  Serial.println();
  
  readPixA(5,5);
  Serial.println(F("Yellow:1111111111100000"));
  Serial.println();
  
  readPixA(7,3);
  Serial.println(F("Grey:  1101111100011100"));
  Serial.println();

}

void readPixA(int x, int y) {

  tft.setAddrWindow(x,y,x,y);

  Serial.print(x);
  Serial.print(" ");
  Serial.print(y);
  Serial.print("  0b");

  digitalWrite(TFT_DC, LOW);
  digitalWrite(TFT_CLK, LOW);
  digitalWrite(TFT_CS, LOW);
  tft.spiwrite(0x2E); // memory read command

  digitalWrite(TFT_DC, HIGH);

  uint16_t r = 0;
  r = tft.spiread(); // discard dummy read

  r = tft.spiread() >> 3; // red: use 5 highest bits (discard three LSB)
  r = (r << 6) | tft.spiread() >> 2; // green: use 6 highest bits (discard two LSB)
  r = (r << 5) | tft.spiread() >> 3; // blue: use 5 highest bits (discard three LSB)

  digitalWrite(TFT_DC, HIGH);
  
  prntBIN16(r);

}

// print binary with leading zero padding
void prntBIN16(uint16_t numToPrnt) {

  for (unsigned long mask = 0x8000; mask; mask >>= 1) {
    Serial.print(mask&numToPrnt?'1':'0');
  }
  Serial.println();

}

void loop() {
}

This works, apparently all the time:

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"

const byte TFT_DC = 9;
const byte TFT_CS = 10;
const byte TFT_CLK = 13;

const unsigned int GREY = 0xDF1C;
const unsigned int LTRED = 0xFE79;
const unsigned int DKGREEN = 0x1BE0;

Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);

void setup() {
  Serial.begin(115200);
  Serial.println("HX8357D Test"); 

  tft.begin(HX8357D);
  tft.fillScreen(HX8357_BLACK);

  Serial.println();

  Serial.print("RED:   ");
  tft.drawPixel(15,15,HX8357_RED);
  readPixB();
  Serial.println("should be: 1111100000000000");
  Serial.println();

  Serial.print("Magenta:   ");
  tft.drawPixel(10,10,HX8357_MAGENTA);
  readPixB();
  Serial.println("should be: 1111100000011111");
  Serial.println();

  Serial.print("Yellow:    ");
  tft.drawPixel(5,5,HX8357_YELLOW);
  readPixB();
  Serial.println("should be: 1111111111100000");
  Serial.println();
  
  Serial.print("Grey:      ");
  tft.drawPixel(7,3,GREY);
  readPixB();
  Serial.println("should be: 1101111100011100");
  Serial.println();

  Serial.print("DkGreen:   ");
  tft.drawPixel(10,10,DKGREEN);
  readPixB();
  Serial.println("should be: 0001101111100000");
  Serial.println();
  Serial.println();

  readPixA(10,10);
  Serial.println("DkGreen: 0001101111100000");

  readPixA(5,5);
  Serial.println("Yellow:1111111111100000");

  readPixA(7,3);
  Serial.println("Grey:  1101111100011100");

}

void readPixB() {

  digitalWrite(TFT_DC, LOW);
  digitalWrite(TFT_CLK, LOW);
  digitalWrite(TFT_CS, LOW);
  tft.spiwrite(0x2E); // memory read

  digitalWrite(TFT_DC, HIGH);

  uint16_t r = 0;
  r = tft.spiread(); // discard dummy read

  r = tft.spiread() >> 3; // red: use 5 highest bits (discard three LSB)
  r = (r << 6) | tft.spiread() >> 2; // green: use 6 highest bits (discard two LSB)
  r = (r << 5) | tft.spiread() >> 3; // blue: use 5 highest bits (discard three LSB)

  prntBIN16(r);

  digitalWrite(TFT_DC, HIGH);
}

void readPixA(int x, int y) {

  tft.setAddrWindow(x,y,x,y);

  Serial.print(x);
  Serial.print(" ");
  Serial.print(y);
  Serial.print("  0b");

  digitalWrite(TFT_DC, LOW);
  digitalWrite(TFT_CLK, LOW);
  digitalWrite(TFT_CS, LOW);
  tft.spiwrite(0x2E); // memory read

  digitalWrite(TFT_DC, HIGH);

  uint16_t r = 0;
  r = tft.spiread(); // discard dummy read

  r = tft.spiread() >> 3; // red: use 5 highest bits (discard three LSB)
  r = (r << 6) | tft.spiread() >> 2; // green: use 6 highest bits (discard two LSB)
  r = (r << 5) | tft.spiread() >> 3; // blue: use 5 highest bits (discard three LSB)

  digitalWrite(TFT_DC, HIGH);
  
  prntBIN16(r);

}



void loop() {

}

// print binary with leading zero padding
void prntBIN16(uint16_t numToPrnt) {

  for (unsigned long mask = 0x8000; mask; mask >>= 1) {
    Serial.print(mask&numToPrnt?'1':'0');
  }
  Serial.println();

}

Results from code in lower window (everything is hunky dory):


Only results without red shown…

HX8357D Test

Magenta:   1111100000011111
should be: 1111100000011111

Yellow:    1111111111100000
should be: 1111111111100000

Grey:      1101111100011100
should be: 1101111100011100

DkGreen:   0001101111100000
should be: 0001101111100000


10 10  0b0001101111100000
DkGreen: 0001101111100000

5 5  0b1111111111100000
Yellow:1111111111100000

7 3  0b1101111100011100
Grey:  1101111100011100

Results from code in upper window:


HX8357D Test

15 15  0b1111100000000000  <-- with Red 
Red    : 1111100000000000

10 10  0b0000000000000000  <-- Magenta FAILS
Magenta: 1111100000011111

10 10  0b0001101111100000  <-- DkGreen is ok
DkGreen: 0001101111100000

5 5  0b1111111111100000    <-- Yellow is ok
Yellow:1111111111100000

7 3  0b0000000000000000    <-- Grey FAILS
Grey:  1101111100011100

HX8357D Test

10 10  0b1111100000011111  <- without Red, Magenta is now ok
Magenta: 1111100000011111

10 10  0b0001101111100000  <-- DkGreen is ok
DkGreen: 0001101111100000

5 5  0b1111111111100000    <-- Yellow is ok
Yellow:1111111111100000

7 3  0b0000000000000000    <- Grey still FAILS
Grey:  1101111100011100

Never mind. I found the error.

  digitalWrite(TFT_DC, HIGH);
  
  prntBIN16(r);

should have been

  digitalWrite(TFT_CS, HIGH);
  
  prntBIN16(r);

Yay!

Corrected code:

// read the RGB565 color code of a pixel
// on the Adafruit 3.5" TFT with HX8357D controller

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"

const byte TFT_DC = 9;
const byte TFT_CS = 10;
const byte TFT_CLK = 13;

/*  Used for testing:
 *   
 *  Magenta: 11111 000000 11111
 *  DkGreen: 00011 011111 00000
 *  Yellow:  11111 111111 00000
 *  Grey:    11011 111000 11100
 *  Red:     11111 000000 00000
 *  LtRed:   11111 110011 11001
 *  
 *  const unsigned int GREY = 0xDF1C;
 *  const unsigned int LTRED = 0xFE79;
 *  const unsigned int DKGREEN = 0x1BE0;
 */

Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);

void setup() {
  tft.begin(HX8357D);
  tft.fillScreen(HX8357_RED);
  Serial.begin(115200);
  
  prntBIN16(readPixA(200,200));
}

uint16_t readPixA(int x, int y) {

  tft.setAddrWindow(x,y,x,y);

  digitalWrite(TFT_DC, LOW);
  digitalWrite(TFT_CLK, LOW);
  digitalWrite(TFT_CS, LOW);
  tft.spiwrite(0x2E); // memory read command

  digitalWrite(TFT_DC, HIGH);

  uint16_t r = 0;
  r = tft.spiread(); // discard dummy read
  r = tft.spiread() >> 3; // red: use 5 highest bits (discard three LSB)
  r = (r << 6) | tft.spiread() >> 2; // green: use 6 highest bits (discard two LSB)
  r = (r << 5) | tft.spiread() >> 3; // blue: use 5 highest bits (discard three LSB)

  digitalWrite(TFT_CS, HIGH);

  return r;
}

// print binary with leading zero padding
void prntBIN16(uint16_t numToPrnt) {

  for (unsigned long mask = 0x8000; mask; mask >>= 1) {
    Serial.print(mask&numToPrnt?'1':'0');
  }
  Serial.println();

}

void loop() {
}