GLCD library version 3 (end of life - no longer supported)

I'm developing a shunting program for our model railway. For years it ran on a PC / laptop but when I heard about Arduino's I had the idea to use those instead. Instant on and a separate display for each operator. The only downer is that on the PC we had plenty of width to display the full wagon name and other stuff such and colour, style etc.

Using Arduino Megas and ks0108 / GLCD and SystemFont5x7 I can get 21 characters and 8 rows. However that leads wagon names abbreviated / truncated, so I hacked at SystemFont5x7 to create Iain5x7 which is proportional (see below). This allows me to create more meaningful descriptions but I can't be sure that the text won't spill over the edge of the display. Since I need all 8 rows to display the list of wagons, any auto wrapping would ruin the display.

One of the displays also incorporates a matrix display to indicate the selected route be used in the goods yard. That display needs to be refreshed every 390us to avoid flicker, so I need to write each character to GLCD in less than 390us (preferably less since I also have to update the matrix as well in that 390us). From my tests, some characters take longer to write than others. From your previous post I believe this is related to the font definition :frowning:

#include <fonts/Iain5x7.h>
#include <fonts/SystemFont5x7.h>
#include <glcd.h>

void setup()
{
    uint32_t start, stop;

    Serial.begin(115200);
    GLCD.Init(NON_INVERTED);
    GLCD.ClearScreen();
    GLCD.SelectFont(Iain5x7);
    //GLCD.SelectFont(SystemFont5x7);
    for (uint8_t i = 0; i < 95; i++)
    {
        char ch = i + 33;

        GLCD.CursorToXY(0, 0); // Ensure each character doesn't wrap.
        start = micros();
        GLCD.write(ch);
        stop = micros();
        Serial.write(ch);
        Serial.print("(");
        Serial.print(ch);
        Serial.print("): ");
        Serial.print(stop - start);
        Serial.println("us");
        delay(100);
    }
}

void loop(
    void)
{
}

and here's my font (Iain5x7.h)

#ifndef IAIN5X7_H_INCLUDED
#define IAIN5X7_H_INCLUDED


/*
 *
 * Iain5x7
 *
 * created with FontCreator
 * written by F. Maximilian Thiele
 *
 * http://www.apetech.de/fontCreator
 * me@apetech.de
 *
 * File Name           : Iain5x7.h
 * Date                : 28.12.2010
 * Font size in bytes  : 2461
 * Font width          : 5
 * Font height         : 7
 * Font first char     : 32
 * Font last char      : 128
 * Font used chars     : 96
 *
 * The font data are defined as
 *
 * struct _FONT_ {
 *     uint16_t   font_Size_in_Bytes_over_all_included_Size_it_self;
 *     uint8_t    font_Width_in_Pixel_for_fixed_drawing;
 *     uint8_t    font_Height_in_Pixel_for_all_characters;
 *     unit8_t    font_First_Char;
 *     uint8_t    font_Char_Count;
 *
 *     uint8_t    font_Char_Widths[font_Last_Char - font_First_Char +1];
 *                  // for each character the separate width in pixels,
 *                  // characters < 128 have an implicit virtual right empty row
 *
 *     uint8_t    font_data[];
 *                  // bit field of all characters
 */

#include <inttypes.h>
#include <avr/pgmspace.h>

// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
#endif

#define IAIN5X7_WIDTH 5
#define IAIN5X7_HEIGHT 7

