Showing posts with label bitmap. Show all posts
Showing posts with label bitmap. Show all posts
0

More on menus

Posted by Chris on Thursday, July 16, 2009 in , , ,
One thing that quickly comes to light when working with the Nokia 6610 display - it has no libraries of its own to use: that means that you have to hand-code pretty much everything for it, including making your own fonts and writing your own bitmap display routines.
This means that your code bloats up pretty quickly.

In fact, to demonstrate using bitmaps, drawing strings of text, and including USB support (in order to send commands to the display to test different combinations of things) our code is already a whopping 9.4kb in size.
That leaves around 15kb of space for actually coding that the device should do (on a 18F2455 chip anyway). So almost half of the available program space is taken up with libraries for controlling the display! (ok, it also includes a routine for reading/writing to eeprom, but that it itself is only a few hundred bytes big!)

In fact, forgetting about the eeprom routines could be quite a mistake - instead of hard-coding menu data into the program memory (which strings to display and in which order) it makes a lot of sense to put these strings into external memory.
This offers two distinct advantages: firstly, you're not filling all your program space with strings of characters that make up the menus (you can just use a double-byte word to keep track of the eeprom address that contains the string to draw for each menu item). Secondly, it means porting your device to another language (it's wishful thinking, but there's a massive European market for electronic golf scorecards too) is a relatively painless task: simply update the strings held in eeprom using an external app and your original device code does not need to keep being amended and recompiled. Interesting idea....

Taking this idea a step further, instead of just storing strings in memory, I've decided to store the entire menu structure in eeprom.
The block diagram looks something like this:



  • Each menu begins with a title
  • C = count the number of items in this menu
  • X/Y = position on screen this menu should be displayed at
  • goto = pointer to eeprom address of the next menu to be displayed

The "variable" C has two functions:
The upper three bits are flags to tell us:
  • Clear the entire screen before drawing this menu?
  • Remove this menu after selecting an item?
  • (reserved)

The remaining lower bits contain the value (1-31) telling us the number of items in the list.

The variable "goto" has some special/reserved values:
0 = do nothing when any item in this menu is selected
65535 (0xffff) = go into edit mode when any item in this menu is selected

"Edit mode" puts the device into a special state, where each character of the menu item can be highlighted and changed, individually. This means that, for example, player names can be put into a menu (so that a player can be selected) but at the same time, player details can be updated (e.g. change the letters of a players name).

If the variable "goto" has a valid value (i.e. a number between 1-65534) then this is the eeprom memory address containing the next menu. The current menu is cleared from screen (if necessary) and the new menu is drawn.

Here's a sample menu, converted to a byte array and written to eeprom
84, 105, 116, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 12, 20, 77, 101, 110, 117, 32, 105, 116, 101, 109, 32, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 101, 110, 117, 32, 105, 116, 101, 109, 32, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 101, 110, 117, 32, 105, 116, 101, 109, 32, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 101, 110, 117, 32, 105, 116, 101, 109, 32, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0

You'll see how the first byte is 84 (ascii 84=letter T), followed by 105 (ascii 105=i) and so on, spelling out the word "Title" and some padding bytes. The values 4,12,20 are the C,X and Y values, followed by the next line item in the menu: ascii 77=letter M, ascii 101=letter e (and so on, spelling out "Menu item 1").
Here's the resulting menu, drawn on the Nokia 6610 screen:


0

Monochrome bitmaps on a full colour display?

Posted by Chris on Sunday, July 12, 2009 in , , , , ,
The Nokia 6610 display can support up to 12-bit colour so why bother with monochrome bitmaps?

