.Bmp to LCD ??

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

.Bmp to LCD ??

Post by cobra1 »

Hi,

Im looking to upload a .bmp image as a bootup flash screen. So far i know i have to put the image onto an SD card.
The image would be to the required pixel size, i.e 320x240 pixels.

When this is done what is the next step? how do i get the data from the SD card to LCD display?
In a previous thread i read that you have to convert to an array, how is this done??
Once converted to an array how do you display that array?

Any help would be great :)

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

The LCD will be 16bit colour too, im guessing that makes it all the more difficult to do.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

Hello.

I doublt there is much you will need to convert to an array here, not unless you want to hold the pixels in memory instead of just displaying them. A .bmp file can be read as a stream of bytes, and you can load the pixels one at a time without having to 'remember' them in an array. I'm assuming you will be using the FAT component to extract the data and that all your HW is set up OK - hardware is out of my scope so I cant help you there I'm afraid.

The first thing to do when decoding a .bmp file is to get the correct headers. This link is probably the most straightforward:
http://www.fileformat.info/format/bmp/corion.htm
If you load a bitmap file into any hex editor (there are plenty available free for Windows) you might be able to trace this structure inside your file. Most of the data can be ignored - all you will need is the offset of the data in the file, and maybe the horizontal/vertical size and bits-per-pixel if you want to sanity check them.

If you save your bitmap as 16-bit colour and also, like you say, ensure its the correct size, things will be much easier. You should be able to use the FAT component to extract the data from the file you require.

Extract the bitmap header - if you assume the correct resolution and bpp for now (just to get things started) all you need is to load the 2 bytes at 0xA - this is the offset of the bitmap data.

Remember when decoding your bitmap that Microsoft are a funny bunch, and therefore the colour format is BGR, not RGB. Also the Y is probably inverted. So use something similar to the loop below to extract your image (assumes the correct bitmap formatting to start with):

Code: Select all

  // Move the file offset to the position specified by the offset of your bitmap data
  .....
  // Extract the data...
  y = bitmap_height
  while y > 0
    y = y - 1
    x = 0
    while x < bitmap_width
      lo = file_read_byte()
      hi = file_read_byte()
      pixel = lo | (hi << 8)
      r = (pixel & 0x7C00) >> 10
      g = (pixel & 0x3E0) >> 5
      b = (pixel & 0x1F)
      lcd_set_fore(r, g, b)
      lcd_plot(x, y)
      x = x + 1
    loop
  loop
Note: I think that the format of a 16bpp bitmap is 5 bits for each red, green, blue component, but some systems use an extra bit for green or blue, and depending on your version of Flowcode you may then have to scale these to the values expected by your LCD display.

Being pseudo-code this isn't tried or tested anywhere, but I hope this is enough to get you started. Cheers,

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Hi jonny.

Thans for the reply. I am still a bit lost tho. I don't get how you get the info from the memory card to the LCD.
What do i do with the code you posted? Does that go into the main of my code in a C box?
Also a bit confused with the headers thing.

Software isn't really my thing so I'm really struggling here.

On a different note I saw your article on you reptile control unit. I am currently working on a similar project at the moment.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

Hello. First and most importantly, I hope you liked the article! I have upgraded that now so it varies the temperature based on day length.

Anyway, no probs - these things seem complicated but once you get into them it becomes much easier.

I dont have Flowcode v3 installed on my machine so couldn't post a flowchart solution - the code I posted is pseudo-code, a made up language just to illustrate the code. A bitmap has an internal format - it isn't just a block of pixels, and requires information such as the width/height of the bitmap, bits-per-pixel, palette (if 8-bpp or under) and so on. After that 'header' there is the pixel data. To load any bitmap correctly you would need to look at this header and perform conversions - scaling if the resolution isnt right, colour conversion if your pixel depth (bpp) isnt right, and so on. We can probably assume as this is a specific bitmap that all this isnt necessary.

