color map for ILI9340/1 TFT display

Go To Last Post
36 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

where can I find such color maps ? I am currently using ILI9340 based TFT display and I found online values for some basic colors like RED ,GREEN ,BLUE ,BLACK etc but I need RGB values for more colors.
Maybe its in the data sheet of ILI9340 but I am not finding it there.

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you intellectually challenged ?

You can make any colour you want from the values of R, G, B. In fact, it is 65536 different colours if you are using the 5-6-5 16-bit mode. Since you have a bare module, you can use the 18-bit mode that gives 262144 different colours.

If you really want to assign unique MACRO_NAMEs for 262144 colors, you will need to do a lot of typing!

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi David !

now I have these basic color defined as :

#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define BLACK 0x0000
#define YELLOW 0xffe0
#define WHITE 0xffff

how can I use other colors from their RGB values?

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looking at the datasheet it looks like it supports two colour depths 5:6:5 or 6:6:6.

if I Google "colour selector for 5:6:5" one of the top hits is:

http://4d.websitetoolbox.com/pos...

Someone's gone to all the trouble of defining lots of fancy names for 5:6:5 colour modes there!

To be honest I think I would simply use an HTML colour selector such as this:

http://www.w3schools.com/tags/re...

Pick some colours, for example I like the look of #66FF99 and then convert this 24 bit 8:8:8 value to 5:6:5 or 6:6:6 using the most significant bits. So for this lovely greeney-blue the 66FF99 is:

R: 0x66 = 0b01100110
G: 0xFF = 0b11111111
B: 0x99 = 0b10011001

To convert to 18 bit (6:6:6) just take the top 6 bits of each:

R: 011001
G: 111111
B: 100110

then add them together to make the 18bits

011001 111111 100110

grouping that in fours:

01 1001 1111 1110 0110

which in hex is:

0x19FE6

Doing the same for 16 bit (5:6:5) would be:

R: 01100
G: 111111
B: 10011

which is

0110 0111 1111 0011
0x67F3

So "limey green" is 0x19FE6 in 18 bit mode and 0x67F3 in 16 bit mode.

Obviously you'd write a C program that you feed a 24 bit HTML #66FF99 from the tool and it would simply pump out the 16 and 18 bit values for it having done the and'ing and shifting for you rather than having to do it all manually.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
// Color definitions for 64k color mode
// Bits 0..4 -> Blue 0..4
// Bits 5..10 -> Green 0..5
// Bits 11..15 -> Red 0..4
#define GLCD_CL_BLACK 0x0000
#define GLCD_CL_WHITE 0xFFFF
#define GLCD_CL_GRAY 0x7BEF
#define GLCD_CL_LIGHT_GRAY 0xC618
#define GLCD_CL_GREEN 0x07E0
#define GLCD_CL_LIME 0x87E0
#define GLCD_CL_BLUE 0x001F
#define GLCD_CL_RED 0xF800
#define GLCD_CL_AQUA 0x5D1C
#define GLCD_CL_YELLOW 0xFFE0
#define GLCD_CL_MAGENTA 0xF81F
#define GLCD_CL_CYAN 0x07FF
#define GLCD_CL_DARK_CYAN 0x03EF
#define GLCD_CL_ORANGE 0xFCA0
#define GLCD_CL_PINK 0xF97F
#define GLCD_CL_BROWN 0x8200
#define GLCD_CL_VIOLET 0x9199
#define GLCD_CL_SILVER 0xA510
#define GLCD_CL_GOLD 0xA508
#define GLCD_CL_NAVY 0x000F
#define GLCD_CL_MAROON 0x7800
#define GLCD_CL_PURPLE 0x780F
#define GLCD_CL_OLIVE 0x7BE0

Note that you can run most of these controllers in RGB or BGR mode, your options are endless.

As Cliff said, you can choose your favourite colours for HTML or other purpose. Then convert to the 5-6-5 mode for your controller.

I strongly advise that you limit yourself to 20 odd favourites and stick to them. It will give your displays a corporate touch and feel. You can use the other 65516 colours for photos etc.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's a novel idea - why not write a colour picker for the AVR+LCD itself? You just need some up/down controls for R, G, B or H, S, V and you then compose the colours you like on the display itself. Have it show a patch of the colour and the 16 bit code for it. Note down the ones you like and give them exotic names like BURNT_SIENNA, INDIAN_OCEN_BLUE or whatever.