static uint8_t Iain5x7[] PROGMEM = {
    0x09, 0x9D, // size
    0x05, // width
    0x07, // height
    0x20, // first char
    0x60, // char count

    // char widths
    0x01, 0x01, 0x03, 0x05, 0x05, 0x05, 0x05, 0x01, 0x02, 0x02,
    0x05, 0x03, 0x01, 0x02, 0x01, 0x03, 0x04, 0x02, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x03, 0x03,
    0x03, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x03, 0x04, 0x05, 0x03, 0x05, 0x05, 0x05, 0x04, 0x05,
    0x04, 0x04, 0x03, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x02,
    0x03, 0x02, 0x03, 0x03, 0x01, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x01, 0x03, 0x04, 0x01, 0x05, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x05, 0x03, 0x04,
    0x04, 0x03, 0x01, 0x03, 0x05, 0x00,

    // font data
    0x00, // 32
    0xBE, // 33
    0x0E, 0x00, 0x0E, // 34
    0x28, 0xFE, 0x28, 0xFE, 0x28, // 35
    0x48, 0x54, 0xFE, 0x54, 0x24, // 36
    0x46, 0x26, 0x10, 0xC8, 0xC4, // 37
    0x6C, 0x92, 0xAA, 0x44, 0xA0, // 38
    0x06, // 39
    0x3C, 0x42, // 40
    0x42, 0x3C, // 41
    0x00, 0x54, 0x38, 0x54, 0x00, // 42
    0x10, 0x38, 0x10, // 43
    0xC0, // 44
    0x10, 0x10, // 45
    0x40, // 46
    0xC0, 0x38, 0x06, // 47
    0x7C, 0x82, 0x82, 0x7C, // 48
    0x04, 0xFE, // 49
    0xC4, 0xA2, 0x92, 0x8C, // 50
    0x82, 0x92, 0x92, 0x6C, // 51
    0x30, 0x28, 0x24, 0xFE, // 52
    0x4E, 0x92, 0x92, 0x72, // 53
    0x78, 0x94, 0x92, 0x60, // 54
    0x02, 0xE2, 0x12, 0x0E, // 55
    0x6C, 0x92, 0x92, 0x6C, // 56
    0x0C, 0x92, 0x52, 0x3C, // 57
    0x6C, // 58
    0x6C, // 59
    0x10, 0x28, 0x44, // 60
    0x28, 0x28, 0x28, // 61
    0x44, 0x28, 0x10, // 62
    0x04, 0xA2, 0x12, 0x0C, // 63
    0x64, 0x92, 0xF2, 0x82, 0x7C, // 64
    0xFC, 0x22, 0x22, 0xFC, // 65
    0xFE, 0x92, 0x92, 0x6C, // 66
    0x7C, 0x82, 0x82, 0x44, // 67
    0xFE, 0x82, 0x82, 0x7C, // 68
    0xFE, 0x92, 0x92, 0x82, // 69
    0xFE, 0x12, 0x12, 0x02, // 70
    0x7C, 0x82, 0xA2, 0x64, // 71
    0xFE, 0x10, 0x10, 0xFE, // 72
    0x82, 0xFE, 0x82, // 73
    0x40, 0x80, 0x80, 0x7E, // 74
    0xFE, 0x10, 0x28, 0x44, 0x82, // 75
    0xFE, 0x80, 0x80, // 76
    0xFE, 0x04, 0x08, 0x04, 0xFE, // 77
    0xFE, 0x08, 0x10, 0x20, 0xFE, // 78
    0x7C, 0x82, 0x82, 0x82, 0x7C, // 79
    0xFE, 0x12, 0x12, 0x0C, // 80
    0x7C, 0x82, 0xA2, 0x42, 0xBC, // 81
    0xFE, 0x32, 0x52, 0x8C, // 82
    0x4C, 0x92, 0x92, 0x64, // 83
    0x02, 0xFE, 0x02, // 84
    0x7E, 0x80, 0x80, 0x7E, // 85
    0x3E, 0x40, 0x80, 0x40, 0x3E, // 86
    0xFE, 0x40, 0x30, 0x40, 0xFE, // 87
    0xC6, 0x28, 0x10, 0x28, 0xC6, // 88
    0x06, 0x08, 0xF0, 0x08, 0x06, // 89
    0xC2, 0xA2, 0x92, 0x8A, 0x86, // 90
    0xFE, 0x82, // 91
    0x06, 0x38, 0xC0, // 92
    0x82, 0xFE, // 93
    0x04, 0x02, 0x04, // 94
    0x80, 0x80, 0x80, // 95
    0x06, // 96
    0x40, 0xA8, 0xA8, 0x70, // 97
    0x7E, 0x90, 0x88, 0x70, // 98
    0x70, 0x88, 0x88, 0x50, // 99
    0x70, 0x88, 0x90, 0x7E, // 100
    0x70, 0xA8, 0xA8, 0x30, // 101
    0x10, 0xFC, 0x12, 0x04, // 102
    0x10, 0xA8, 0xA8, 0x78, // 103
    0xFE, 0x10, 0x08, 0xF0, // 104
    0xFA, // 105
    0x40, 0x80, 0x7A, // 106
    0xFE, 0x20, 0x50, 0x88, // 107
    0xFE, // 108
    0xF8, 0x08, 0x30, 0x08, 0xF0, // 109
    0xF8, 0x10, 0x08, 0xF0, // 110
    0x70, 0x88, 0x88, 0x70, // 111
    0xF8, 0x28, 0x28, 0x10, // 112
    0x10, 0x28, 0x28, 0xF8, // 113
    0xF8, 0x10, 0x08, 0x10, // 114
    0x90, 0xA8, 0xA8, 0x48, // 115
    0x08, 0x7E, 0x88, 0x40, // 116
    0x78, 0x80, 0x40, 0xF8, // 117
    0x78, 0x80, 0x78, // 118
    0x78, 0x80, 0x60, 0x80, 0x78, // 119
    0xD8, 0x20, 0xD8, // 120
    0x18, 0xA0, 0xA0, 0x78, // 121
    0xC8, 0xA8, 0xA8, 0x98, // 122
    0x10, 0x6C, 0x82, // 123
    0xEE, // 124
    0x82, 0x6C, 0x10, // 125
    0x10, 0x08, 0x10, 0x20, 0x10, // 126

};

