lcd display character set factory

Previous examples connect the white LED backlight to power. The following example is specifically for those using an LCD with a RGB LED backlight. The only difference between the connection is the LED"s backlight on pins 15-18.

After uploading, you will notice the same "Hello, world!" and time since the Arduino was last reset in the first example. The only difference is that the current color of the backlight will be printed as it cycles through each of the primary, secondary, and tertiary colors. You should see something similar to the image below.

lcd display character set factory

This is not official manufacturer"s information. It is distilled from information on many different data sheets and from my own experience. I have never used some of these displays. I have extrapolated what I know about the displays that I have used to the ones that I have just read about. I welcome any suggestions and corrections. Contact information is at the bottom of the page.

The HD44780 type controller chip is used with a wide variety of Liquid Crystal Displays. These LCDs come in many configurations each with between 8 and 80 viewable characters arranged in 1, 2, or 4 rows.

The problem is that there is no way to inform the controller of the configuration of the display that it is driving. The controller operates exactly the same way for all displays and it is up to the programmer of the device that is controlling the LCD controller (usually a host microcontroller) to deal with this situation.

The controller contains 80 bytes of Display Data Random Access Memory which is usually referred to as DDRAM. When the controller is used with a 40 x 2 display (forty characters on each of two rows) the operation is quite straightforward and that operation will be explained first. Each of the other configurations introduces one or more quirks so it is best to understand the operation of the 40 x 2 before proceeding to the description of the operation of any of the others.

Each of these DDRAM memory addresses corresponds to a character position on an attached display, but the specific position varies depending on the configuration of that display. As part of the initialization sequence the display is cleared by storing the ASCII code for a space in each of the 80 memory locations. Subsequently if a different ASCII code is stored in any of those memory locations then the character corresponding to that ASCII code is automatically displayed at a specific location on the display.

You can tell the controller where you want the first ASCII character that you send it to be stored, this is usually address 00h. After receiving that character it will automatically update its address pointer and put the next ASCII character you send into an adjacent memory location with no more addressing work on your part. You can specify whether to increment or decrement the address counter but normally it is incremented, so the next character will be put into address 01h. The LCD controller automatically accounts for the gap in addresses and after storing an ASCII code in address 27h it puts the next code in address 40h. Similarly it increments from address 67h back to 00h.

Here is a simplified diagram of the display on a 40 x 2 LCD Module. Each of the boxes in the diagram represents a location where a character can be displayed.

Here is a copy of the memory map of the controller. Remember, each of the memory locations in the controller chip is directly associated with one of the character locations on the display.

By some miracle of modern technology there is actually a one for one relationship between these two diagrams. If an ASCII code is stored at address 00h in memory the corresponding character will appear at the left end of the top row of the display. If an ASCII code is stored at address 63h in memory the corresponding character will appear five locations in from the right end of the second row of the display.

Here is a diagram showing how the two rows of the display are mapped into the two lines of memory. It is basically a combination of the two diagrams just above.

When the host controller wants to display a string of characters on the display all it has to do is specify a starting DDRAM address and then start sending the string of ASCII codes corresponding to the desired characters to the LCD controller, one after another. The LCD controller takes the first code that it receives, stores it at the specified address, and simultaneously displays the corresponding character on the display. It then increments it"s internal address counter and stores the next ASCII code that it receives in the next DDRAM location which causes the corresponding character to appear in the next location on the display. As mentioned before the LCD controller automatically accounts for the gap in addresses and after storing an ASCII code in address 27h it puts the next code in address 40h. Similarly it increments from address 67h back to 00h.

This display also has 80 characters, but the relationship between the DDRAM addresses and the character locations on the LCD is not quite as straightforward as the LCD with two rows of 40 characters. Here is a diagram of the device.

The memory map is always the same regardless of the display configuration, but in this drawing I have shown a small space between addresses 13h and 14h on the first line and another between addresses 53h and 54h on the second line.

Here is the same memory map, rearranged this time to show how the memory addresses relate to the character positions on a 20 x 4 LCD. Note how the right half of the previous diagram is now below the left half and note the resulting sequence of starting addresses for each display row (00h, 40h, 14h, 54h).