It's probably better doing it this way than using a colour selector on your monitor as the "temperature" of the display you are using probably won't match the colour profile of your PC monitor.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank you to both of you for valuable info. I am learning this TFT display and very pleaseed with the response i am getting for screen refreshes in 8bit mode.
I would love to learn how to use the RGB mode but it looks too intimidating from data sheet.
I am now trying to display the bmp images using arrays I dont know if it will display color image or black n white .
how RGB mode works in nut shell and how can it benifit me?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't read the entire datasheet but as far as I can see it just has 16 and 18 bit modes. Both are RGB colour modes. To render a B/W image you would presumably have to upscale the data to 0x3FFFF/0x0000 or 0xFFFF/0x0000 values. For grey scale you would construct 16/18 bit values with equal amounts of RGB and map from the 0..255 byte values in the source image.

BTW I notice it has a BGR rather than RGB capability - that could be useful for Windows BMP which is once of the only formats in the world that uses BGR instead of RGB ordering.

One thing that is going to be an issue for you is that BMP formats are going to be one of 2bit (b/w), 8bit (paletted), 24bit (RGB). I imagine you will try to show 24 bit. You are therefore going to have to downsclae it to 16/18 bit. Of those 5:6:5 (16 bit) is probably easier,

If you hunt around on here you may find a utility I once wrote that can downscale 24 bit RGB to 5:6:5. Guess what the exact reason was that I wrote it! ;-) It will even do some Floyd-Steinberg as it down-samples if you ask it nicely.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ell, I did not read Clawson's remark about BGR instead of RG, but a python script can convert easily to 18 bits:

# ? denotes the percent sign (modulo)
def col24to18(color): 
  red, reste = color / 0x10000 ,   color ?  0x10000
  green, blue =reste / 0x100 , reste ? 0x100
  base=2**6
  bm1=2**8 / base 
  return( ((red / bm1) * base + (green / bm1) ) * base + (blue / bm1))

color=0x66FF99
print format(col24to18(color),"0x")
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The "RGB Interface" actually means you are using the VSYNC, HSYNC, DOTCLK, DE, D [17:0] pins.

Most static displays use the 8080 style parallel or SPI style serial pins.
e.g. display photos, graphics, text, ...

You probably use the RGB Interface when you want to display video.

I would stick to the regular static type if you are using an AVR.
You can manage simple animations but full-speed video is too much for an AVR.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've never totally understood why C programmers choose to use other languages like Python? Personally I'm a C programmer and I'd do that in C:

uid23021@lxl0060u:~$ cat test2.c
#include 
#include 

int main(int argc, char * argv[]) {
	uint32_t num;
	if (argc != 2) {
		printf("use %s 0x66FF99 or similar\n", argv[0]);
		return 1;
	}
	num = strtoul(argv[1], NULL, 16);
	printf("%06X - > %04X\n", num, (num & 0xF80000)>>8 | (num & 0x00FC00)>>5 | (num & 0x0000F8)>>3);
	return 0;
}
uid23021@lxl0060u:~$ gcc test2.c -o test2
uid23021@lxl0060u:~$ ./test2
use ./test2 0x66FF99 or similar
uid23021@lxl0060u:~$ ./test2 0x66FF99
66FF99 - > 67F3

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

!duplicate .removed

Last Edited: Wed. Mar 26, 2014 - 02:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
The "RGB Interface" actually means you are using the VSYNC, HSYNC, DOTCLK, DE, D [17:0] pins.

Most static displays use the 8080 style parallel or SPI style serial pins.
e.g. display photos, graphics, text, ...

You probably use the RGB Interface when you want to display video.

I would stick to the regular static type if you are using an AVR.
You can manage simple animations but full-speed video is too much for an AVR.

David.

yes David I will not be using videos on this display , just bmp images and color menus. Also I only can use 8 data pins so i will stick to current 8080 style mode.

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

so if i have to display a bitmap image i should convert a image to bitmap and select its resolution as 320x240 and 16bit or 256 color, then save it as an array and call that array in my program ?
any known good bitmap image converters you can recommend for this ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