#endif

You might be interested in this bit that I added to stop the warnings:

// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
#endif

I think the Arduino team need to do the same thing to Tone.cpp in the library.

If you run the test you'll see that some of the letters are taking a bit too long to display but I'm pretty sure we won't have a ~ in our wagon names (but you never know...).

Iain

You could switch to a wider display like a 192x64 to get longer names.
I picked up one of the JHD19264 displays off ebay for under $19 USD shipped.
They are not as tall so the characters are actually a bit smaller but you do
get quite a bit more pixels and characters on the display.

You've got me curious on the timings now.
I'll load up your font and do some timings with my logic analyzer and see where the real time is lost.
(I can isolate things down the individual glcd library routine)
It is always a good exercise to see where the time is lost to ensure that any updates that are made
are made to the areas that matter the most.

Something else to think about is that
another one of the things I'm looking for 3.1 is support for the Chipkit UNO32 and MAX32 boards.
They are WAY faster than arduino 80Mz vs 16Mz, 32bit vs 8bit,
with more flash, more RAM and more pins and the chipkit UNO32 has a lower cost than the official Arduino UNO.
There are some differences that make it not suitable for a total drop in replacement, but so
far it looks very promising especially since the mpide it uses seamlessly supports AVR based arduinos
and Chipkit MIPS based boards so you can switch back and forth between the different boards using the same IDE.
(Maple's ARM based boards requires a different IDE and I'm not sure what the Arduino guys are going to do for Due)

I've already worked with one person to get a "hacked" version of v3 up and going on the ChipKit
but its not the way I want to do the code so I'll be updating things for the Chipkit boards in 3.1

--- bill

bperrybap:
You could switch to a wider display like a 192x64 to get longer names.
I picked up one of the JHD19264 displays off ebay for under $19 USD shipped.
They are not as tall so the characters are actually a bit smaller but you do
get quite a bit more pixels and characters on the display.

Sadly the hardware is already purchased and I'm using 4 screens, so replacement costs would be too high. I originally rejected the 192x64 screens because my brother didn't think he'd be able to read them. Thanks for the suggestion.

You've got me curious on the timings now.
I'll load up your font and do some timings with my logic analyzer and see where the real time is lost.
(I can isolate things down the individual glcd library routine)
It is always a good exercise to see where the time is lost to ensure that any updates that are made
are made to the areas that matter the most.

Indeed. I'm thinking about getting out my logic analyzer as well so I can pin down the timings in my own code more precisely.

If there's anything easy you can do to improve timings for a proportional font, I'd really appreciate it. Worst case, I can always revert to SystemFont5x7 and get faster timings if I can't make Iain5x7 work within my timing constraints.

Something else to think about is that
another one of the things I'm looking for 3.1 is support for the Chipkit UNO32 and MAX32 boards.
They are WAY faster than arduino 80Mz vs 16Mz, 32bit vs 8bit,
with more flash, more RAM and more pins and the chipkit UNO32 has a lower cost than the official Arduino UNO.
There are some differences that make it not suitable for a total drop in replacement, but so
far it looks very promising especially since the mpide it uses seamlessly supports AVR based arduinos
and Chipkit MIPS based boards so you can switch back and forth between the different boards using the same IDE.
(Maple's ARM based boards requires a different IDE and I'm not sure what the Arduino guys are going to do for Due)

I've already worked with one person to get a "hacked" version of v3 up and going on the ChipKit
but its not the way I want to do the code so I'll be updating things for the Chipkit boards in 3.1

Again Arduino Megas already purchased. It's a large project and I've got over 10 of the boards. I've bought Megas because most of my circuits require 50+ I/O. The board I'm currently concerned with only has 30 I/O but if I stick with one board, my code base can be used across all the boards. My one concession is the main scheduler software. I plan to use a Netduino so I can debug it easily and it's much easier to handle lots of strings in C# than C++. I actually was able to write most of the scheduler over Christmas using a simulator. What a great help it is to be able to debug something rather than insert trace statements.