Remember that the LCD controller still considers this to be two lines of RAM. It is important to understand that this way of picturing the DDRAM addresses helps relate the memory addresses to the character locations but does not change the fact that as far as the controller is concerned there are only two lines of memory. In other words, although this diagram shows the DDRAM differently than before, the actual DDRAM configuration and operation is exactly the same as described above for the 40 x 2 display since there is no way of telling the LCD controller that there are now 4 rows of 20 characters instead of 2 rows of 40 characters.

When a long string of ASCII codes is sent to this LCD controller the action is not quite as simple as for the 40 x 2 display. After the first row is full the characters will continue on to the third row. The normal automatic incrementing from 27h to 40h will then cause the display to continue on the second row, and from there it will continue to the fourth row. After that the following characters will appear back on the first row, and so on.

In order to get a coherent display on sequential rows it is necessary to compensate for the design of the LCD controller when programming the host microcontroller. Basically the program on the host microcontroller can keep track of the DDRAM addresses, and when appropriate it can set up a new starting DDRAM address.

For each of the above displays there are 80 addresses in memory and there are 80 character locations on the display so it should be obvious that any time you send an ASCII code to the controller the corresponding character will show up somewhere on the display. If you mess up the address the character may not show up where you expected it, but it will be visible somewhere. If you work back from where it actually appears you can usually figure out where you made your mistake. All of the displays that follow have fewer character locations on the display than memory addresses in the controller. This makes the operation somewhat more complicated and troubleshooting more difficult.

This can be thought of as a truncated 40 x 2 display, but there are some ramifications of this truncation that may not be readily apparent. Here is a drawing of the device.

It is important to understand that, although this diagram shows only the part of the DDRAM that is normally used to display information on the 20 x 2 LCD, the actual memory map and controller operation is exactly the same as described above for the previous displays. Again that is because there is no way of telling the LCD controller that there are only 40 characters on the attached display.

Here is a drawing of the complete memory map. Note that this drawing is the same as the one for the 20 x 4 display except that the addresses on the right side are greyed out.

Although this display has only 40 characters there are still 80 bytes of DDRAM and they are still configured the same as they were before. The greyed out addresses are the locations in DDRAM that do not have corrresponding locations on the display. Any ASCII codes that are written to those locations are not lost, and it is possible to display them by "shifting" the display window, but in normal use as described here they are simply not displayed.

When a long string of ASCII codes is sent to this LCD controller the action is not quite as simple as for either of the 80 character displays. Assume that the host controller is sending a string of characters as described above. Consider what happens after the LCD controller stores an ASCII code in address 13h and displays the corresponding character at the right end of the top row on the LCD. It then stores the next ASCII code in address 14h, which has no corresponding location on this 20x2 display. As more ASCII codes are sent to the LCD controller they are stored in the DDRAM but do not appear on the display until the LCD controller finally increments it"s address counter from 27h to 40h at which time subsequent characters start to appear on the second row of the display. As far as a viewer of the display is concerned there is a gap of 20 missing characters. The same thing will happen on the second row when ASCII codes are stored in addresses 54h - 67h.

In order to prevent any missing characters the program on the host microcontroller can keep track of the DDRAM addresses, and when appropriate it can set up a new starting DDRAM address. On the other hand the display can be shifted to display those missing characters, but the techniques to do that will not be covered here.

This is a commonly found configuration and its operation is almost identical to that of the 20 x 2. The relationship between the DDRAM addresses and the character locations on the LCD is a subset of the example shown above. Here is a drawing of the device.

Once again it is important to understand that although this diagram shows only the part of the DDRAM that is normally used to display information on the 16 x 2 LCD the actual DDRAM configuration and operation is exactly the same as described above for the 40 x 2 display. This is because there is no way of telling the LCD controller that there are only 32 characters on the attached display.

Here is a drawing of the complete memory map. Note that this drawing is the same as the one for the 20 x 2 display except that a different range of addresses on the right side are greyed out.

The operation of this display when a long string of characters is sent to it is that same as described for the 20 x 2 display except that there is a gap of 24 missing characters at the end of each line (instead of 20).

