[SOLVED] Getting the ST7735 to work with Spark

I’m starting a new thread and hopefully (if we can resolve this) it will be helpful for others.

I bought a 1.8’’ TFT display on ebay: http://www.ebay.com/itm/1-8-Serial-128X160-SPI-TFT-LCD-Module-Display-Screen-PCB-Adapter-w-SD-Socket-/200764741074?pt=LH_DefaultDomain_0&hash=item2ebe82d5d2

This display uses SPI (and not I2C despite the confusing labels on the board)

After working on some issues, I’m pretty sure of my wiring which is as follows:

  • display SDK -> A3 Spark (it’s confusing to have SDK, SCK, M_CLK… but
    anyway it’s all Clocks)
  • display SDA (which is in fact MOSI, because
    it’s SPI not I2C) -> A5 Spark (MOSI Pin for SPI)
  • display CS (Chip
    Select) -> A2 Spark (SS Pin for SPI)
  • display A0 (which is the D/C Pin for choosing Data or Command) -> D6 Spark (avoiding D0 or D1 in case I need them for something else)
  • display RST -> D2 Spark (also avoiding D0 or D1, can put it anywhere and managed through code)
  • display VCC -> 3V3) Spark (the TFT has a jumper that can be shorter to use 3V3 instead of 5V, I soldered the little jumper in the back)
  • display LED+ -> 3V3 Spark
  • display LED- and GND -> GND

I have used the ported library from @peekay123 that he posted here: https://github.com/pkourany/Adafruit_ST7735_mfGFX

compiled the thing (I used the Spark Dev for the first time, pretty cool).

All I can get right now is a lighted up TFT and nothing else… The code runs fine, I can see some output using the serial connection (on USB) and can access the spark just fine, but I get no output.

I cannot tell if this is a ST7735R or ST7735B by the way…

Here is the code I use:

#define cs   A2
#define dc   D6
#define rst   D2 // instead of 0
#define v    4

#include "Adafruit_GFX.h"    // Core graphics library
#include "Adafruit_ST7735.h" // Hardware-specific library
#include "glcdfont.h"

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); // hardware spi

void setup() {

Spark.function("version", version);

Serial.begin(9600);
Serial.println("TFT test!"); 
Serial.println("Version: ");
Serial.print(v);

 tft.initR(INITR_BLACKTAB); //for the ST7735R, otherwise would be initB for the B version

 tft.fillScreen(ST7735_BLACK);

tft.setCursor(0, 0);
tft.setTextColor(ST7735_WHITE);
tft.setTextWrap(true);
tft.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla");

tft.drawLine(0, 0, tft.width()-1, tft.height()-1, ST7735_YELLOW);
tft.drawLine(tft.width()-1, 0, 0, tft.height()-1, ST7735_YELLOW);

tft.drawPixel(0, tft.height()/2, ST7735_GREEN);

}

void loop() {
      Serial.print("Going Black ");
      tft.fillScreen(ST7735_BLACK);
      delay(1000);
      Serial.print("Going White ");
      tft.fillScreen(ST7735_WHITE);
      delay(1000);
}

int version(String s) {
  return v;
}

The first thing for me would be to know if the display actually works… but not sure if there is anyway for me to do that. How can I track if commands are actually sent? I can I debug this thing?

Thanks for the help.

EDIT: Corrected the code to reflect the correct wiring.

1 Like

@apassemard, it may be a good idea to power the display from 5v instead of the 3.3v due to current requirements.

Also, your text says RST -> D2 but the code show rst -> D5! To debug, you would need a logic analyzer on the SPI line. You should perhaps start with the demo code in the repo, making sure you set the correct control pins in the code. :smile:

3 Likes

ok, my bad, I was trying to recap cleanly… and good catch. my RST was not wired where the code was pointing to. This is fixed:

#define cs   A2
#define dc   D6
#define rst  D2 // instead of 0

I will fix the initial post because I’d like the thread to be clean.

I unsoldered the J1 jumper and connected the VCC pin to the VIN of the spark to work on 5V.

Recompiled and pushed. Same result unfortunately.