Iain

sixeyes:

You've got me curious on the timings now.
I'll load up your font and do some timings with my logic analyzer and see where the real time is lost.
(I can isolate things down the individual glcd library routine)
It is always a good exercise to see where the time is lost to ensure that any updates that are made
are made to the areas that matter the most.

Indeed. I'm thinking about getting out my logic analyzer as well so I can pin down the timings in my own code more precisely.

If there's anything easy you can do to improve timings for a proportional font, I'd really appreciate it. Worst case, I can always revert to SystemFont5x7 and get faster timings if I can't make Iain5x7 work within my timing constraints.

Well, I did have a look. There really isn't anything that is "easy". What you are seeing is mainly the inefficiency of the
variable font format itself. (there are much faster ways to store and lookup the font data but it does require a bit more flash space)
With the current variable font format, to locate the data position for a character you have to
to add up the width of each previous character in the font. It is time consuming, especially on a Harvard Architecture
chip like the AVR since you have to call access functions. That is why you see each character taking longer and longer
to render. Each lookup and font width add for each character along the way
adds about 3us or so to the overall rendering.
The MIPs (used on Chipkit) and ARM (used on Maple) architectures are Von Neumann so they can directly access data in flash
which would be little bit faster even if the clock rate were the same.
But the real issue is the font format itself.

There are few other things that could shave off 3-4 us here and there 2 or 3 times in the rendering
at the expense of using up a few bytes of ram for each text area,
but that won't solve the issue you are facing.

BTW, the call GLCD.CursorToXY(0,0) doesn't really reposition the glcd hardware.
It only saves the coordinates for later. The actual hardware positioning is not done until a character is rendered.
So you are measuring the time for that as well. You can print the character an additional time before your micros() call
if you want to eliminate that positioning overhead. It is 3-4us or so.

One thing that you could do is create a more limited font that has say just the characters
from 'A' to 'z'. 0x41 to 0x7A
That way the flash width scans are shorter.
I tried this out and it reduces the render times around 40-80us on my setup.
40us being for 'A' and 80us shorter for 'z'.
So I see 156us for 'A' and 260us for 'z'.
But that eliminates and the numbers which may not be acceptable.
Note: you can use multiple fonts at the same time by
using a different font in each text area.
If you can use the shorter/smaller font you could use that font
for some text areas while the full font or even the system5x7 font could be used in other text areas.

Again Arduino Megas already purchased. It's a large project and I've got over 10 of the boards. I've bought Megas because most of my circuits require 50+ I/O.
Iain

10 boards of 50+ i/o. Thats A LOT of i/o!
What all is going on? This is for toy/model railroad stuff?
Can you shift any of your time critical code sections
to use interrupts so that it can interrupt the glcd library code?
The glcd library has no timing requirements and can be interrupted literally forever.

--- bill

bperrybap:
BTW, the call GLCD.CursorToXY(0,0) doesn't really reposition the glcd hardware.
It only saves the coordinates for later. The actual hardware positioning is not done until a character is rendered.
So you are measuring the time for that as well. You can print the character an additional time before your micros() call
if you want to eliminate that positioning overhead. It is 3-4us or so.

I only added that call to stop the wrapping affecting the timing. I wasn't planning to use it in my code. Useful to know it was adding some time.

One thing that you could do is create a more limited font that has say just the characters
from 'A' to 'z'. 0x41 to 0x7A
That way the flash width scans are shorter.
I tried this out and it reduces the render times around 40-80us on my setup.
40us being for 'A' and 80us shorter for 'z'.
So I see 156us for 'A' and 260us for 'z'.
But that eliminates and the numbers which may not be acceptable.
Note: you can use multiple fonts at the same time by
using a different font in each text area.
If you can use the shorter/smaller font you could use that font
for some text areas while the full font or even the system5x7 font could be used in other text areas.

I think I'll try my font. If that's too slow, I'll try SystemFont5x7. If that's too limiting I'll look at writing my own font format to speed things up.

Again Arduino Megas already purchased. It's a large project and I've got over 10 of the boards. I've bought Megas because most of my circuits require 50+ I/O.
Iain

10 boards of 50+ i/o. Thats A LOT of i/o!
What all is going on? This is for toy/model railroad stuff?

Yes. I'm controlling points (I believe you may call them turnouts), detecting point positions, detecting locomotives, route planning, route selection, turntables etc.

Can you shift any of your time critical code sections
to use interrupts so that it can interrupt the glcd library code?
The glcd library has no timing requirements and can be interrupted literally forever.