There are actually two different varieties of 16 x 1 LCD displays and the initialization and operation of each is different so it is important to determine which one you have.

When power is first applied to any of the multi-row LCD modules and before the controller is initialized you will see that the character locations corresponding to the first line of memory are dark and the others are light (assuming that the contrast adjustment is properly set). If you apply power to a 16 x 1 LCD module and only the left 8 character locations are dark you have what I will call a type 1 module. If only the right 8 character locations are dark this is also a type 1 module but it is upside down! If all 16 character locations are dark then it is what I will call a type 2 module. This is my own terminology used only for the purpose of keeping them differentiated while describing their operation. The type 1 modules will have only one IC on the back of the pcb while the type 2 will have 2 (I guess this tidbit gives away the source of my "type" designations). This distinction may apply to newer devices with epoxy blobs instead of ICs, but I believe that sometimes one blob may cover more than one equivalent IC function.

From this you can see that although the display has only a single row of characters, as far as the LCD controller is concerned it is using two lines of memory and it must be considered to be a 2 line device when initializing the controller.

Here is a drawing of the complete memory map. Note that this drawing is the same as the one for the 20 x 2 and 16 x 2 displays except that a different range of addresses on the right side are greyed out.

Here you can see that if the host controller sends a long string of characters without periodically adjusting the DDRAM starting address then after each 8 characters are displayed the next 32 will "disappear".

Also, to display a message of more than 8 characters on the 16 character display the host controller will have to readjust the DDRAM address after displaying the first 8 characters.

Here is a drawing of the complete memory map. Note that this memory map is different than all of the previous ones. This is the only device described here that is a true "one-line" display (see note 2) and as such it has a different memory map.

Here you can see that if the host controller sends a long string of characters after the first 16 characters are displayed the next 64 will "disappear".

At the expense of an extra IC you get some slightly easier programming since, in order to display a message of more than 8 characters on the 16 character display, the host microcontroller does not have to readjust the DDRAM address after displaying the first 8 characters.

Since only one line of memory is in use this LCD module should be configured as a 1-line device. As far as I can determine, this changes the multiplex frequency which changes the display brightness and/or contrast. Also, there are some single row LCDs that are capable of displaying a larger 5x10 font instead of the more common 5x7 font.

I"ve stuck this description toward the end because, as you will see, it has some of the characteristics of the 40 x 4 and some of the characteristics of the 16 x 2. Here is a drawing of the device.

Here is the same memory map, rearranged this time to show how the memory addresses relate to the character positions on a 16 x 4 LCD. Note how the center of the previous diagram is now below the left part, the right part is missing, and the resulting sequence of starting addresses for each display row is different than for the 20 x 4 (00h, 40h, 10h, 50h).

Here you can see that if the host controller sends a long string of characters without periodically adjusting the DDRAM starting address then after the first row is full the characters will continue on to the third row. After the third row is full the next eight characters "disappear". The normal automatic incrementing from 27h to 40h will then cause the display to continue on the second row, and from there it will continue to the fourth row. After the fourth row is full the next eight characters will "disappear" and then it"s back to the first row.

The 40 x 4 LCD is treated essentially as two 40 x 2 devices stacked one on top of another in the same glass enclosure. Electrically it uses what amounts to two HD44780 controller chips and it therefore has two separate memory maps each with the same address range. One is used for the top two lines and the other is used for the bottom two lines. The memories are accessed individually by strobing the desired Enable pin of which there are now two. Here is a diagram of the device.

To display a really long string of characters on this display the host controller would start out just like it did for the 40 x 2 display. It would specify a starting DDRAM address (typically 00h) and then start sending the string of ASCII codes corresponding to the desired characters to the LCD controller, one after another, making sure to strobe the enable pin associated with the upper memory bank.   After storing an ASCII code in address 67h the LCD controller will automatically increment to address 00h as before and at this time the host controller must stop strobing the enable pin for the upper bank and start strobing the one for the lower bank.

There are other LCD configurations available but I believe that any of them can be handled by a technique similar to one of the examples above. If you have a display that seems to be considerably different from any of these I would like to hear from you.

