Long shot question: drawBitmap() issues with TFT_ILI9341 lib vs Adafruit lib

This is a long shot, but I have to ask just because I know I’m not smart enough to solve this on my own.

I have monochromatic graphics in an array in PROGMEM that I need to display on my screen. I am using an ILI9341 display and running everything from a 3V Pro Trinket (ATMega328p). This works fine with Adafruit’s GFX libraries.

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
//#include <TFT_ILI9341.h> // Hardware-specific library
#include "graphics.c" //external file containing "pre-baked" graphics assets to save memory size

// Numbers indicate pins to connect to Pro Trinket 3V
#define TFT_DC 9
#define TFT_CS 10
#define TFT_MOSI 11
#define TFT_MISO 12
#define TFT_RST 8
#define TFT_CLK 13 //Arduino SCK
#define TFT_LCD 6

//Some handy color definitions in R5G6B5 for later
#define BLACK        0x0000
#define WHITE        0xFFFF

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); //Constructor to use Hardware SPI. Software SPI constructor is below - will work, but slower. 
//TFT_ILI9341 tft = TFT_ILI9341();

void setup()
{
  pinMode(TFT_LCD, OUTPUT);
  tft.begin();
  analogWrite(TFT_LCD,255); //backlight can turn on now.
  tft.fillScreen(BLACK);
  drawBitmap(10,10,testEye,200,213,WHITE);
  //tft.drawBitmap(10,10,testEye,200,213,WHITE);
}

void loop()
{   
}

void drawBitmap(int16_t x, int16_t y,
 const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {
  
  int16_t i, j, byteWidth = (w + 7) / 8;
  Serial.println(byteWidth);
  uint8_t byte;

  for(j=0; j<h; j++) {
    for(i=0; i<w; i++) {
      if(i & 7) byte <<= 1;
      else      byte   = pgm_read_byte(bitmap + j * byteWidth + i / 8);
      if(byte & 0x80) tft.drawPixel(x+i, y+j, color);
    }
  }
}

It reads the image data from graphics.c, which I’m going to attach because of its length, but which contains the data for static const uint8_t testEye[] PROGMEM = {}

This all works exactly as expected, but it is slow to populate on the screen. I was interested in the TFT_ILI9341 library because it looks like it is optimized for speed and compatibility. Switching the code over, at a glance, works really well! I change my declarations around, can get rid of the drawBitmap() function in my sketch, and instead call tft.drawBitmap(10,10,testEye,200,213,WHITE);

I say “at first glance” because as I look closely, I start realizing there’s problems in how it’s rendering. There’s “noise”, but it’s only limited to the left edge of the image. An image is the best way to demonstrate the issue:

Running on the same hardware, same screen, same wiring, and it’s the same array being fed into both functions, so I’m not sure where the discrepancy lies, but I’m afraid it might be something in the drawBitmap() function itself, which is so far beyond my ability to understand that it’s embarassing.

In my User_Setup.h for this library, I’ve got #define FAST_GLCD and #define FAST_LINE uncommented, my pins are defined correctly, and I’ve commented out all of the fonts save for the initial #define LOAD_GLCD. #define CLIP_CHECK and #define SUPPORT_TRANSACTIONS are presently commented.

Any idea what I’m doing wrong? I’m an amateur at best here, and I honestly have no idea how to read useful data out of the byte array above to figure out if there’s some formatting thing I have wrong in there that would cause it to work fine with one library’s functions but not another’s.

graphics.c (74.2 KB)

test_eye.ino (1.31 KB)

Another example. This one is a set of 3 arrays overlaid on one another with 3 drawBitmap() calls, one for each. Same kind of results - something is up with that left edge and I don't know what.

|500x247

Hi, I will invesrigate this. I see that there are other corupted pixels elsewhere in the image. Can you tell me more about your setup. Are you running the Trinket at 3V? What is the clock frequency of the processor. Which TFT display are you using?

I see this issue is also posted on Github so that is where the solution will be posted when solved.

At the moment I suspect the display is not seeing some data bits, hence the wrong pixel colour, but that is getting all the clock signal edges as the drawn pixel count looks right. Do you have anything else on the SPI bus?

Update: I see you are using drawPixel. This means that we would not see a tearing efect in the image from lost clock edges, hence lost edges is a possible reason for the problem.