I've considered it but I'd prefer to avoid them if possible.
Once I get a chance to hook up my logic analyzer I should be able to figure out what my options are.

Iain

lain,
There is one other thing that you can try.
The old/original rendering code is still in the gText.cpp module.
It is the original Thiele code for rendering fonts. It has many issues depending on the font size
and the y pixel boundary and when using inverse modes.
However, it does work for many cases, and should work fine for your font.
Since it is simpler, it is faster when the fonts are multiples of a page size.
I measured it as saving about 20us with your font.
You can try it by editing gText.cpp and uncommenting the #define GLCD_OLD_FONTDRAW

--- bill

bperrybap:
Well, I did have a look. There really isn't anything that is "easy". What you are seeing is mainly the inefficiency of the
variable font format itself. (there are much faster ways to store and lookup the font data but it does require a bit more flash space)
With the current variable font format, to locate the data position for a character you have to
to add up the width of each previous character in the font. It is time consuming, especially on a Harvard Architecture
chip like the AVR since you have to call access functions. That is why you see each character taking longer and longer
to render. Each lookup and font width add for each character along the way
adds about 3us or so to the overall rendering.

I think it would be well worth using 1 additional byte of flash per character by ditching the byte count and instead having a table of pointers to the start of the data for each character, plus one extra pointer to enable the byte count of the last character to be calculated.

As a short term improvement, you could consider caching the address of the data for the character that is half way through the table, giving you an alternative place to start searching from.

dc42:

bperrybap:
Well, I did have a look. There really isn't anything that is "easy". What you are seeing is mainly the inefficiency of the
variable font format itself. (there are much faster ways to store and lookup the font data but it does require a bit more flash space)
With the current variable font format, to locate the data position for a character you have to
to add up the width of each previous character in the font. It is time consuming, especially on a Harvard Architecture
chip like the AVR since you have to call access functions. That is why you see each character taking longer and longer
to render. Each lookup and font width add for each character along the way
adds about 3us or so to the overall rendering.

I think it would be well worth using 1 additional byte of flash per character by ditching the byte count and instead having a table of pointers to the start of the data for each character, plus one extra pointer to enable the byte count of the last character to be calculated.

As a short term improvement, you could consider caching the address of the data for the character that is half way through the table, giving you an alternative place to start searching from.


I like the idea about having an offset value for a character that is half way through the table
This is an interesting idea that I may look further into as that can be calculated runtime and
saved in RAM as the font is selected. It also does not require modifying the existing font data format.


As far as font formats go, let me start of by saying I am not a fan of the current variable font data format.
Michael and I were painfully aware of its issues and limitations when we moved forward with it going into v3.
It existed before I started working on the glcd library and even before Michael converted
Thiele's original C library to C++ for Arduino.
There are other issues with the variable font data format that are also irritating and also cost time,
like the residual bits in a font data byte when the font is not exactly a multiple of 8 bits.
The bits in the font data are shifted the wrong direction for aligning with the glcd page byte.
(This is different from how bits are stored for fixed fonts and bitmaps)
This causes additional code and checks to have to be done, while rendering,
to detect when the last byte in a column is being rendered
and to shift the bits around when the font is a variable font and not a multiple of 8 bits in height.
Michael and I had some long discussions about changing the font data format to at least get rid of the incorrectly shifted bits.
I would be nice for rendering in that all the rendering would then
be the same whether the "glyph" was a fixed font, bitmap, or variable font.

The issue early on of the v3 development was that it would break compatibility with ks0108/glcd v2 library
since none of the v2 fonts would work and a major goal of v3 was backward compatibility with v2.

Having a new font format also means re-doing the fontcreator2 JAVA app to be able to generate the new format.
While its not that bad, we opted not to do that for v3.


With respect to the current variable font format, there is no "byte count" for each character.
The data byte for each character is the width of the given character. I assume that is what you meant.
(byte counts and widths are not the same for fonts that are taller than 8 pixels)
I didn't follow your comment about: "plus one extra pointer to enable the byte count of the last character to be calculated".
I assume you meant that the width could be replaced with 16 bit offset values.
And that the width could be back calculated fairly easily knowing the address of the "next" character
and the height of the font.
But it does require and offset value for a "next" character just after the real last character in the table.

Definitely worth considering going forward.

There is also the possibility of having the width and formatting information inside the "glpyh" data.
So the offsets point to a "glyph" and the glyph data has all the needed sizing and leading information
which is a closer match to some of the other font formats used in Operating systems.

