Problem drawing image to screen using ILI9341_t3n Library

gazzer23

Member
Hi I am really quite stumped by this as when I first use the writeRect method it draws the image fine but subsequent attempts draws a dark rectangle with scrolling diagonal red lines.

The first attempt thta works calls the DisplayStatus method which in turn calls the Show_BTDiscovery method and it works fine.
Then later my main code calls Show_BTDiscovery directly and this is when it doesn't work.
The main code reads and parses data from serial3 which is connected to an ESP32. On boot the ESP32 does a BT discovery to try and find a known device to connect to and sends status notifications over the serial line.
The image byte arrays were created using http://www.rinkydinkelectronics.com/_t_doimageconverter565.php which works very well and each of the images can be displayed fine by the DisplayStatus method by not independently later on.
I am using a Teensy 4.1 with the Arduino IDE on the Teensy side and Espressif IDF on the ESP32 side.
Up to now I have had no problem with the graphics on the display and can plot lines and draw circles and rectangles etc with no problem.
I am using this driver as I have the display on the 2nd SPI interface as the normal can only work with the 1st SPI interface.
I thought maybe it worked because of something to do with the fill screen so i tried with a fill screen in each of the methods and it didn't work still.

Here is a link to a very short video clip showing the problem


On the top far right you can see briefly a red BT symbol before it gets overwritten by a black rectangle with scrolling lines.
Every time the same method call is made with true so should be displaying the same symbol all the time.

Another clip showing the graphics etc working fine on the display before I decided to add notifications so I could see what was going on with the Bluetooth.


I am obviously doing something stupid but i can't for the life of me work it out.

Actually I should mention it has an audio shield on it as well but I don't think it is related to that.

Code:
#define TFT_SCLK 27  // SCLK can also use pin 14
#define TFT_MOSI 26  // MOSI can also use pin 7
#define TFT_MISO 39  // MOSI can also use pin 7
#define TFT_CS   22  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC   40  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST  255  // RST can use any pin
#define SD_CS    10  // CS for SD card on audio board



void DisplaySelection::init()
{
  tft = new ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO);
  tft->begin();
  tft->setRotation(3);
  ts.begin(SPI1);
  DisplayStatus();
}



void DisplaySelection::Show_BTDiscovery(bool show)
{
   if (show)
   {
      tft->writeRect(300, 2, 17, 21, (uint16_t*)bluetooth2_sym);
   } else
   {
     tft->fillRect(300, 2, 17, 21, ILI9341_WHITE);
   }
}

void DisplaySelection::ShowDC_BTSym(bool show)
{
   if (show)
   {
      tft->writeRect(300, 2, 17, 21, (uint16_t*)bluetooth_sym);
   } else
   {
     tft->fillRect(300, 2, 17, 21, ILI9341_WHITE);
   }
}



void DisplaySelection::ShowApp_BTSym(bool show)
{
   if (show)
   {
      tft->writeRect(280, 2, 17, 21, (uint16_t*)bluetooth_sym);
   } else
   {
     tft->fillRect(280, 2, 17, 21, ILI9341_WHITE);
   }
}




void DisplaySelection::ShowApp_MuteSym(bool show)
{
   if (show)
   {
      tft->writeRect(260, 2, 18, 21, (uint16_t*)mute);
   } else
   {
     tft->fillRect(260, 2, 18, 21, ILI9341_WHITE);
   }
}


void DisplaySelection::DisplayStatus()
{
  tft->fillScreen(ILI9341_WHITE);
  Show_BTDiscovery(true);
  ShowApp_BTSym(true);
  ShowApp_MuteSym(true);
  tft->setTextColor(ILI9341_BLACK, ILI9341_WHITE);
  tft->setTextSize(2);
  tft->setCursor(2, 2);
  tft->printf("Vol %3.2f", voiceVolumeParam->Value());
}
 
Last edited:
Hard to test without the image files and how you have the image files defined. Nothing obvious strikes me.
 
Yes you are right, sorry about that. I ws hoping it was something someone had seen before and was a known problem.
Here they are, there is a lot of rubbish in there as still messing around and need to tidy it up.
I will knock up a cut down version for testing with just the notifications.
 

Attachments

  • bluetooth.c
    3.8 KB · Views: 18
  • bluetooth2.c
    3.8 KB · Views: 15
  • DisplaySelection.cpp
    11.3 KB · Views: 15
  • DisplaySelection.h
    1 KB · Views: 15
  • VoiceModVariant.ino
    14.4 KB · Views: 14
  • mute.c
    3.9 KB · Views: 17
Well cutting it down to a simple Test program and it works fine.
My guess is I must be accessing the TFT instance while it is already busy, interrupt or something.

If I draw something then access the TFT immediately for something else, can it effect the previous draw (say some DMA SPI transfer in progress can be aborted ?).
 
Last edited:
Or you may be having some memory trashing issue, like how much space is left for a stack?

Taking a look at one of your Bitmap files, I see:
C++:
// Generated by   : ImageConverter 565 Online
// Generated from : bluetooth2.jpg
// Time generated : Wed, 09 Oct 24 00:44:19 +0200  (Server timezone: CET)
// Image Size     : 17x21 pixels
// Memory usage   : 714 bytes


#if defined(__AVR__)
    #include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
    #define PROGMEM
#elif defined(__arm__)
    #define PROGMEM
#endif