(1) The mysterious gap is due to considerations resulting from the multiplexing of the display.   The DDRAM addressing uses seven bit addressing and the highest bit signifies which row of memory is involved.   If you compare the addresses in the first row with those just below in the second row you will see that the only difference is in that one bit.

(2) As implied above the number of rows of characters that can be displayed on the LCD is not the same as the number of lines of memory used by its controller.   Only some of the 16x1 displays use "one line" of memory, all of the other displays including most 16x1 displays, use "two lines" of memory.

lcd display character set factory

If you’ve ever tried to connect an LCD display to an Arduino, you might have noticed that it consumes a lot of pins on the Arduino. Even in 4-bit mode, the Arduino still requires a total of seven connections – which is half of the Arduino’s available digital I/O pins.

The solution is to use an I2C LCD display. It consumes only two I/O pins that are not even part of the set of digital I/O pins and can be shared with other I2C devices as well.

True to their name, these LCDs are ideal for displaying only text/characters. A 16×2 character LCD, for example, has an LED backlight and can display 32 ASCII characters in two rows of 16 characters each.

If you look closely you can see tiny rectangles for each character on the display and the pixels that make up a character. Each of these rectangles is a grid of 5×8 pixels.

At the heart of the adapter is an 8-bit I/O expander chip – PCF8574. This chip converts the I2C data from an Arduino into the parallel data required for an LCD display.

If you are using multiple devices on the same I2C bus, you may need to set a different I2C address for the LCD adapter so that it does not conflict with another I2C device.

An important point here is that several companies manufacture the same PCF8574 chip, Texas Instruments and NXP Semiconductors, to name a few. And the I2C address of your LCD depends on the chip manufacturer.

So your LCD probably has a default I2C address 0x27Hex or 0x3FHex. However it is recommended that you find out the actual I2C address of the LCD before using it.

Connecting an I2C LCD is much easier than connecting a standard LCD. You only need to connect 4 pins instead of 12. Start by connecting the VCC pin to the 5V output on the Arduino and GND to ground.

After wiring up the LCD you’ll need to adjust the contrast of the display. On the I2C module you will find a potentiometer that you can rotate with a small screwdriver.

Plug in the Arduino’s USB connector to power the LCD. You will see the backlight lit up. Now as you turn the knob on the potentiometer, you will start to see the first row of rectangles. If that happens, Congratulations! Your LCD is working fine.

To drive an I2C LCD you must first install a library called LiquidCrystal_I2C. This library is an enhanced version of the LiquidCrystal library that comes with your Arduino IDE.

The I2C address of your LCD depends on the manufacturer, as mentioned earlier. If your LCD has a Texas Instruments’ PCF8574 chip, its default I2C address is 0x27Hex. If your LCD has NXP Semiconductors’ PCF8574 chip, its default I2C address is 0x3FHex.

So your LCD probably has I2C address 0x27Hex or 0x3FHex. However it is recommended that you find out the actual I2C address of the LCD before using it. Luckily there’s an easy way to do this, thanks to the Nick Gammon.

But, before you proceed to upload the sketch, you need to make a small change to make it work for you. You must pass the I2C address of your LCD and the dimensions of the display to the constructor of the LiquidCrystal_I2C class. If you are using a 16×2 character LCD, pass the 16 and 2; If you’re using a 20×4 LCD, pass 20 and 4. You got the point!

First of all an object of LiquidCrystal_I2C class is created. This object takes three parameters LiquidCrystal_I2C(address, columns, rows). This is where you need to enter the address you found earlier, and the dimensions of the display.

In ‘setup’ we call three functions. The first function is init(). It initializes the LCD object. The second function is clear(). This clears the LCD screen and moves the cursor to the top left corner. And third, the backlight() function turns on the LCD backlight.

After that we set the cursor position to the third column of the first row by calling the function lcd.setCursor(2, 0). The cursor position specifies the location where you want the new text to be displayed on the LCD. The upper left corner is assumed to be col=0, row=0.

There are some useful functions you can use with LiquidCrystal_I2C objects. Some of them are listed below:lcd.home() function is used to position the cursor in the upper-left of the LCD without clearing the display.