I really want to get away from this font format. I also want to be able to either directly use BDF format or
write a small script/tool that can convert from BDF fonts to the embedded format.
That will instantly allow the creation of hundreds of fonts - which will ease the pain of people
having to deal with the loss of their existing font formats should the font data format be changed.
Yes it would be possible to support multiple formats, but that takes extra code since all the rendering for
all the formats would have to exist and be selected runtime
based on the font. It also adds to the maintenance and support load of the library.

There are several other issues such as the current way the font data is compiled & linked in that needs to be resolved.
Currently they are all "static" data arrays that are all compiled in and the linker removes
out the unused fonts.
This creates real problems for implementations that use more than a single source code module.
There are many ways to resolve this but most won't work with the Arduino IDE and its goofy way
of doing things.

I have many ideas and things that could be done, it is a matter of trying to pick the highest priority
items moving forward that can offer the best trade-off of new & improved functionality and backward compatibility.

--- bill

It becomes difficult to follow this HUGE thread, but let me allow to make some small notes.

BDF: Yes, i think BDF is an excellent source for fonts. It is easy to parse, there is a ttf to bdf converter (called OTF2BDF) and there are already very good open source BDF fonts in the X11 distribution: freedesktop.org git repository browser

Inner glyph offset: After profiling of my font format i found that the searching for the glyph data start position required a big fraction of the overall time for rendering. I added the offset of the lower case 'a' and the upper case 'A', to my font format, which was great speedup (about overall factor 2, if I remember correctly).

Fonts in PROGMEM area: A big issue. In principle one can place one font in one C file (did not check C++ files), declared with the PROGMEM attribute. All other parts of the program will only see the external declaration from some .h file, e.g.

extern uint8_t my_font_data[] PROGMEM;

For the linker to be able to remove the font from the final hex file, it is required to place all fonts in separate C files. Unfortunately this becomes impractical as soon as there are several hundred fonts.
Simply the compile time of the Arduino IDE gets very high. After several hours of investigation of the gcc garbage collector I found that it is possible to put all fonts into the same C file, if the font data are assigned to different progmem sections.
This will look like this:

extern uint8_t my_font_data1[] __attribute__ (( section(".progmem.font1") ));
extern uint8_t my_font_data2[] __attribute__ (( section(".progmem.font2") ));

Oliver

I needed help with the GLCD library version 3 I am also new to the Ardunio world, I have an KS0108 (B pin setup) it is labeled JHD521M7 12864AB ,

I have been trying to get work for about two weeks now , i have cross checked the wring more than 1001 ( I have Tomas Edison beat on this one) and I have also learned how to labeling all wires makes things easy , the GLCD work on my PIC so I know its good, however with the Arduiono there are no pixels displayed, I could adjust the contrast and the back light is working fine , and I have ran GLCDdiags and i got this

Diag Loop: 3
Initializing GLCD
GLCD initialization Failed: RESET wait Timeout (status code: 2)

the pins are configured right, so is there any one brave enough to help me

GLCD data sheet

http://www.itron.com.cn/PDF_file/JHD12864AB.pdf

Akim14,
I'll post answers in your other thread:

--- bill

Hello:

I am very new to the forum and the Arduino products. I have just purchased a Mega2650 and it comes with a 128x64 display. I have tested the board with LED bulb with "Blink" and it work. But I can never get even the blacklight of the Display works, it is black. I been searching for document and now come to this GLCD library topic and find the download here, Google Code Archive - Long-term storage for Google Code Project Hosting., should I download the file and add to my Arduino program. it also states in the readme file that a sketchbook directory, I don't have a sketchbook directory should I just create one.

anyway, I am try to do the first step, to make the display lit up. Oh, I have follow the Point B for setup the pins.

Thank you.

cc

The google site you have if for the GLCD library, that I'm maintaining.
glcd v3 RC3 is the latest version.
There is also some information about the older v2 version here:
http://www.arduino.cc/playground/Code/GLCDks0108

You actually do have a sketchbook directory.
Bring up the IDE and click on [File]->Preferences

You sketchbook directory can be anywhere you want.
The location that the IDE is looking for you sketchbook is
in the text box right there at the top of the "preferences" dialog.

Wherever that directory is, you will need to create a directory called
"libraries", then extract the zip image into that directory.
So you will end up with
{sketchbook directory}/libraries/glcd ....

Make sure you have properly identified the glcd type as incorrect wiring up the glcd
could damage the glcd or the Arduino board.

Make sure the datasheet that you have for you glcd module is for the glcd that you have
by verifying that the part number on the back of the glcd matches what is in the datasheet.

Some glcds have labeled pins but many do not, make sure you properly identify pin 1.