const unsigned short bluetooth2_sym[357] PROGMEM={
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDF, 0xFFFF, 0xFFFF, 0xF7FF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE,   // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDE, 0xFFDD, 0xFFDE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0020 (32) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFD, 0xFFBA, 0xBC8E, 0xFFBC, 0xFFDD, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0030 (48) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDD, 0xFF99, 0xCC6B, 0xC48C, 0xFFBA, 0xFFDD, 0xFFFE, 0xFFDE,   // 0x0040 (64) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDE, 0xFFBA, 0xD48B, 0xE448, 0xDC4A, 0xFFBB, 0xFFDE,   // 0x0050 (80) pixels
0xFFFF, 0xFFFF, 0xF7DF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDE, 0xFFBC, 0xFF99, 0xD44A, 0xE428, 0xE428, 0xD44B,   // 0x0060 (96) pixels
0xFF9A, 0xFFDE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDE, 0xFFDE, 0xB4B0, 0xC46C, 0xFF97, 0xFF97, 0xCC8B, 0xCC6A, 0xFF76,   // 0x0070 (112) pixels
0xEC27, 0xD429, 0xFFDC, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDD, 0xFF9B, 0xCC8C, 0xD449, 0xFF76, 0xD449, 0xD46A,   // 0x0080 (128) pixels
0xFF55, 0xE427, 0xDC6A, 0xFFBC, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFDD, 0xFFBB, 0xD46C, 0xEC07, 0xF406,   // 0x0090 (144) pixels
0xF407, 0xE408, 0xD46B, 0xFFBA, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFDD, 0xFF9A, 0xF428,   // 0x00A0 (160) pixels
0xFBE5, 0xF3E5, 0xEC49, 0xFF9A, 0xFFDD, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFBB,   // 0x00B0 (176) pixels
0xFF56, 0xEC28, 0xEC47, 0xFF76, 0xFF9A, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDD,   // 0x00C0 (192) pixels
0xFFBA, 0xDC4A, 0xE428, 0xE428, 0xD44A, 0xFFBA, 0xFFDD, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDF, 0xFFFF, 0xFFFD,   // 0x00D0 (208) pixels
0xFF99, 0xDC4A, 0xE428, 0xEC28, 0xE428, 0xDC29, 0xDC6A, 0xFF79, 0xFFDE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x00E0 (224) pixels
0xFFDC, 0xCC4B, 0xDC49, 0xFF55, 0xE408, 0xE428, 0xFF55, 0xEC48, 0xD44B, 0xFFDD, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x00F0 (240) pixels
0xFFDD, 0xB490, 0xBCAF, 0xFF99, 0xFF98, 0xD44A, 0xE448, 0xFF33, 0xE407, 0xCC4B, 0xFFDD, 0xF7BE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0100 (256) pixels
0xFFFF, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDC, 0xFF99, 0xD46B, 0xE428, 0xE449, 0xD46B, 0xFFB9, 0xFFFD, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0110 (272) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFDE, 0xFFFE, 0xFFDD, 0xFF99, 0xD46B, 0xE429, 0xD44B, 0xFFBB, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF,   // 0x0120 (288) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDD, 0xFFBA, 0xCC6C, 0xD46B, 0xFF9A, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0130 (304) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7DF, 0xFFFF, 0xFFBC, 0xBC8E, 0xFFDC, 0xFFDD, 0xFFFF, 0xFFDF, 0xFFDE, 0xFFFF,   // 0x0140 (320) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDE, 0xFFDE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0150 (336) pixels
0xFFDF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFDF, 0xFFFF,   // 0x0160 (352) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
};
So there is some code at the start of this file that helps define what PROGMEM does...

Quick and dirty sketch that shows how those three checks are defined on T4.1
Code:
void setup() {
  while (!Serial) {}
  Serial.begin(115200);

#if defined(__AVR__)
    Serial.println("__AVR__ defined");
#endif   
#if defined(__PIC32MX__)
    Serial.println("__PIC32MX__ defined");
#endif   
#if defined(__arm__)
    Serial.println("__arm__ defined");
#endif
}

void loop() {
}
As I already knew it only printed out:
Code:
__arm__ defined

So this initial stuff at the top of the file: #define PROGMEM
removed the PROGMEM definition and as such a copy of the image will be brought down into memory (ITCM).
Try removing that section:
Code:
#if defined(__AVR__)
    #include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
    #define PROGMEM
#elif defined(__arm__)
    #define PROGMEM
#endif
from your generated image files and see if that makes a difference
 
Thanks KurtE I did see in complier warning it complaining about PROGMEM being already defined.
But I have found the problem after cutting down to a simple program and seeing it worked I then went back to the original program and commented out all other calls to the display.
After doing that and it still not working properly, I noticed a call to CheckifTouched at the bottom of the loop and when I comment this out (since I am not currently using the touch screen) it worked correctly.
The touch and the display are both on the same SPI bus so it looks like this was trashing it.
Thanks for everyone's help on this.
 
I just noticed something very stupid.
I have both the display and touch SPI chip selects set as the same pin :-(

Code:
#define TFT_SCLK 27  // SCLK can also use pin 14
#define TFT_MOSI 26  // MOSI can also use pin 7
#define TFT_MISO 39  // MOSI can also use pin 7
#define TFT_CS   22  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC   40  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST  255  // RST can use any pin
#define SD_CS    10  // CS for SD card on audio board

#define XPT2046_CS 22
#define XPT2046_IRQ 255
#define XPT2046_MOSI 26
#define XPT2046_MISO 39
#define XPT2046_CLK 27

It must be when I cut ad paste the touch SPI values I forgot to change the CS as all the other defines for it remain the same as the same bus.
 
As you noted should not have same CS. But the MISO pin of many of these displays have an issue where they are not buffered, i.e.
they don't work well with other devices. Many fix by using other SPI buss for touch, or add on an external buffer on the MISO...
 
Thanks KurtE, I will leave the touch side of things as I got rotary encoders and buttons to do selection anyway.
I used SPI1 as the SPI pins are used by the audio shield just to be safe.
 
Back
Top