The code I use is the one from the repo, I just added some serial output and a version function that allow me to check the new code is actually running on the board.

@apassemard, defining rst as zero in the demo indicates that the reset line is not used. I recommend disconnecting the rst line altogether and setting the value to zero in the code, as original.

1 Like

Just to throw in my unsolicited BUT :wink:

But since D0 equals to 0 this might become confusing if anybody actually wants D0 as RST pin - or any other pin where 0 should mark a dummy parameter.
Wouldn’t it be clearer if unused pins were denoted by use of -1 or 0xFF instead?

1 Like

@ScruffR, good point. The original library was designed that way and uses a uint8_t to define the rst variable. So I will most likely change all pin defs to int8_t and make use -1 as the “no pin” definition for rst.

Nonetheless, for @apassemard’s testing, the existing code will work. The most important thing is to disconnect the RST pin to do the testing. :smile:

UPDATE: I have updated the github repo code to use -1 (255) in order to define rst as not being used. I updated the demo code as well.

3 Likes

OK… I did remove the wiring on the RST pin and changed the code to 0. Compiled. Didn’t do anything. Then I removed my “version” function, and some of the Serial.print lines to clean the code a bit and make more compact. Compiled. and Voila! I haven’t tried but I doubt it’s related to my cleanup, but more about the reboot or something but anyhow it is working!!

Nw you have to explain something to me… From what I read in various places I had found that the TFT will initialize with a reset drop for 50ms. How can this happen if the rst pin is not connected? Also, why would connected the rst to another pin stop the TFT from initializing (which is what I assume is happening)?

Here is the exact code that is compiled now for reference:

#define cs   A2
#define dc   D6
#define rst  0

#include "Adafruit_GFX.h"    // Core graphics library
#include "Adafruit_ST7735.h" // Hardware-specific library
#include "glcdfont.h"

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); // hardware spi

void setup() {
    Serial.begin(9600);

    tft.initR(INITR_BLACKTAB); //for the ST7735R, otherwise would be initB for the B version

    tft.fillScreen(ST7735_BLACK);

    tft.setCursor(0, 0);
    tft.setTextColor(ST7735_WHITE);
    tft.setTextWrap(true);
    tft.print("peekay123 and ScruffR are Geniuses!!");

    tft.drawLine(0, 0, tft.width()-1, tft.height()-1, ST7735_YELLOW);
    tft.drawLine(tft.width()-1, 0, 0, tft.height()-1, ST7735_YELLOW);

    tft.drawPixel(0, tft.height()/2, ST7735_GREEN);

}

void loop() {
}

A huge shout out to @peekay123 and @ScruffR who seem to be on every thread bout TFT that I could find! I was ready to through this TFT out the window honestly…

3 Likes

Good to hear you’ve got it working :+1:

As for your questions:
The thing of how to reset without the pin - Do you really need to reset the TFT independent of the Core?
Not satisfying, but … :stuck_out_tongue_winking_eye: … a lot of folk (including me) rather reset the TFT along with the Core, and so there is no need to sacrifice a precious pin.
Or under which circumstances would you reset the TFT?

The other thing about the wrong pin might have to do with what’s known as the “D pin start-up glitch” on the Core.
If you don’t set the pinMode() of any of the D pins, the pins will (counterintuitively) be driven LOW.
In your case by assigning a pin but connecting another, this might have held the TFT in reset.


But to confirm my theory, could you try to rewire the reset pin (maybe an A pin to get around the glitch) and also adapt the code accordingly?
I’d be curious if your problem comes back - I’d guess it won’t.

@apassemard, the ST7735 has its own power-on reset circuitry. However, I agree with @ScruffR regarding the start-up glitch as trying an analog pin instead. Another thing may be that the pin logic in the code is reversed. Without a display unit, I can’t test that for sure. I tend not to use RST lines on displays simply it requires an extra pin.

ok, this is very frustrating. I tried your new code (with the -1 on the RST) but it turned the screen back to white with nothing.

I reverted to the old code and it worked again (after I unplugged the spark and replugged it for some reason)