so if i have to display a bitmap image i should convert a image to bitmap and select its resolution as 320x240 and 16bit or 256 color, then save it as an array and call that array in my program ?

Which AVR model are you using?

320x240 is how many pixels? 76800.

16-bit would take 153600 bytes of storage in your array. And that is for >>one frame<<.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've never totally understood why C programmers choose to use other languages like Python?

Because :
a) I program much better (at least, less badly!) in Fortran or -incl.- R than in C...

b) I decided to try not to add entropy to this word, and emitting poor C programs is a source of disorder (this is the most important point) . As good C programmers exist, this is not that dramatic.

c) I noticed that Python was easier to debug (interpreted language, like R -the latter remains unpopular- or bash -which is cryptic- ) than C

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

then save it as an array and call that array in my program ?

If you think that bitmap images magically appear on LCD displays because you "call the array" then I'm afraid you have a lot to learn.

The way things appear on displays is by pixels being set on/off or to some level of colours. To display a picture it's really just an x,y rectangular grid of pixels so, in the simplest form you go across the x's and down the y's setting each pixel in turn.

Computer science has developed a name for this - it's called a "bitblit". Wikipedia:

http://en.wikipedia.org/wiki/Bit...

tells us this is "binary-boundary block transfer" but everyone just use bitblt or bitblt.

Most LCD libraries have functions like set_pixel(x,y) and for graphics displays there's a strong chance there is a bitblt(x,y,data) which takes a pointer to your array and arranges to blit the pixels to the display at the starting x,y position. Internally the library probably uses the same routine to blit characters of a font (just small rectangular pictures after all) to the display and at an even higher level there's probably lcd_choose_font() and lcd_print_string(). One chooses which set of rectangles might be blitted and the other works along a string of character looking up the right "picture" for each character in the string and blits each in turn to the output moving the destination X value on by the width of the character just output each time.

So look to your LCD library (I assume you are using one?) and see what it offers. If it only has lcd_set_pixel() you are going to need to build your own blit() on top of that.

When you have that and when you have massaged the BMP data into the same pixel format as the display uses you are ready to lcd_blit() that array onto the screen.

I'm sure there must be tons of tutorials on the internet about all this?

PS when I google the name of this display I see a mention on Adafruit (always a good sign as there's a fair bet the works been done and done well!). It leads to:

https://github.com/adafruit/Adaf...

Sadly that does not go as high level as a blit() and fonts:

           setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),
           pushColor(uint16_t color),
           fillScreen(uint16_t color),
           drawPixel(int16_t x, int16_t y, uint16_t color),
           drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
           drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
           fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
             uint16_t color),
           setRotation(uint8_t r),
           invertDisplay(boolean i);

I guess one could use the drawPixel() there to develop a blit()

EDIT2: oh how ironic. The other place I found a library was:

http://www.mikroe.com/download/e...

But that is going to need the MikroC compiler methinks - it as an odd scheme where you pick things like TFT support in the project settings. I doubt the licence on the 4K eval copy allows you to steal their TFT library code (even if you could make it work with a real C compiler!).

Last Edited: Wed. Mar 26, 2014 - 03:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi Clawson !
I am not using any library I built my own functions based on the example given on NHD site .
I can set indivisual pixels to any color I want and already doing it to draw lines and rectangles on the display.
so if I can indivisually control the 320x240 bits on this display can I display the bitmap image ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In that case time to implement a blit. It's basically going to be something like:

void blit(int x, int y, int w, int h, uint16_t * data) {
  for (int localy=y; localy < (y + h); localy++) {
    for (int localx=x; localx < (x + w); localx++) {
      set_pixel(localx, localy, *data++);
    }
  } 
}

Assuming the uint16_t data is ordered nicely.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes Cliff, most libraries have a blit() method.

You generally load BitMaps directly from a SD Card. They often require massaging to your internal TFT format. You take a short BMP sequence, massage it into a TFT sequence, blit this to your display window. Rinse and repeat until done.

The only way that you can use arrays is like in those Ebay TFT photos. e.g. multiple Penguins. You can fit a small image in an array, then draw it multiple times.

@Ali,

Life is much simpler if you use respected libraries. e.g. Adafruit.
See how they do things. Then you can learn for yourself.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A lot of these displays have a mechanism for setting a bounding box, i.e. specifying top right and bottom left coordinates of a rectangle. Then you can simply write x * y pixels without having to keep setting X and Y.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

