Go Down

Topic: Someone please help me with font edit (Read 2352 times) previous topic - next topic


This is the code for nokia 3310 LCD I got from here

Code: [Select]
#define PIN_SCE   7
#define PIN_RESET 6
#define PIN_DC    5
#define PIN_SDIN  4
#define PIN_SCLK  3

#define LCD_C     LOW
#define LCD_D     HIGH

#define LCD_X     84
#define LCD_Y     48

static const byte ASCII[][5] =
{0x00, 0x00, 0x00, 0x00, 0x00} // 20  
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f ?

void LcdCharacter(char character)
 LcdWrite(LCD_D, 0x00);
 for (int index = 0; index < 5; index++)
   LcdWrite(LCD_D, ASCII[character - 0x20][index]);
 LcdWrite(LCD_D, 0x00);

void LcdClear(void)
 for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
   LcdWrite(LCD_D, 0x00);

void LcdInitialise(void)
 pinMode(PIN_SCE, OUTPUT);
 pinMode(PIN_DC, OUTPUT);
 digitalWrite(PIN_RESET, LOW);
 digitalWrite(PIN_RESET, HIGH);
 LcdWrite(LCD_C, 0x20);
 LcdWrite(LCD_C, 0x0C);

void LcdString(char *characters)
 while (*characters)

void LcdWrite(byte dc, byte data)
 digitalWrite(PIN_DC, dc);
 digitalWrite(PIN_SCE, LOW);
 shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
 digitalWrite(PIN_SCE, HIGH);

void setup(void)
 LcdString("Hello World!");

void loop(void)

Now I want to edit the font size,

so I can get from the code that this part
Code: [Select]
static const byte ASCII[][5] =
the number 5 in [5] describes the width of a font,

which part is controlling the height of the font..??


The bytes in the array are 8 bits each so I think the characters will be 8 lines high.  The top bit of each byte doesn't seem to be used (no values over 0x7F) so the glyphs are all 5x7.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp


The bytes in the array are 8 bits each so I think the characters will be 8 lines high.  The top bit of each byte doesn't seem to be used (no values over 0x7F) so the glyphs are all 5x7.

thank you for your reply..

I understand that now...

Now how do I change it to a 8x11 font size...??

I have an editor where I can create the 8x11 size..

like for 1 i have the code
0x00, 0x00, 0x0c, 0x06, 0xff, 0xff, 0x00

now when I replace the existing value for one with the new one and change the [5] in  "" static const byte ASCII[][5] = "" to [8]
the width is fine but I get the height till only 8 grid..

now how do I change the height to 11...??


The 5 dot width is hardwired to the code you provided. You can try to change LCDCharacter function. I don't have the spec sheet but I suspect the memory is organized with columns of 8 dots and doing it any other way (8X11) would be awkward. Give it a try modifying LCDCharacter. I don't have the display either.
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter


can someone plz help me understand this part form lcdcharacter..??

    LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  LcdWrite(LCD_D, 0x00);


Can someone please help me understand this part from LcdCharacter()..??

Code: [Select]

    LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  LcdWrite(LCD_D, 0x00);

Code: [Select]

void LcdCharacter(char character)
  LcdWrite(LCD_D, 0x00);  // Send a byte of all zeros to the LCD data register
  for (int index = 0; index < 5; index++)  // For each of 5 columns...
    LcdWrite(LCD_D, ASCII[character - 0x20][index]);  //  Send a column of the character to the LCD data register
  LcdWrite(LCD_D, 0x00);  // Send another byte of all zeros to the LCD data register

I expect what it is doing is drawing one blank column on either side of the five character columns.  That means that each character actually takes up 7 columns of dots.

If you want characters that are taller than 8 dots you will have to draw them 8 lines at a time.  If you want a font that is 11 dots tall you will have to draw the top 8 rows, re-position the LCD address to the start of the next row and draw the bottom 3 lines.  When you draw the bottom three lines you will also be drawing the top 5 lines of the next row.  Unless you know that the next row is blank you will need to merge the bottom three lines of the first row with the top five lines of the second row.

Good luck.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp


It is difficult to even write one character of 11 pixel tall since the lcd is likely addressed by a column of 8 pixels at a time. You will either have to read in from the display and do merge as John pointed out or have a display buffer in arduino memory, 504 bytes.
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter


Rendering fonts on GLCDs can get quite complicated especially when fonts
are not in exactly the same format as the glcd memory and
when not using a frame buffer.
I spent a few solid weeks writing the code in the glcd v3 library, but that library allows
any sized font and characters can be rendered and later scrolled on any pixel boundary.

The issue is that the current code in this library is too simple to support other sized fonts.
It assumes a 5x7 fixed width font which consumes
7 wide x 8 tall pixels when rendered. When using a vertical paged based glcd, things start to get really tricky
when trying to render fonts that are not exactly a page size when rendered or whenever the character font
data spans glcd memory pages.
The current code can get away with just slamming out the 5 font data bytes to render each column of the font
because the font data is stored in the same way the pixels in glcd memory are positioned *and* the characters
are always rendered on a page (multiple of 8 pixels) boundary.
(font data format of 8 bits with bit 0 being the top most pixel in the 8 pixel column/page)
Notice that bit 7 of the data is never set.
This will give a blank pixel below the rendered character to provide a gap between the lines of text.
If the font is no longer exactly 8 bits tall, or you want to render the character on pixel
boundaries that are not glcd memory page boundaries you can no longer do this and the code
must get a whole lot smarter.

My suggestion, while it may not be exactly what you want, is to
create a 9x14 or 9x15 font that takes up 10x16 pixels when rendered
and things get much simpler, as now the fonts are page aligned.
So now the rendering can work very similar to what is already there
by simply slamming out font data bytes but instead of just slamming out the 5 bytes
you slam out 5, reset the position to the page below where the first byte was written and then slam out
the next 5 bytes.

Alternatively, you could modify the code to have a
say a "wide" mode or a "tall" mode or perhaps both.
These modifications are much simpler modifications to the code than modifying it to support
variable height (or variable width fonts) and do not require any new font data.
You merely change the way you paint the same 5x7 font data.
It doesn't look as pretty as a true bigger font but it is smaller/simpler code than supporting
variable sized fonts.

For example to do a wide mode, you simply duplicate each font data byte, (write each byte twice rather than once).
This gives you a fatter/bolder font.
To do a tall mode, you do the same vertically but it is a bit more complicated in that you
duplicate the nibbles across two vertical bytes in glcd memory.

So for the upper half of the font, you take the lower nibble from each byte and turn it into a 8 bit byte
by duplicating each bit in the nibble to create an 8 bit byte.
Then you reset the position back to the position of where the character started rendering
and do it again for the upper nibble.

And for tall & wide you do both of the operations at the same time.

Not exactly what you what you were asking for or wanting but it is much simpler than
trying to update the code for supporting variable height fonts.
And you get 4 fonts out of one set of font data. (normal, wide, tall, wide&tall).

Hope that gives you some ideas.

--- bill

Go Up