Then I decided to add a temperature sensor. Went on to add my code for it (it’s a DHT_22) and compiled the new code. The TFT went white again, but the code was running as I could ready the temp through the serial interface (on USB). So I figure I had done something wrong. Now I’m trying to revert to working code, basically copy/paste the code I had before removing everything about the DHT, but to no avail.

It really feels like the TFT will not initialize correctly. Is there a way to trigger the reset or something. I’m not sure what’s going wrong here…

This can be explained easily.
Whenever the TFT gets stuck for some obscure reason (I had an issue with inserting an SD card on a TFT/SD combo board once - cured with a capacitor) reseting the Core doesn’t help, since the TFT stays powered and hence will keep hanging - power-cycling usually helps there.
For such a reason you could use the reset pin. But things like this should not happen anyway, so the RST might be useful for development, but then you could also add a TFT-reset button ;-).
But if you reset the TFT the Core should get informed too, to do some sort of re-init.

More obscure is why @peekay123 's reworked lib gives you headaches.
Have you tried a power cycle with his lib?
Have you tried his samples, to exclude your own code to be the foe?

@ScruffR, I agree. I never use RST on any displays. Since I don’t have one of these displays, it is hard for me to debug. Do you have an Arduino to test with? I would NOT connect the RST line. There is NO pull-up on the RST line so I would add connect a 10K resistor to 3.3v to disable it.

I will revisit the Adafruit code and compare it with the code provided on the unit’s eBay page.

This is rather awkward - what on earth …
If there is no pull resistor on the board you’re bound to get headaches by leaving it floating.
I’d also go with @peekay123 's advice to add one.

I tell you guys… This thing has been really frustrating for something that does look straightforward…

Here is what I will try tonight:
-Put a 10K Resistor on the RST to 3v3 to pull it up
-Retry the Lib from scratch (which I think i did several times but will check again)
-I will unplug everything and re-wire and retry…

Unfortunately I don’t have an arduino handy, i’ve got almost every other board you can think of but not an arduino. I was thinking of just buying one and think I will… I also ordered 2 other TFT form ebay that are a bit different for $5 each, in case there is an issue with mine. I’ll update you tonight.

2 Likes

no no and no… I rewired, recompiled, shorten the wires… it will not work. BUT, one time I got the text to display for half a second after a power cycle and the screen went white again. I haven’t been able to reproduce it though. I do have my 10K resistor between RST and 3V3. I removed any other components and kept the code to the sample provided by peekay123.

I’m pretty sure it’s reset or initialization problem. It’s unbelievable…

How about this as a test:

  • Add a delay in setup() of say 10 seconds so you have time to work.

  • Now when the core is in this delay, take a jumper and bring the display’s reset pin low (to ground) for one second.

  • Now wait for the rest of the program run and see if you get anything on the display.

The LCD controller data sheet on page 66 says it needs a 10ms reset pulse if the power is not applied just right (there are two VDD pins that need to be ordered).

You could also try a big-ish electrolytic capacitor and a 0.1uF ceramic cap across the LCD power and ground.

You could also try adding an electrolytic cap to the reset line so it held low while power is coming up.

Hang in there! We’ll figure it out!

2 Likes

Hello @bko, thanks for jumping in. I need Prozac! :cry:

here is what I have done. I turn the D7 LED on at the beginning of the setup and turn it off after 10sec so I know when I am in that “wait” phase.

While in there, I plug the RST pin of the TFT to the GND for a second or two… Then put the 10K resistor back in place between the RST and 3V3 to have a pull-up on it.

Then I see my D7 go off… and… nothing. The TFT stays lit up white.

Tried a 0.1uF ceramic cap (104) on the LCD power and GND but didn’t do much.

As I was trying all this it did once display the text for 0.5sec and turned back white. Raging!!

We are feeling with you :weary:

With @peekay123 and @bko on board you’ve got the best trying to assist.

It IS puzzling :confounded:


As for the pull-up, you can leave it in place while pulling the pin low. That’s the whole point of pull resistors - to provide a defined state while there is no other signal, but not to (or very little) interfere with other dedicated signals.