If you need help, just ask additional questions and I'll be happy to help.

--- bill

Thank you for your prompt reply.

I have made the LCD display lit up. It is blue now. I have installed the glcd in the sketchbook location.

I got message "Done compiling" and "Binary sketch size: 6108 bytes (of a 258048 byte maximum) after upload the sketch,
I used the "HelloWorld" and "GLCDdiags" files Under File of IDE, Sketchbook>libraries>glcd> both of them got the above messages and the green light on the board blinks with "HelloWorld" and stay green with "GLCDdiags". Please advise how can I made "Hello World" or anything dispaly on my LCD display.

thanks again.
cc

Diags reports information out the serial port.

Unless the glcd is bad, incorrect wiring is always the cause for the glcd not working properly.

Since the backlight is now working, you have changed something with the wiring.

Make sure that you have the correct data sheet and wiring up the glcd according to the datasheet
and the documentation included with the library.
Wiring is not something you want to be guessing
as incorrect wiring can damage the glcd or the Arduino board.

When things are not yet working. Use the diags sketch.
Until diags pass, there is no reason to try to run any other sketch.
Diags will display useful information on the serial port
about how the library is configured and any potential testing failures.

--- bill

Hi, Bill:

Thanks again.

Here is the datasheet I used to do the wiring
http://fritzing.org/projects/128x64-lcd/
I also read the the ks0108mega.h file
#define glcdDI 36 // D/I Bit
// Reset Bit - uncomment the next line if reset is connected to an output pin
#define glcdRES 30 // Reset Bit

it seems the only difference for the datasheet I used and those states at the config file is those I copied above, is there a difference of D/I bit and RS. My reset is 17 not 30, should I use 30 instead.

When I compile the sketch, do I need to disconnect the reset, let the sketch upload and connect the reset.

I have used the GLCDdiags and nothing happen to the LCD display. you mentioned about using the diag and until it pass, is this diag the same as the GLCDdiags sketch I used. When I compiled the GLCDdiags, other than the comment regarding the byte, there is no other information. You also said diag reports information out the serial port, where can I find the serial port, bear with me, I know it sounds kind of stupid.

thanks
cc

carrieklchow:
Hi, Bill:

Thanks again.

Here is the datasheet I used to do the wiring
128x64 LCD

That is not a data sheet. That is a wiring diagram.
A data sheet will show all the technical information about the lcd panel
and will have the pinout for the lcd panel.
There are many different pinouts for ks0108 glcds and if things are improperly hooked up
it can damage the glcd or the Arduino board.
That is why it is very important to locate a proper datasheet for a glcd to see
the functions for each of the 20 pins to ensure that the pin connections to the Arduino are correct.
Here is what a couple of ks0108 datasheets look like:
http://www.longtech-display.com/produts/LCD%20MODULES/longtech%20pdf/LGM12864B.pdf
http://docs.bgmicro.com/pdf/lcd1030.pdf

Pretty much all glcds have their model silk screened on the back of the board.
Look at the back of the board and you should see the lcd model.
It will usually have "12864" somewhere in the model name.
You can do a google search with the model name to locate a datasheet for the glcd.

I also read the the ks0108mega.h file
#define glcdDI 36 // D/I Bit
// Reset Bit - uncomment the next line if reset is connected to an output pin
#define glcdRES 30 // Reset Bit

it seems the only difference for the datasheet I used and those states at the config file is those I copied above, is there a difference of D/I bit and RS. My reset is 17 not 30, should I use 30 instead.

Sorry about any confusion here.
RS and DI are the same. Some data sheets call the pin RS and some call it DI.
They are the same thing.

The numbers like 36 for glcdDI and 30 for glcdRES are Arduino pin#s.
All the numbers you see in the glcd pin config files like ks0108_Mega.h are arduino pin #s.
Numbers like "17" for reset are the glcd pin number.

If you want the glcd library to control the reset signal on the glcd, you hook
the arduino pin number for glcdRES to the reset signal pin number on the glcd.
In your case that would be hooking up Arduino pin# 30 to glcd pin #17.
Make sense?

When I compile the sketch, do I need to disconnect the reset, let the sketch upload and connect the reset.

Unfortuantely there are some issues with AutoReset on certain Arduino boards
which can cause uploads to fail when the the Arduino reset line is hooked directly to the glcd
reset pin.
The real issue is that some glcd modules need a reset pulse and some don't.
On the glcds that don't need a reset some glcds can work with the glcd reset pin tied to vcc
as shown in your wiring diagram. Some glcds will work when the glcd reset signal is left unconnected.