As part of that bitmap header there is an offset in the file to the pixels. This is the only thing you need to know really, and it needs reading out of the file. After this the pixels may be streamed from the file to the LCD.

The following images show how you might do this in Flowcode. It assumes you are using the FAT16 and gLCD components - if you are not then you need some way of accessing the card (via SPI, etc) and drawing to the LCD. I'm afraid I cant help here. It is the entire program, stored in 2 macros. You can then call the 'load_bitmap' call from Main or wherever you want.

Please note that this hasn't been tested properly - it is written in v5 which is still in development - but I hope it serves as an outline of what to do. Also, note that any variables in the images that start with a '.' are local variables - this is neater than a load of globals but isnt vital.

This image shows how to load from the FAT16 a 2-byte word. If you arn't using the FAT16 component, you can ignore this, but provide an alternative function for loading the data via SPI from your card, if necessary.
***** Note: There is a typo in the screenshot, '.ix <= 16' should be '.ix < 16' *****
load_fat_word.png
Load 16 bits with the FAT component
(33.72 KiB) Downloaded 6846 times
This next image shows how this can be used to load the data off the card and sent to the LCD. Again, if you are not using these components you will have to provide your own calls.
load_bitmap.png
Loads a bitmap to the LCD
(31.01 KiB) Downloaded 6846 times
Finally, here is an image of the macros and variables used. A 'B' next to a variable indicates it is a byte, a 'Z' indicates it is an integer. Any of the local variables can be created as globals if you like.
summary.png
Summary of the program
(14.5 KiB) Downloaded 10983 times
Hopefully, thats about it. If any (or all) of this dosent make sense, lemme know, but otherwise good luck with it!

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Hi,

Thanks for your reply, very detailed. I can work from that i think, there was one last thing i saw in the flowchart im not sure on.

In the Load bitmap chart, you have a macro being called, its the one labelled "load the pixel" whats would i do there??

I know in the glcd component theres a plot pixel macro, but not one to load a pixel.

Other than that i think i might be able to get it to work :)

Thanks again for you help mate.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

Hi there. The 'load a pixel' is calling the load_word() macro - the first of the images. This loads 2 bytes from the FAT16 component and 'bolts' them together, forming your 16-bit word that will be the pixel. This is then stored in variable 'pixel' which is 'dissected' into its red, green and blue components and sent to the LCD.

Note that there isnt any scaling done here - for example, if you use this code and it works OK but the bitmap seems dark, then the R, G, B values probably need shifting up.

Cheers,

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Ok, thats cool, i will get as far as i can now and see what happens, just out of interest how does one shift the pproperties up?? is it just a case of changing numbers to higher values?

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

A bitshift is done using the 'logical shift-left' operator:

Code: Select all

r = r << shift
This is equivalent of multiplying by 2 to the power 'shift', but is much faster and easier for the chip to handle. If the bitmap doesnt look right, then its likely the bits-per-pixel are wrong in some way (some LCDs use 6 bits per pixel for green or blue instead of 5). In this case the values either need shifting up/left (<<) or down/right (>>).

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Hi Jonny,

i tried to follow your flowcharts, but i think im getting a bit stuck with the load_pixel macro, i think i might have messed it up, what i did was changed the fat_file_offset variable to pixel variable in a new macro, so i have 3 macros in total.

Load Bitmap
Load Word
Load Pixel

i have attached my file for you to look at as far as hardware goes im getting the screen to initialise, thanks to Mika. I have also added in my fat 16 component and that seems to be initialising OK. After that the screen just stays blank.

Hopefully its not something too major.
Attachments
Load Bitmap 18F4685.fcf
(16 KiB) Downloaded 466 times

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

Morning.

First thing is none of the init functions 'FAT16::Init_FAT()' etc are writing their return value to a variable. Without this mod, the function will either sit in an infinite loop (retval is non-zero) or never initialise the FAT file system (retval is zero).