so if i have to display a bitmap image i should convert a image to bitmap and select its resolution as 320x240 and 16bit or 256 color, then save it as an array and call that array in my program ?

Which AVR model are you using?

320x240 is how many pixels? 76800.

16-bit would take 153600 bytes of storage in your array. And that is for >>one frame<<.

I am using atmetga1284.
yeah 16bit image wont fit then, so 256 color images ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
In that case time to implement a blit. It's basically going to be something like:

void blit(int x, int y, int w, int h, uint16_t * data) {
  for (int localy=y; localy < (y + h); localy++) {
    for (int localx=x; localx < (x + w); localx++) {
      set_pixel(localx, localy, *data++);
    }
  } 
}

Assuming the uint16_t data is ordered nicely.

where "data" is array of pixels from an image converted to bitmap ?
do you have anyguide lines on how to do this ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Yes Cliff, most libraries have a blit() method.

You generally load BitMaps directly from a SD Card. They often require massaging to your internal TFT format. You take a short BMP sequence, massage it into a TFT sequence, blit this to your display window. Rinse and repeat until done.

The only way that you can use arrays is like in those Ebay TFT photos. e.g. multiple Penguins. You can fit a small image in an array, then draw it multiple times.

@Ali,

Life is much simpler if you use respected libraries. e.g. Adafruit.
See how they do things. Then you can learn for yourself.

David.

why is it called "blit" ?
does Adafruit library have an example of how to convert and call this image array ? I will take a look.
I just need to display a simple 256 color image on the display no fancy animated stuff or videos.
what I am not sure is that when I convert the image into bitmap array does it contain color info ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Buy an Arduino. Then you can run ready-made programs that work first time.

I am not sure about the origin of "BLIT". Something to do with sending bits at the speed of light ?

If you just want to draw simple graphics or computed colours, it is trivial.
You use virtually no SRAM memory. The graphics libraries fit in 20kB or so of Flash memory.

Then you can draw Oscilloscope front panels, Aeroplane instrument displays, Logos, Text, Diagrams, ... to your heart's content. Your ATmega1284 or an ATmega2560 has plenty of Flash for your application code.

However full-screen 64k Colour BitMaps need to come from a BIG EEPROM or SD Card.
An Arduino UNO is quite capable of showing thousands of photos. Most TFT display shields come with an SD Card socket.

Yes, you can save memory by going to 256 Colours. Photos will look crap.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok I guess my next project is to interface SD card to my board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I just need to display a simple 256 color image on the display no fancy animated stuff or videos.

You never addressed what I wrote earlier...
Quote:
320x240 is how many pixels? 76800.

16-bit would take 153600 bytes of storage in your array. And that is for >>one frame<<.


Where are you going to put this 150KB for your simple image?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

I just need to display a simple 256 color image on the display no fancy animated stuff or videos.

You never addressed what I wrote earlier...
Quote:
320x240 is how many pixels? 76800.

16-bit would take 153600 bytes of storage in your array. And that is for >>one frame<<.


Where are you going to put this 150KB for your simple image?

I just converted a bitmap image of resolution 320x240 16bit using a bitmap image converter and the resulting size of file is 57k bytes , so cant i put it in flash memory ? since i have more than 100K available there.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
#include 
#include 

extern uint8_t SmallFont[], BigFont[];

UTFTGLUE tft(SSD1289,A1,A2,A0,A3);

uint16_t height, width;

void setup(void) 
{
    tft.InitLCD(0);
    tft.setFont(BigFont);

    tft.fillScr(0, 0, 0);
}

void loop(void)
{
    uint16_t start, y, incr;
    width = tft.getDisplayXSize() - 1;
    height = tft.getDisplayYSize();
    incr = height / 3;
    tft.setColor(255, 255, 255);
    tft.print("Red", 0, start = 0);
    for (start += 16, y = 0; y < 64; y++) {
        tft.setColor(y<<2, 0, 0);
        tft.drawLine(0, start+y, width, start+y);
    }
    tft.setColor(255, 255, 255);
    tft.print("Green", 0, start = incr);
    for (start += 16, y = 0; y < 64; y++) {
        tft.setColor(0, y<<2, 0);
        tft.drawLine(0, start+y, width, start+y);
    }
    tft.setColor(255, 255, 255);
    tft.print("Blue", 0, start = 2*incr);
    for (start += 16, y = 0; y < 64; y++) {
        tft.setColor(0, 0, y<<2);
        tft.drawLine(0, start+y, width, start+y);
    }
    delay(1000);
}