For the glcds that need a reset pulse the problem is that
some Arduino boards will not auto reset if the glcd reset pin is hooked up to the Arduino board reset pin.
For those glcds you must control the glcd with an arduino pin.

The safest thing to do at this point would be to eliminate any potential reset issue by letting
the library control the reset pin.
To do that you uncomment the line like you did and then hook Arduino pin 30 to the glcd reset signal pin.

After the glcd is working, if you don't want to use an arduino pin to reset the glcd, you can
try connecting the glcd reset pin to VCC instead. But if you do that make sure to go into the
ks0108_Mega.h header file and comment out the glcdRES line to make sure the glcd library
does not try to use the pin.

I have used the GLCDdiags and nothing happen to the LCD display. you mentioned about using the diag and until it pass, is this diag the same as the GLCDdiags sketch I used.

Yes sorry about my wording.

When I compiled the GLCDdiags, other than the comment regarding the byte,

"byte"? Not sure what you mean by this.

there is no other information. You also said diag reports information out the serial port, where can I find the serial port, bear with me, I know it sounds kind of stupid.

In the IDE if you click on the serial monitor icon, it will bring up the serial monitor.
Set the baud rate to 9600 and you will see the diagnostic messages from the GLCDdiags sketch.

If you post the information from diags, it will help to diagnose what is happening.

--- bill

Hi, Bill:

thanks a lot.

I have checked the wiring with datasheet, the board is SG12864J4. I have followed the pinoutB from this link :Arduino Playground - GLCDks0108

I have complied the GLCDdiags again, and here is the information from the Serial Monitor, I can only read that is a problem with the initialization of the GLSD and issue of reset. I don't know how to fix it.

Following is an extract the information from the serial monitor, it doesn't allow me to cut and paste and I just typed it out.

Reported Arduino Revision: 1.0

GLCD Lib Confirguration: glcd ver: 3 dlrd_Device ver: 1 gText ver: 1
GLCD Lib build date: Mon Dec 5 10:50:07 CST 2011
GLCD Lib build number: 442
panel Configuration:ks0108
pin Configuration:ks0108-Mega

GLCD:ks0108 DisplayWidth:128 DisplayHeight:64
Chips:2 ChipWidth:64 ChipHeight:64
CSEL1:33 (PIN_C4) CSEL2:34 (PIN_C3)
RW:35 (PIN_C2) DI:36 (PIN_C1) EN:37(PIN_C0)
DO:22 (PIN_A0) D1:23 (PIN_A1) D2:24 (PIN_A2) D3:25 (PIN_A3)
D4:26 (PIN_A4) D5:27 (PIN_A5) D6:28 (PIN_A6) D7:29 (PIN_A7)
Delays: tDDR:320 tAS:140 tDSW200 twH:450 twL:450
ChipSelects: CHIP0: (33, 0x1, 34, 0x0) CHIP1: (33, 0x4, 34, 0x1)
Date mode: byte

Diag Loop: 9
Initializing GLCD
GLCD initialization failed: RESET wait Timeout (status code: 2)

Can you teach me how to cut and paste from the serial monitor. BTW, I tried to open the Mega.h file but I cannot open it from my file directory, i.e. users/xxxxx/Document, how can I modify the .h file. I know probably in the future I need to uncomment the reset or change the file.

thanks again
have a nice weekend.
cc

You can copy and paste from the terminal window.
Just highlight the text in the terminal window,
then move to the window where you want to paste it and click the middle mouse button
to paste the highlighted text.

See this thread for some information about that error:

(ignore his information and just scroll down to my explanation of the error)

That error is always due to a wiring error.
Look at the diag output and wire up the glcd panel according the pins you see in the output.

You can see that glcd RW should be hooked up to arduino 35
glcd DI to Arduino 36
glcd CS1 to Arduino 33
glcd D4 to Arduino 26
etc...
Make sure that the wiring to the glcd is using the reported arduino pins for each glcd function.

Make sure you pot is wired correctly:

----- GND
------------------------------------- Vo (glcd pin 3)
----- Vee (glcd pin 18)

I don't know what you mean by this:

BTW, I tried to open the Mega.h file but I cannot open it from my file directory, i.e. users/xxxxx/Document, how can I modify the .h file. I know probably in the future I need to uncomment the reset or change the file.

I assume you mean {sketchbook directory}/libraries/glcd/config/ks0108_Mega.h ?
You showed some text from that file in your previous posts. Can't you open the file for editing using your favorite
text editor

--- bill

Good Day, Bill:

Thank you so much. The GLCDdiags finally works :slight_smile:

cc