Well, using a PIC microcontroller, even with 24C256 I2C eeprom (256kb) attached, doesn't provide a massive amount of memory for displaying full colour bitmaps. Even a simple 256 colour image (8-bit palette, similar to a GIF) uses one byte per pixel (the Nokia supports modes that use up to 2-bytes per pixel). The display is 131x131 (often listed as 128 by 128 but this allows for non-viewable pixels around the edge of the display) so a GIF-type image would take a whopping 17,161 bytes (around 16kb).
Given that the PIC18F2455 has 24kb of program space (it was tempting to write "only 24kb" but that's doing the chip a disservice!) coding a single full-colour image uses up 3/4 of the available space. Add in USB support, using the Oshonsoft PIC18 compiler and you've filled the program memory without actually writing any of your own code!
Also, dragging data back from the eeprom chip inbetween drawing pixels on the screen means that displaying the full colour image actually takes quite a long time.

Compare this to a displaying a monochrome bitmap.
First off, pixel data can be packed into packets of 8-bits - since each pixel takes on the colour of either "foreground" or "background" (a one or a zero can be used to represent either state). This means that a full screen image takes up (131 x 131)/8 = 2,146 bytes.
For images that have large areas of the same colour, the "bitmap" data could be written as "number of pixels before pixel changes colour". This can reduce the amount of memory used quite drastically.

Below is a screenshot of a VB app thrown together which loads a monochrome bitmap image and outputs two byte arrays - one an array of pixel data using 1=foreground colour, 0=background colour, the other an array listing the number of pixels in a (vertical) row before the pixel colour changes:



The image loaded was 43x87 pixels.
This can be represented as (43x88)/8 = 473 bytes.
(the image size has to be rounded up to 88 so that it is a multiple of 8, allowing the data to be packed into byte-sized packets).

Below is the byte array used to store the golfer bitmap data:
0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x98, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x8C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x00, 0xF8, 0x7F, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0xF8, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x9F, 0x00, 0xF0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x83, 0x00, 0xF0, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x81, 0x00, 0xD8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x81, 0x00, 0x0C, 0xFC, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x80, 0x00, 0x06, 0xF8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0x7F, 0x80, 0x00, 0x03, 0xF8, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x80, 0x80, 0x01, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x80, 0xC0, 0x00, 0xFE, 0xFF, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x80, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0x38, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x7C, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xA0, 0x7E, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xC3, 0x7F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xF8, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x80, 0xFF, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x80, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x80


But changing the method of recording data as "number of same coloured pixels" can be recorded as
29, 5, 53, 1, 28, 6, 53, 1, 27, 2, 2, 4, 52, 1, 26, 2, 3, 3, 53, 1, 25, 2, 5, 1, 54, 1, 24, 2, 61, 1, 23, 2, 62, 1, 22, 2, 63, 1, 21, 2, 64, 1, 20, 2, 65, 1, 16, 5, 66, 1, 14, 6, 67, 1, 13, 7, 59, 7, 1, 1, 12, 9, 54, 13, 11, 11, 52, 14, 11, 12, 2, 2, 46, 15, 11, 18, 44, 12, 2, 1, 12, 18, 41, 11, 5, 1, 12, 19, 39, 11, 6, 1, 11, 2, 1, 18, 36, 13, 6, 1, 10, 2, 6, 16, 33, 13, 7, 1, 9, 2, 8, 17, 30, 13, 8, 1, 8, 2, 9, 18, 28, 13, 9, 1, 7, 2, 9, 22, 24, 12, 11, 1, 6, 2, 9, 25, 19, 15, 11, 1, 5, 2, 9, 58, 13, 1, 3, 3, 8, 58, 15, 1, 2, 5, 6, 58, 14, 1, 1, 1, 1, 6, 4, 58, 15, 4, 1, 67, 15, 5, 1, 65, 16, 70, 3, 34, 1, 74, 1, 5, 8, 74, 1, 9, 4, 9, 2, 61, 1, 1, 2, 20, 5, 58, 2, 1, 3, 18, 7, 56, 3, 1, 7, 13, 11, 49, 7, 1, 9, 10, 14, 45, 9, 1, 11, 6, 17, 39, 14, 1, 36, 30, 21, 1, 41, 14, 32, 1, 44, 6, 37


This uses just 231 bytes to store the entire image.
And here it is drawn back on the Nokia display (code includes a yet-to-be-resolved bug, but you can see the bitmap image displayed clearly on the LCD).



So why use monochrome images when you have a full-colour display?
When working with PIC microcontrollers or limited memory space, because you can get an image size down from a ridiculous 16kb down to just 231!

whos.amung.us

Copyright © 2009 .Nerd Club All rights reserved. Theme by Laptop Geek. | Bloggerized by FalconHive Supported by Blogger Templates.