I am sure that you can 'translate' this to your Compiler, Controller, etc.

The computed colours will cost you about 50 words of Flash. Virtually zero SRAM.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

#include 
#include 
#include 

extern uint8_t SmallFont[], BigFont[];

UTFTGLUE tft(SSD1289,A1,A2,A0,A3);

uint16_t height, width;

void setup(void) 
{
    tft.InitLCD(0);
    tft.setFont(BigFont);

    tft.fillScr(0, 0, 0);
}

void loop(void)
{
    uint16_t start, y, incr;
    width = tft.getDisplayXSize() - 1;
    height = tft.getDisplayYSize();
    incr = height / 3;
    tft.setColor(255, 255, 255);
    tft.print("Red", 0, start = 0);
    for (start += 16, y = 0; y < 64; y++) {
        tft.setColor(y<<2, 0, 0);
        tft.drawLine(0, start+y, width, start+y);
    }
    tft.setColor(255, 255, 255);
    tft.print("Green", 0, start = incr);
    for (start += 16, y = 0; y < 64; y++) {
        tft.setColor(0, y<<2, 0);
        tft.drawLine(0, start+y, width, start+y);
    }
    tft.setColor(255, 255, 255);
    tft.print("Blue", 0, start = 2*incr);
    for (start += 16, y = 0; y < 64; y++) {
        tft.setColor(0, 0, y<<2);
        tft.drawLine(0, start+y, width, start+y);
    }
    delay(1000);
}

I am sure that you can 'translate' this to your Compiler, Controller, etc.

The computed colours will cost you about 50 words of Flash. Virtually zero SRAM.

David.

Thanks David !

what is this code doing ?is it an example of SSD interface ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is an Arduino example (init, loop are specific) of computed image:
A part of the screen has variants of red , with vertical gradients; another rectangle has vertical green gradients, the latest vertical blue gradients; fonts are tested, too.
I do not know how x and y axes are in the real world...

It has nothing to do with SSD (but it would be wise to cut difficult problems into smaller ones, and testing each small problem)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Evans and Sutherland BLIT = "Bit Block Transfer"

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

why is it called "blit" ?

I love talking to a brick wall.

"Hello brick wall - how are you?"

Did I or did I NOT say:

Quote:
Computer science has developed a name for this - it's called a "bitblit". Wikipedia:

http://en.wikipedia.org/wiki/Bit...

tells us this is "binary-boundary block transfer" but everyone just use bitblt or bitblt.


Am I just wasting my time answering your questions?!?

Anyway when I said:

void blit(int x, int y, int w, int h, uint16_t * data) {
  for (int localy=y; localy < (y + h); localy++) {
    for (int localx=x; localx < (x + w); localx++) {
      set_pixel(localx, localy, *data++);
    }
  }
} 

obviously no one (except Arduino library authors??) would actually implement it like this. It would be more like:

void blit(int x, int y, int w, int h, uint16_t * data) {
  uint16_t dst = scrnbuffer + (((y * xwidth) + x) * 2);
  for (int localy=0; localy < h; localy++) {
    memcpy(dst, data, (w * 2));
    dst += (xwidth*2);
    data += (w *2);
  }
} 

Or words to that effect. I'll leave you to discover why since anything I say will probably be ignored anyway.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks ! n trust me your words are not getting wasted

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well I read BLIT on wiki link provided by Clawson , didnt get it .. why would you need to send blocks of pixels when you can control each pixel and construct the image?
also in the code by Clawson , where are we sending blocks of bitmap ? I am not understanding it.

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

why would you need to send blocks of pixels when you can control each pixel and construct the image?

You've just asked the question my recently posted code answers. Good luck with finding out why ;-)
Quote:

where are we sending blocks of bitmap ?

Normally a local screen buffer but your one lives down the end of an SPI/I2C link. (yet more reason for doing blits as I suggest!)