Not to go against @peekay123 's advice to NOT connect RST to the Core, but since we are somehow groping in the dark and can’t test it without the board, you could again attach the RST to an A pin, but this time without “telling” the library (leave the pull-up in place).
This way you could try several combinations and timings for the RST signal against your TFT code.
As Paul pointed out, the RST logic might well be inverted.
If you whip up a test code where you can set the RST procedure and timing via a Spark.function or Serial, you might be able to test a lot of combos without having to reflash permanently.

Sorry for not being more of a help here :disappointed:

1 Like

I have no way of testing this, but try this code

I’ve ignored my own advice and purposely chosen D7 as reset pin, to have some visual feedback of what’s going on on the reset line.

This buils on the Web IDE (which uses the ST7735 lib version that uses 0 as NO_RST_PIN value)

// This #include statement was automatically added by the Spark IDE.
#include "Adafruit_ST7735/Adafruit_ST7735.h"


#define cs   A2
#define dc   D6
#define rst  D7


//#include "Adafruit_GFX.h"    // Core graphics library
//#include "Adafruit_ST7735.h" // Hardware-specific library
//#include "glcdfont.h"


Adafruit_ST7735 tft(cs, dc, 0); // hardware SPI / no RST

unsigned long ms;
bool retry = true;

int resetLevel = 0xAAAA;  // let pull resistor do its job
uint resetTime = 50;

void setup() 
{
    pinMode(rst, INPUT); // ensure to have high impedance 

    Serial.begin(115200);
    ms = millis();
    
    
    Spark.function("SetTFT", setTFT);
    
    while(!Serial.available() && (millis() - ms) < 5000)
        SPARK_WLAN_Loop();
}

void loop() 
{
    if(retry)
    {
        doTFT();
        retry = false;
    }
}

void doTFT()
{
    if (resetLevel == LOW || resetLevel == HIGH)
    {
        digitalWrite(rst, !resetLevel);
        delay(resetTime);
        digitalWrite(rst, resetLevel);
        delay(resetTime);
        digitalWrite(rst, !resetLevel);
    }
    
    tft.initR(INITR_BLACKTAB); //for the ST7735R, otherwise would be initB for the B version

    tft.fillScreen(ST7735_BLACK);

    tft.setCursor(0, 0);
    tft.setTextColor(ST7735_WHITE);
    tft.setTextWrap(true);
    tft.print("Paul and Brian are the real Geniuses!!");
    tft.setCursor(3, 0);
    tft.print(millis());

    tft.drawLine(0, 0, tft.width()-1, tft.height()-1, ST7735_YELLOW);
    tft.drawLine(tft.width()-1, 0, 0, tft.height()-1, ST7735_YELLOW);

    tft.drawPixel(0, tft.height()/2, ST7735_GREEN);
}


int setTFT(String cmd)
{
    int result = 0xAA;
    int x = cmd.toInt();
    
    if(x > 0)
    {
        result = 
        resetTime = x;
    }
    else if (cmd == "LOW")
    {
        resetLevel = LOW;
        pinMode(rst, OUTPUT);
        digitalWrite(rst, !resetLevel);
        result = 0;
    }
    else if (cmd == "HIGH")
    {
        resetLevel = HIGH;
        pinMode(rst, OUTPUT);
        digitalWrite(rst, !resetLevel);
        result = -1;
    }
    else
    {
        pinMode(rst, INPUT);
        result =
        resetLevel = 0xAAAA;
    }
    
    retry = true;
    return result;
}

BTW: Are you running the TFT on 3V3 or on 5V now?

@ScruffR and @apassemard, please get the latest code from the repo as I found the compiler was not producing the results I expected for the reset pin logic. I fixed that with a #define NO_RST_PIN for the correct pin value. So to NOT use a RST pin, you make the pin value NO_RST_PIN. :smile:

@ScruffR, earlier in the topic I asked @apassemard to power the board from the Vin pin, having some concerns over the amount of power draw on the 3.3v pin. There is an onboard 3.3v regulator that he set the jumper for. I do, however, notice that he is powering the LEDs from the 3.3v line.

1 Like