Try modding Main() with the following loop:
mod_01.png
Modify to main()
(6.2 KiB) Downloaded 10853 times
Secondly yes - you are using 'pixel' in 2 contexts, one for incremental file reading and the other as a global variable representing the pixel. There are also issues where the component argument and the return value are the wrong way round:

Code: Select all

pixel = Read_Byte_From_Buffer(byte)
Should be:

Code: Select all

byte = Read_Byte_From_Buffer(pixel)
(The first line loads a value from offset 'byte' and stores it in 'pixel' - the second loads a value from 'pixel' and stores it in 'byte', which is what you want).

I would suggest removing the 'pixel' variable from the flowchart and replacing it with fat_file_offset as they are both doing exactly the same thing.

As I don't have v3 installed I'm afraid I cant post a fixed solution, however, what I would suggest is for each variable you have created, write down the use of that variable - it is not generally good practice to use the same variable for more than one use, or to use more than one variable for the same use when you can just use one.

The 'return' variable you have created is holding the result of each macro Load_Pixel() and Load_Word(), but then nothing is done with this, so all the data read from the FAT is lost.

The following list should hopefully at least get you progressing - follow the steps in order and this should fix the main issues.
  • Make the mod to initialise the FAT16 above.
  • Swap the variables 'pixel' and 'byte' in Load_Pixel() Read_Byte_From_Buffer() call, and the same for the equivalent Load_Word() call - this causes the 'byte' read to be returned from offset 'pixel' in the file
  • Replace all uses of 'pixel' with 'fat_file_offset' in the Load_Pixel() macro - this keeps fat_file_offset as the offset of the next byte to read in the FAT file through all functions ('pixel' will be the loaded pixel data)
  • As the final icon in Load_Word(), add a calculation 'fat_file_offset = return' - this will cause the offset to 'jump' to the correct location of the first pixel, otherwise the routine will display garbage to the screen
  • In 'Load_Pixel()' replace all occurrences of 'return' with 'pixel' - this will cause this function to load the pixels RGB to 'pixel', so it can be read by Load_Bitmap() and displayed on the LCD
Good luck,

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Ok, i made the changes you suggested and now it initialises and then tries to open the file, when trying to open the file i get a retval "11"

I cant get it to go past this part.

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

ok, it looks like i might be almost there.

I have got it to display the picture on the LCD :)

There is a couple of small problems,


1: the picture is being printed 4 times across the bottom 1/4 of the screen, after about a 1/4 of the way up it turns to jargon, just random coloured pixels.

2: the colours are out, blue is red, red is blue and green is yellow.

3: the loading of the picture is taking about 6 mins to print the full screen out. im running at 64Mhz too

Can you help, i feel soo close

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Ok, just a bit of an update.

I have got the .bmp displaying on the screen properly, had to save it in 16 bit, which isnt all that easy because not many programs support it.
Altered the colours to RGB565 so thats all good now.

Only thing is now i cant figure out how to make it update the screen faster it literally is taking 5-6 mins to load the whole screen, im running 8Mhz in PLL mode so thats 32Mhz.

I will carry on trying, if you have any ideas can you let me know :)
Last edited by cobra1 on Tue Nov 29, 2011 2:09 am, edited 1 time in total.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

Hello. Glad you got it working!

When it comes to speed, I think the first thing to do is establish what is taking so long - there are two aspects - loading from the file and writing to the screen.

Neither of these should take that long (or even close to it) but I would suggest putting that code aside for the time being and performing some basic tests on the HW. Try writing a program that jst fills the LCD pixel-by-pixel on the screen 9without accessing the FAT file), and another that just reads the pixels but doesnt write to the LCD and time how long each one takes.

Thing is, it doesnt matter how fast your CPU will be if the interface between the FAT disk or the LCD is very slow, as these calls will be the bottlenecks.

I am on a Linux laptop at the moment so cant remind myself of the flowchart before tomorrow, but make sure that the call to Read-File-Sector() is only being done when it needs to be - if the 'force_load' variable is always set then this could be the cause of the slowdown. FAT16 sectors are 512 bytes, so you only need to re-read the sector info when you need to read the next 512 byte block (this is the 'if fat-file-offset >= 512' condition), or when you first start the program.