lcd.scrollDisplayRight() function scrolls the contents of the display one space to the right. If you want the text to scroll continuously, you have to use this function inside a for loop.

lcd.scrollDisplayLeft() function scrolls the contents of the display one space to the left. Similar to above function, use this inside a for loop for continuous scrolling.

If you find the characters on the display dull and boring, you can create your own custom characters (glyphs) and symbols for your LCD. They are extremely useful when you want to display a character that is not part of the standard ASCII character set.

As discussed earlier in this tutorial a character is made up of a 5×8 pixel matrix, so you need to define your custom character within that matrix. You can use the createChar() function to define a character.

To use createChar() you first set up an array of 8 bytes. Each byte in the array represents a row of characters in a 5×8 matrix. Whereas, 0 and 1 in a byte indicate which pixel in the row should be ON and which should be OFF.

CGROM is used to store all permanent fonts that are displayed using their ASCII codes. For example, if we send 0x41 to the LCD, the letter ‘A’ will be printed on the display.

CGRAM is another memory used to store user defined characters. This RAM is limited to 64 bytes. For a 5×8 pixel based LCD, only 8 user-defined characters can be stored in CGRAM. And for 5×10 pixel based LCD only 4 user-defined characters can be stored.

Creating custom characters has never been easier! We have created a small application called Custom Character Generator. Can you see the blue grid below? You can click on any 5×8 pixel to set/clear that particular pixel. And as you click, the code for the character is generated next to the grid. This code can be used directly in your Arduino sketch.

Your imagination is limitless. The only limitation is that the LiquidCrystal library only supports eight custom characters. But don’t be discouraged, look at the bright side, at least we have eight characters.

After the library is included and the LCD object is created, custom character arrays are defined. The array consists of 8 bytes, each byte representing a row of a 5×8 LED matrix. In this sketch, eight custom characters have been created.

In setup, a custom character is created using the createChar() function. This function takes two parameters. The first parameter is a number between 0 and 7 to reserve one of the 8 supported custom characters. The second is the name of the array.

lcd display character set factory

