Teensy 4 with Adafruit 1,8" Color TFT LCD display with MicroSD Card Breakout

Status
Not open for further replies.

Erik_

Member
Hello,
sorry, but i posted a part of my problem also in Thread: Teensy 4.0 First Beta Test. But there are so many posts that i fear my post will go under and it is not in the right thread.

Maybe someone has a solution.

After installing Arduino IDE 1.8.9 and Teensyduino 1.47 beta 6 i connected Teensy 4 with Adafruit 1,8" Color TFT LCD display with MicroSD Card Breakout ( https://www.adafruit.com/product/358 ).
I am using following pins:
MISO - pin12
SCK - pin13
MOSI - pin11
TFT_CS - pin10
Card_CS - pin4
D/C - pin9
Reset - pin8
VCC - 3,3V
Gnd - Gnd
But i had no success in using library ST7735_t3 (in ...Arduino\hardware\teensy\avr\libraries)

in example spiffbitmap : (with SD Card) : Initializing SD Card - failure -> Screen is white ....
(without SD Card): Initializing SD Card - failure -> Screen is blach with message: Unable to access SD Card

Then i tried graphicstest: Text is ok, most graphics also, but in the end there were objects on the screen that were not right.
rotationtest: black screen

I cross checked 2 Displays with my Teensy 3.6 and they are ok.

I need both (TFT LCD display and Micro SD Card) on this board working with Teensy 4 (without changing much of the above mentioned wiring)
(so example spiffbitmap is the most important one what should run with Teensy 4)

Is the problem of Initialization failure of the SD Card because that pin 4 isn't a fast CS pin on Teensy 4 anymore? (Teensy 3.6 has 2 fast CS pins)

Thank you

best regards
Erik
 
@Erik_ - @KurtE

Erik - I have a ST7735_R from adafruit as well just not your model. I can read from the SD card not a problem with the latest Teensyduino 1.47 firmare:
Code:
Initializing SD card...OK!

Loading image 'parrot.bmp'
File size: 61496
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 128x160
However it hangs at this point for me but that's next.

First I would recommend make sure you have the latest Teensyduino firmware (1.47), there was a fix that Paul put in for the SD library. Second double check the wiring.

@KurtE. The sketch hangs when it tries to draw to the screen: tft.pushColor(tft.Color565(r,g,b)); . If I comment out that out it will dump the contents of the bmp file with out a problem. Its like something is going on with CS not being released or reset?
 
@mjs513

Hello,
in the moment it is only possible to download 1.46 (https://www.pjrc.com/teensy/td_146/TeensyduinoInstall.exe) (in 1.46 st7735_t3 is removed)
Yesterday i saw under Windows XP / 7 / 8 / 10 Installer: the link (https://www.pjrc.com/teensy/td_147/TeensyduinoInstall.exe)
So i changed the link and downloaded 1.47 and installed it.
I checked all wirings and they are connected as i wrote before.
But the same results. (I checked the example spiffbitmap with 2 Displays):

Initializing SD card...failed!


(with SD Card) : The TeensyMonitor shows: Initializing SD card...failed! The Display is white (only Backlight)


(without SD Card): The TeensyMonitor shows: Initializing SD card... (then a little pause and then: ) failed!
DisplayScreen is black with message: Unable to access SD Card

spiffbitmap runs very good with Teensy 3.6 and this Display and the same wiring .

best wishes
Erik










@Erik_ - @KurtE

Erik - I have a ST7735_R from adafruit as well just not your model. I can read from the SD card not a problem with the latest Teensyduino 1.47 firmare:
Code:
Initializing SD card...OK!

Loading image 'parrot.bmp'
File size: 61496
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 128x160
However it hangs at this point for me but that's next.

First I would recommend make sure you have the latest Teensyduino firmware (1.47), there was a fix that Paul put in for the SD library. Second double check the wiring.

@KurtE. The sketch hangs when it tries to draw to the screen: tft.pushColor(tft.Color565(r,g,b)); . If I comment out that out it will dump the contents of the bmp file with out a problem. Its like something is going on with CS not being released or reset?
 
@Erik_ - @KurtE

Did a little more testing. While I was able to read the header info (open your sermon to see the data after you load the sketch) I put the SD Card into an external card reader and re-ran the sketch.

I did get the image to display but tft.pushColor did not work I had to change that to tft.drawPixel(row, col, tft.Color565(….)). Then it displayed.

Bottom line there appears to be some sort of issue with using the SDCard on the display at the same time as display.
 
@mjs513, @Erik_

I understand some of the issues with the spittftbitmap here, but I really don't know how to fix the specific way this test app is written with the current code.

That is, with this code:
Code:
        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x+w-1, y+h-1);

        for (row=0; row<h; row++) { // For each scanline...

          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
            pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) { // Need seek?
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }

          for (col=0; col<w; col++) { // For each pixel...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }

            // Convert pixel from BMP to TFT format, push to display
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            tft.pushColor(tft.Color565(r,g,b));
          } // end pixel
        } // end scanline
        Serial.print("Loaded in ");
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      } // end goodBmp
First issue, disregard the SD Stuff:

tft.setADDRWindow does:
Code:
void ST7735_t3::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
	beginSPITransaction();
	setAddr(x0, y0, x1, y1);
	writecommand(ST7735_RAMWR); // write to RAM
	endSPITransaction();
}
So it enables a transaction, assert CS do the setADDR and set into RAMWRite mode and then it unasserts CS and ends the SPI transaction... Problem is, I believe that the when the CS is unasserted the display will not take the data sent to it by PushColor:
Code:
void ST7735_t3::pushColor(uint16_t color)
{
	beginSPITransaction();
	writedata16_last(color);
	endSPITransaction();
}
Which again does full transaction assert/deassert...

Which I don't think will work...

So not sure how to make it properly work in this environment. Could potentially change the APIS a little, for example have the SetADDRWindow not call the endSPITransaction.

Change the pushColor to not begin/end and rely on it still being asserted. Maybe add an optional secons parameter like bool last_pixel=false, which if true would call the endSPITransaction()...

But then you through the SD into the mix which if you are trying to use the one on the display, most likely be on the same SPI. So when you call off to the bmpFile functions, it is also going to output stuff on SPI buss (while the TFT still has it asserted) and both will be fighting to send/respond...

So how would I change this sketch?
Option 1) Punt and do easy(slow) way and use drawPixel and get rid of setADDRWindow and pushColor...
Option 2) build up an array of colors, maybe have an array big enough for one or two rows of pixels, and when you finish the one or two rows, use writeRect, to output all of them in one SPI write...
Option 3) Option 1 or Option 2, but turn on useFrameBuffer, so all of these writes go to memory and then use updateScreen at the end... (which is what I would do)

And more or less what my attempt at changing uncannyEyes is doing... Except currently trying to have them then update using DMA...
 
@KurtE

The simplest solution gives:
Code:
File size: 61496
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 128x160
[COLOR="#FF0000"]Loaded in 219 ms[/COLOR]
writeRect - messing something up - doesn't display correctly. This is what I did in the loop:
Code:
            // Convert pixel from BMP to TFT format, push to display
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            //tft.drawPixel(row, col, tft.Color565(r,g,b));
            bmpColors[col] = tft.Color565(r,g,b);
          } // end pixel
          tft.writeRect(row, 0, w, h, bmpColors);
        } // end scanline
 
@KurtE

The simplest solution gives:
Code:
File size: 61496
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 128x160
[COLOR="#FF0000"]Loaded in 219 ms[/COLOR]
writeRect - messing something up - doesn't display correctly. This is what I did in the loop:
Code:
            // Convert pixel from BMP to TFT format, push to display
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            //tft.drawPixel(row, col, tft.Color565(r,g,b));
            bmpColors[col] = tft.Color565(r,g,b);
          } // end pixel
          tft.writeRect(row, 0, w, h, bmpColors);
        } // end scanline

Probably the parameters are wrong to writeRect, I am guessing you need:
tft.writeRect(0, row, w, 1, bmpColors);
 
@KurtE

Yep. That was it:
Code:
[COLOR="#FF0000"]Loaded in 115 ms[/COLOR]

I think I am going to punt at this point. You of course can do more.

bmpColors is a uint16_t for colors.
 
pushColor , CS conflict

I got around this issue by loading the entire bitmap 128x128 ( 49206 bytes) into the ram on the teensy 4.0 from the SD card first then writing the whole screen . This needs the endTransmission to be commented out in the ST7735_t3.cpp void ST7735_t3::setAddrWindow function. then at the end of the write loop do a pushColor(0,1); to end the transmission.

Also found the image was mirrored and had to edit the rotation function not to set MADCTL_MX, using a green tab screen. the SD card read takes about 50ms and the screen update about 20ms.
 
@bobonion,
can you post your coding to make this wortk.I am testing the speed with which different microcontroller can display a bitmap image.I am new to Teensys.I got it to work on a Teensy 3.2, but not sure how to do the SD card to memory write and change the spitftbitrmap code to write the imnage from the memeory to the screen
 
Status
Not open for further replies.
Back
Top