As a suggestion, remove the call to Read_File_Sector() from the start of Load_Pixel() and Load_Word(), and add it instead to the start of Load_Bitmap(), and maybe immediately after the calls to Move_To_Next_File_Sector(). This should remove this call from the possibility it is causing the slowdown.

Good luck,

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Hi jonny,

I removed the load pixel macro from the loop and set it away, it fills the screen with pixels in about 1 second. So i think that rules out the LCD writes being a problem.

I moved the force load to where you said and the screen definatly loads much faster :) about 8-10 seconds. I still dont think thats fast enough though.

The only thing left to slow it down is the read_from_buffer command, is there any way to speed this up? currently its in bit bang mode as the Hardware SPI doesnt seem to want to function in PLL mode.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

Hello.

8-10 seconds - this can be cut down to 2-3 seconds at the expense of resolution if you want. If you use a bitmap that is 1/2 the width and 1/2 the height then you can speed the load up by 1/4. Of course you then have to draw 4 pixels instead of one each time. If you do this, would create another macro, called Draw_Pixel() and pass your X and Y as parameters to this - it just works out neater for the code this way. You could combine this with converting your bitmap to 8bpp and using a palette to get a further double saving, at the expense of colours (max 256 colours can be plenty though, with the right palette), or even 16 colours (4bpp) and load 2 pixels every byte.

All this comes at the expense of extra processing inside your rendering loop, but this is negligible in terms of CPU cost when compared to loading from the disk.

As far as hardware tweaks go, I'm afraid I cant help you much, and there may be ways of speeding the disk load up so you wont have to worry about implementing any of the above, which will probably be a bit of a headache.

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Hi jonny

I might be able to sacrifice resolution for speed. Hopefully it won't look too bad.

I don't suppose I could be cheeky and ask for a guide on how to make this extra macro?

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Also 256 colour would be ok too

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

No probs.

First thing, use local variables in your macro. It will keep your program cleaner and be easier to understand in the long run. Locals in Flowcode are referenced by 'macro_name.var_name'.

This is a screenshot of the macro, this will assume X and Y are 1/2 what they should be, so remember in your main load loop to change 240 and 320 to 120 and 160. It is pretty basic and draws each pixel individually, instead of drawing in a loop.
Draw_Pixel.JPG
Example draw
(113.24 KiB) Downloaded 6678 times
If you don't want to use local variables there is no problem, you can use globals, but make sure they are different X and Y from the ones that are controlling the drawing loop, so they don't corrupt.

Hope its of use,

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

That's great. Thanks. Just one thing. Do is till save the image in 16 bit. Or 256 colour?

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

That flowchart will deal with 16bpp. For 256 colour this would need additional mods, as would the Load_Pixel() macro.

Jonny

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Ok cool ill see how fast it is with this mod and get back to you :)

cobra1
Posts: 175
Joined: Thu Feb 04, 2010 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: .Bmp to LCD ??

Post by cobra1 »

Just out of interest. Would a PIC24 run this any faster? If it would I would consider buying flowcode fo pic24. If I could use pic24 would I need any modifications to this code?

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: .Bmp to LCD ??

Post by JonnyW »

I would expect a dsPIC to run faster, though I'm not the best person to ask. As a rough guide, I have had Asteroids and PacMan running on a dsPIC with a graphical LCD at a very decent frame-rate - I cant see that would ever be possible with an 8-bit PIC. As well as the speed increase there is also the additional memory (ROM and RAM) and ability to do floating point arithmetic at a decent rate. Given the choice, I would opt for a dsPIC. I can't tell you the expected release date of Flowcode v5 for dsPIC though - somewhere early in the new year.

However, bear in mind that the bottleneck for your program isn't in the chip itself, its in the comms with the FAT data. I don't know if there would be any saving here or not.

Jonny

Post Reply