Is theres another trick for displaying more than 7 characters (my lcd maximum supports 7 characters its weird i don"t think it was hd based beacuse hd44780 had 8 character limit) .

lcd display character set factory

We offer character LCDs and graphic LCDs as modules or COG (Chip On Glass) displays in a wide array of character and pixel configuration sizes. From yellow/green, red, orange, green, blue, amber, white, and RGB backlight colors to displays without a backlight, we have the perfect LCD for your application.

lcd display character set factory

ERM2004FS-3 is small size 20 characters wide,4 rows character lcd module,SPLC780C controller (Industry-standard HD44780 compatible controller),6800 4/8-bit parallel interface,single led backlight with white color included can be dimmed easily with a resistor or PWM,fstn-lcd positive,black text on the white color,high contrast,wide operating temperature range,wide view angle,rohs compliant,built in character set supports English/Japanese text, see the SPLC780C datasheet for the full character set, It"s optional for pin header connection,5V or 3.3V power supply and I2C adapter board for arduino.

lcd display character set factory

Character LCDs provide a project with a compact, easy-to-read display for basic textual information. The most common type of character LCD available to developers ship on a circuit board which also contains a Hitachi HD44780 controller chip or one of a number of controllers that are compatible with the Hitachi device, such as the Seiko-Epson SED1278. The HD44780 is now the de facto standard for character LCD controllers.

The HD44780 connects to the outside world across a standard 14-pin interface. Most LCDs come with 16 pins — the extra two, usually marked A and K, are used to access the display’s backlight anode and cathode connections, and are optional. The full set of 16 pins is:

The HD44780 supports displays ranging from one line of eight characters (8 x 1) to four lines of 40 characters (40 x 4), and you can easily find displays of these dimensions and any in between, including the very commonplace 16 x 2 and 20 x 4 sizes. Each HD44780 is designed to support up to 8 x 2, ie. 16 characters, so displays with greater dimensions use two, three or four controllers, all connected through a single 14-pin bus. Each HD44780 is smart enough to co-operate with the others so that you don’t have to worry about which particular one your imp is talking to.

Fourteen pins can present something of a challenge when it comes to hooking up a character LCD to imps with a low number of GPIO pins, such as the imp001. The HD44780 has a 4-bit mode which means you can dispense with four of the eight data pins, but that still leaves seven pins required for data and an eighth if you want to set the display contrast dynamically.

Adafruit’s I²C/SPI backpack is a good choice. It can handle character LCDs with display dimensions from 8 x 1 to 20 x 4 and only adds around $10 to the price of a project. It is sold separately from the LCD itself, giving you scope to choose exactly the display you prefer, and it includes circuitry to manage the display contrast, which is controlled from a variable resistor on the board itself.

There is one criterion when it comes to choosing a character LCD: its operating voltage. This has to be correct for imp operation, which means the display must operate at 3 or 3.3V. Most of the character LCDs on the market are designed to operate at 5V and these are not suitable for connecting directly to an imp without some form of level adjustment. Though the selection of said screens isn’t as broad as it is for 5V devices, you should be able to find a 3.3V display that meets your needs.

Beyond operating voltage, displays come in a variety of sizes, in various colors and with backlights designed for dark-on-light characters or for light-on-dark. Prices are low and availability is good.

Writing to the HD44780 — and thus the LCD — involves choosing one of the chip’s two registers, Command and Data, which is done by setting the RS pin high or low, respectively. Next set the RW pin low to indicate a write, put the data byte’s bit values on the data pins, and set E to high to tell the chip to process the data. When the HD44780 has had time to do so, you end the process by setting E low. The HD44780 datasheet tells you how long all key tasks take to complete so you know how long to wait before setting E low.

Before you can start presenting characters on the display, you need to initialize the display. This involves sending the Function Set command, followed by Entry Mode Set, Display Control and Clear Display. These are all set codes which, again, the datasheet provides. You’ll find them included in the sample code, below.

The HD44780 is pre-programmed with all the standard Ascii characters. It also provides eight user-definable characters that you can use to add symbols that are either absent from the controller’s characters — the degrees sign, for instance — or which are unique to your application, such as weather icons. The HD44780 reserves a block of RAM for the user-definable characters, so they won’t be preserved when the controller is power-cycled. However, it does mean you can change any of the characters on the fly, giving you an effectively infinite set of characters to work with.

The user-definable characters are drawn on a 5 x 8 pixel matrix and allotted to Ascii values 0 through 7. You send the RAM address of the character you want (the base address OR’d with the chosen Ascii value) as a command and then write the eight bytes of character matrix row data. Bits 5 through 7 of each row are ignored, leaving bits 0 through 4 as the character matrix values.

Electric Imp’s GitHub repo contains a Squirrel class for working with character LCDs connected via Adafruit’s I²C/SPI backpack. The class, CHARLCD, is instantiated with the imp I²C bus to which the display is connected and the backpack’s I²C address, which defaults to 0x20 but can be changed by bridging a series of pads on the back of the board. The new CHARLCD object must then be initialized, using the init() function, with the dimensions of the LCD: the number of characters and the number of rows. For example:

The class provides functions to print characters and strings, set the print position to a chosen row and column, to center text on the screen, to switch the backlight on or off, and to define characters. The HD44780 supports broader functionality: to set a static or blinking cursor, to set the type of cursor (underline or block) and to handle scrolling, for example. Details of these and other features can be found in the controller’s datasheet.

lcd display character set factory

The CFA633 series of advanced display modules will be changing from the current firmware v2.1 to v2.2. Design changes were made for backwards compatibility.

The CFA633 series of advanced display modules will be changing from the current hardware v2.0 to v2.1. Design changes were made for backwards compatibility.

As part of our continuous improvement, design changes have been made to the hardware of the CFA633 series of advanced display modules for improved manufacturability, improved quality, and a lower current profile.

Starting August 1, 2015 the "Drive Bay Kit Configurator" located at https://www.crystalfontz.com/products/select_kit.html will no longer be functional for ordering one of our Serial or USB displays (CFA533, CFA631, CFA632, CFA633, CFA634, CFA635, and CFA735) in a bracket or SLED. This functionality is being moved to the Customize and Add to Cart process when checking out. This will allow for further customization by our customers to better fit their needs.

The new part numbers will have the bracket / SLED and overlay type as a PREFIX to the configured part number. The choice for bracket / SLED to a display order will be via the cart options. Our CFA835 displays were introduced with these configuration options.

As part of our continuous improvement process, we are integrating the ordering of displays in drive bay and SLED kits as part of the display ordering process.

In command 5 (0x05): Reboot CFA633, Reset Host, or Power Off Host, the module now knows if it is coming from a power up or from a reset. This in turn improves the bootup sequence. A note was added to describe the brief delay at bootup when more than one of the optional fans are on.

In command 12 (0x0C): Set LCD Cursor Style, cursor style choice "3" changed from "3 = blinking block plus underscore" to "3 = blinking underscore cursor." The rate at which the cursor blinks is faster than in previous CFA633 versions (HW v1.x).

The attached PDF file describes differences between our CFA633 v1.5x and CFA633 v2.0 intelligent display module series. We also list the CFA533 series as a comparison for customers who do not require the fan control available in the CFA633 series. Hardware version numbers are silk screened on the back of the PCBs.

lcd display character set factory

Marlin deals with a variety of different displays and needs to display a lot of different languages in different scripts on them, within their capabilities. The system described here solves some of the related problems that need to be overcome with in a limited environment.

Marlin 1.0 and 1.1 currently support: HD44780 (and similar) with Kana charset A00 HD44780 (Page 17) These are very common, but sadly not very useful when writing in European languages.

HD44780 (and similar) with Western charset A02 HD44780 (Page 18). These are rare, but fairly useful for European languages. Also a limited number of Cyrillic symbols is available.

On all these displays you can define 8 custom symbols to display at once. In Marlin these characters are used on the Boot Screen, and on the Info Screen for the Bed Temp, Degree symbol, Thermometer, “FR” (feed-rate), Clock, and Progress Bar. On the SD Card listing screens some of these characters are re-used again for Up-level, Folder, and Refresh.

Graphical displays provide complete freedom to display whatever we want, so long as we provide a program for it. Currently we deal with 128x64 Pixel Displays and divide this area into ~5 Lines with ~22 columns. So we need monospace fonts with a bounding box of about 6x10. Until now we’ve been using a custom Marlin font similar to ISO10646-1 but with special symbols at the end, which made ‘ü’ and ‘ä’ inaccessible at 6x10 size.

All these languages (except English) normally use extended symbols not contained in US-ASCII. Even the English translation uses some Symbols not in US-ASCII (e.g., ‘\002’ for Thermometer, STR_h3 for ‘³’). In the code itself symbols may be used without taking into account the display they’re written on.

The upshot of all this is that on Western displays you’ll see a ‘~’ while on Cyrillic an “arrow coming from top - pointing to left” (which is quite the opposite of what the programmer wanted). The Germans want to use “ÄäÖöÜüß”, the Finnish at least “äö”. Other European languages want to see their accents too. For other scripts like Cyrillic, Japanese, Greek, Hebrew, … you have to find totally different symbol sets.

The Japanese translator dealt with two scripts, introducing a special font for Graphical Displays and making use of the Japanese extended character displays. Thus he ended up with two pretty unreadable language.h files full of ‘\xxx’ definitions. Other languages either tried to avoid words that included special symbols or just used the basic symbols without the accents, dots… whatever.

Make output functions that count the number of chars written and switch the font to Marlin symbols and back when needed. (ultralcd_impl_DOGM.h) (ultralcd_impl_HD44780.h)

Make three fonts to simulate the HD44780 charsets on dogm-displays. With these fonts the translator can check how the translation will look on character-based displays.

Make ISO fonts for Cyrillic and Katakana - because they don’t need a mapping table, are faster to deal with, and have a better charset than the HD44780 fonts. (Less compromise!)

If you make extensive use, your file will look like language_kana.h and your language file will only work on one of the displays (in this case DISPLAY_CHARSET_HD44780 == JAPANESE).

If you want to make use of more than a few symbols outside standard ASCII or want to improve the portability to more types of displays, use UTF-8 input. Which means defining another mapper.

Due to storage limitations we can’t use every UTF-8 glyph at once, so we capture only a subset containing the characters we need: MAPPER_C2C3 corresponds well with Western-European languages. The possible symbols are listed at this Latin-1 page.

The mapper_tables do their best to find a similar symbol in the HD44780fonts (for example, replacing small letters with the matching capital letters). But they may fail to find a match and will output a ‘?’. There are combinations of language and display which simply have no corresponding symbols - like Cyrillic on a Japanese display or _vice-versa. In those cases the compiler will throw an error.

In short: Choose a mapper that works with the symbols you want to use. Use only symbols matching the mapper. On Full Graphic Displays all symbols should be fine. Using the graphical display, you can test for bad substitutions or question-marks that would appear on character displays by defining SIMULATE_ROMFONT and trying the different variants.

If you get a lot of question marks on the Hitachi-based displays with your new translation, maybe creating an additional language file with the format language_xx_utf8.h is the way to go.

Mappers together with an ISO10646_* font are the second-best choice in terms of speed and memory consumption. Only a few more decisions are made per-character.

In this file specify the mapper (e.g., MAPPER_NON) and font (e.g., DISPLAY_CHARSET_ISO10646_1) and translate some of the strings defined in language_en.h. (Remove #ifndef #endif from the defines.)

If there’s no existing mapper for your language then things get a bit more complex. With the Hitachi-based displays you can’t make something useful without a matching charset. For graphical display… let’s take the example of Greek: Find a matching charset. (Greek and Coptic)

Provide a bitmap font containing the symbols in the right size (5x9 to 6x10 recommended). Normal ASCII characters should occupy 1 to 127, and the upper 128 places should be populated with your special characters.

If you want to integrate an entirely new variant of a Hitachi-based display. Add it to Configuration.h and define mapper tables in utf_mapper.h. You may need to add a new mapper function.

The length of strings (for menu titles, edit labels, etc.) is limited. “17 characters” was a crude rule of thumb. Obviously 17 is too long for a 16x2 display. So, language files are free to check the LCD width and provide shorter strings in the following manner:

On 16x2 displays, strings suited to a 20x4 display will be chopped to fit. So if shorter string isn’t provided, at least make similar strings different early in the string. (‘Someverylongoptionname x’ -> ‘x Somverylongoptionname’)

To find out which character set your hardware uses, set #define LCD_LANGUAGE test and compile Marlin. In the menu you’ll see two lines from the upper half of the character set: JAPANESE displays “バパヒビピフブプヘベペホボポマミ”

If you get an error message about “missing mappers” during compilation - lie about your display’s hardware font to see at least some garbage, or select another language.

LCD_LANGUAGE: The LCD language and encoding to compile in. For example, pt-br_utf8 specifies Portuguese (Brazil) in UTF-8 format with a mapper. For a faster, lighter, but non-accented translation you might choose pt-br instead.

MAPPER_C2C3: This is a mapper set by some language files, and indicates that Marlin should use the mapper for Unicode pages C2 and C3. In this mapper, strings are converted from raw UTF-8 input to single ASCII characters from 0-127, and indexes from 0-127 within the combined two 64-glyph pages C2 and C3.

SIMULATE_ROMFONT: Languages can opt to use the HD44780 ROM font special characters on graphical display. This method can be used for accented Western, Katakana, and Cyrillic if they don’t supply their own fonts, or just for testing character-based mappers on a graphical display.

DISPLAY_CHARSET_ISO10646_1: To support a graphical display, a language file must specify either SIMULATE_ROMFONT or a display character set. This specific option selects the Western font for use on graphical display. Others include ISO10646_5, ISO10646_KANA, ISO10646_GREEK, ISO10646_CN, ISO10646_TR, and ISO10646_PL. If no character set is specified, Marlin assumes ISO10646_1.

MAPPER_ONE_TO_ONE: Most character sets on graphical displays (including SIMULATE_ROMFONT) map the character index directly to its position in the upper half of the font. This is possible for character sets that have only 2 contiguous pages of Unicode containing all the special characters. Other mappers use logic or a lookup table to locate the glyph.