Display driver library for 7 segment LED and LCD displays on Arduino

DSC_7805

For some of my projects I needed a LED display on the Arduino. This is fairly easy with the library manager in Arduino I could find two libraries supporting the display I wanted (TM1637), but everything was not fine!
In the end I wrote my own driver, it supports many different 7 segments displays and has a broad selection of functions to display data.
It is not a real library, but best copied into the project directory, due to the "#define". The library uses about 1100 bytes flash for the basic number display on a TM1637.
This library supports all the display on the above picture including keys and indicators, it do also support some other display.

Contents
    Display driver library for 7 segment LED and LCD displays on Arduino
    Requirement
    Supported displays
        HC164 2x4 digit
        HC595 2 digit
        HC595 4 digit
        HC595 Static any number of digit
        HT1621 6 digit LCD display
        HT1621 12 digit LCD display
        HT16K33 4 digit LED display
        HT16K33 8 digit LED display
        MAX7219 8 or more digit
        TM1637 4 digit
        TM1637 6 digit, 6+ keys
        TM1638 8 digit, 8 indicators, 8 keys
        TM1638 8 digit, 16 keys
        TM1638 8 digit, 2 indicators, 24 keys
    The software
        The simple usage
            Show a number
            Using it for a clock display
            Controlling segments directly
            A temperature display
            Displaying text
        Optimizing library for the applications: #define
            Display type select
            DELAY_TIME
            _FAST_CLOCK_
            _ENABLE_6_DIGITS_
            _INCLUDE_BYTE_
            MAX_DIGITS
        Constants
        All functions
            General notes
            Constructors
            Bytes and integers
            Bytes and integers in hex (BCD)
            Bytes and integers in binary
            Float and double (They are the same on a MEGA)
            Text, strings and characters
            Indicator segments
            Direct segment access
            Key input
            Support routines
        Print and LCD API
            Constructors
            LCD API
    My favorites and dislikes
        Favorites
        Dislikes
    Conclusion
    Notes and download


Requirement

I wanted a flexible and easy to use display driver library, my initial list of requirements was:
Later one I added a few more requirements: This may sound like a large library and it do contain a fair amount of code, but the compiler will strip unused code and with the defines I only include code for the selected display type. This means memory usage will usually be fairly low.



Supported displays

Each display type requires a change in the top of the ".h" file where the relevant #define must be un-commented and all the other must be commented out.
The displays listed below are the ones I have tested with, other displays with the same driver chip will often be supported.

support

The above table shows what is supported on different displays.


HC164 2x4 digit

DSC_7191

DSC_7192 DSC_7193

Connections: data=DAT, clock=CP
Display type: _HC164_

The HC164 is a fairly bad choice as display driver because the display driver pins are on while data is being shifted in. For this to give a usable display _FAST_CLOCK_ must be enabled and DELAY_TIME must be defined as 0, but some segments will flicker occasionally.
The display uses interrupts.



HC595 2 digit

DSC_7194

DSC_7195

DSC_7196

Connections: data=DAT, clock=SCLK, load=RCLK
Display type: _HC595A_

With this display one HC595 contains the segment data, the other select digit, this means it must be update multiple times each second.
It is recommended to use fast mode with this display (_FAST_CLOCK_ defined and DELAY_TIME 0) to reduce the amount of processor time used for updating.
The display uses interrupts.



HC595 4 digit

DSC_6631

DSC_6632
DSC_6633

Connections: data=DIO, clock=SCLK, load=RCLK
Display type: _HC595_

With this display one HC595 contains the segment data, the other select digit, this means it must be update multiple times each second.
It is recommended to use fast mode with this display (_FAST_CLOCK_ defined and DELAY_TIME 0) to reduce the amount of processor time used for updating.
The display uses interrupts.



HC595 Static any number of digit

DSC_7786 DSC_7787
DSC_7197

DSC_7790 DSC_7791

DSC_7788
DSC_7789


DSC_7198
DSC_7199

Connections: data=SDI, clock=SCLK, load=LOAD
Display type: _HC595_STATIC_

This is a simple LED display and with static drive the digits are always stable. It is possible to chain displays for any number of digits. When using more than 8 digits remember to increase the buffer (MAX_DIGITS).

DSC_7776

A couple of display is driven from the same output, the frame buffer (MAX_DIGITS) was increased to support the displays.



HT1621 6 digit LCD display

DSC_7200

DSC_7201

DSC_7202

DSC_7206

Connections: data=Data, clock=WR, load=CS, depending on S1 (solder bridges) the backlight is powered from Vcc or LED+
Display type: _HT1621_6D_

This is a LCD display with background light, 6 digits and battery indicator, as can be seen the point is only support on some digits. The points has a offset compared to the digit and the missing points are used for the battery indicator, all this is mostly handled by the driver. It will ignore non-existing points, this means float may be missing a point if it is supposed to be in one of the two first positions. For controlling the battery symbol use showIndicators() with BATT_LOW, BATT_MEDIUM and BATT_HIGH, each will turn on one symbol.
This selection only works with this display, not with other HT1621 based displays!



HT1621 12 digit LCD display

DSC_7203

DSC_7204

DSC_7205

DSC_7209

Connections: data=3, clock=2, load=1, GND=4, Vcc=5
Display type: _HT1621_12D_

This is a LCD display with 12 digits and 7 indicators. For controlling the indicators use showIndicators(). This display type will redefine MAX_DIGITS to 12.
This selection only works with this display, not with other HT1621 based displays!



HT16K33 4 digit LED display

DSC_8054
DSC_8052
DSC_8053

Connections: data=D, clock=C, All 3 address links are supposed to be open (Address 0x70).
Display type: _HT16K33_4D_

This display uses a I2C protocol, the driver handles this in software, i.e. any two IO pins can be used to control the display.
This display support both point and colon, the colon is placed on a spare digit. This is hidden in the driver, it is just a 4 digit display with a indicator called COLON_DISP_n where n is display number (First is 0). The driver supports up to 8 display with different address, they will all be handled as one large display with the lowest address starting with digit 0. Remember to increase MAX_DIGITS if more then two displays are used, it must be a multiple of 4.

address

No jumpers is default address, for secondary display short 0, for 3. short 1, for 4. short 0 and 1.

DSC_8056

3 displays on a Arduino Nano with temperature, clock and a counter.



HT16K33 8 digit LED display

DSC_7504
DSC_7505
DSC_7506
DSC_7509


Connections: data=SDA, clock=SCL, V_I is pullup for I2C and VCC is power for display, on 5V systems both are connected to 5V. All 3 address links are supposed to be open (Address 0x70).
Display type: _HT16K33_

This display uses a I2C protocol, the driver handles this in software, i.e. any two IO pins can be used to control the display.
The displays are in sockets, this makes it possible to swap them for other colors, but it also means they are slightly unstable in the mounting.
The driver supports up to 8 display with different address, they will all be handled as one large display with the lowest address starting with digit 0. Remember to increase MAX_DIGITS if more then two displays are used, it must be a multiple of 8.



MAX7219 8 or more digit

DSC_6628

DSC_6629
DSC_6630

Connections: data=DIN, clock=CLK, load=CS
Display type: _MAX7219_

The MAX7219, usual sold with 8 digits connected. The library do not use the 7 segment decoder in the chip, but directly controls the segment.

DSC_6547

Multiple MAX7219 chained together, for this to work the frame buffer must be increased (MAX_DIGITS), one byte is needed for each digit, i.e. 24 for the above display. With this size display it is best to run without auto update and first call update after updating all the numbers.



TM1637 4 digit

DSC_6624
DSC_6625 DSC_8060

DSC_6622
DSC_6623

DSC_6626
DSC_6627

DSC_8057
DSC_8059

Connections: data=dio, clock=CLK
Display type: _TM1637_

These displays only needs two connections. Many displays are designed for clock usage, i.e. the decimal points are not connected, but it is possible to find display with working decimal points. There is two versions of this chip with slightly different protocol timing, the one implemented here works with both.



TM1637 6 digit, 6+ keys

DSC_7213
DSC_7214 DSC_7215

Connections: data=SDA, clock=SCL
Display type: _TM1637_

These displays only needs two connections. In addition to the 6 buttons on the circuit board it supports 8 external buttons. Only one button can be pressed at a time.

The keys are defined as KEY_S1 to KEY_S6 and can be read with readKeyIndex or readKeyIndexOnce.
Use Keys are read with readKeys to get a bitmask of pressed keys.

DSC_7217

The marking on the circuit board is wrong, this is the way to connect the eight extra buttons. There are no definitions for the external keys, but they are numbered from 8 to 16.



TM1638 8 digit, 8 indicators, 8 keys

DSC_7210

DSC_7211 DSC_7212

Connections: data=DIO, clock=CLK, load=STB
Display type: _TM1638_

This board has 8 digit, 8 leds and 8 switches, this is not everything the chip supports, the software is made to support the full ability of the TM1638 chip.

The leds can be controlled with setIndicators and are defined as LED_1 to LED_8

The keys are defined as KEY_S1 to KEY_S8 and can be read with readKeyIndex or readKeyIndexOnce.



TM1638 8 digit, 16 keys

DSC_7439

DSC_7440 DSC_7441


Connections: data=DIO, clock=CLK, load=STB
Display type: _TM1638_QYF_

This board has 8 digit and 16 switches, the segments and digits pins are swapped. This driver is not a full TM1638 driver, but only supports this board (The indicators are not implemented).

The keys are defined as KEY_S1 to KEY_S16 and can be read with readKeyIndex or readKeyIndexOnce.





TM1638 8 digit, 2 indicators, 24 keys

DSC_7751

DSC_7752 DSC_7753

Connections: data=DIO, clock=CLK, load=STB, this means removing the jumpers.
A 1kOhm pullup to 5V must be added to the DIO line for the keyboard to work and the switch S1 must be pushed down for anything to work.
Display type: _TM1638_HWA11_

This board has 8 digits, 24 switches and 2 indicators, it do also has a buzzer, but it is not supported through the TM1638.
The driver for this display is the same as for _TM1638_ except the LSB/MSB digits are swapped on the display.

The keys are defined as KEY_K1 to KEY_K24 and can be read with readKeyIndex or readKeyIndexOnce.

The two led can be controlled with setIndicators and are defined as LED_1 and LED_2



The software


The simple usage

Some examples on using the library.

Creating the display object is fairly standard, with only a minimum of parameters:
Code:
LEDDisplayDriver display(data,clock);// 4 digit mode with 2 connections to display
LEDDisplayDriver display(data,clock,load);// 4 digit mode with 3 connections to display

Show a number

digitEmpty digit1 digit2 digit3           digit1 float7 digit5 digit0

Code:
display.showNum(123);
display.showNum(17.5);
This is, of course, the simplest usage where the number will use all the digits.


Using it for a clock display

clock1 clock2 clock3 clock4

Code:
LEDDisplayDriver display(data,clock,false,4);// Turn auto update off, this is never required, but makes the code a bit faster

display.setDp(1);// The colon is on digit 1, this will turn it on independent of the show functions called. 
display.showNum2Left(hour);// I could also have used the full call: display.showNum(hour,0,2);
display.showNum2Right(minutes)// I could also have used the full call: display.showNum(minutes,2,2);
display.update();// Transfer the above 3 calls to the display
In this example the display is updated in two sections and the forced decimal point is used to turn the colon on. To get best performance auto update is disables and a manual call to update is used.



Controlling segments directly

digitD digit0 digitN digitE

Code:
LEDDisplayDriver display(data,clock);

byte data[]={digitD,digit0,digitN,digitE};
display.showDigits(data,0,4);
It could also be done this way, it is more useful when combining a number with a status segment:
Code:
LEDDisplayDriver display(data,clock,false,4);// Turn auto update off, I want to call multiple show before updating display

display.showDigit(digitD,0);
display.showDigit(digit0,1);
display.showDigit(digitN,2);
display.showDigit(digitE,3);
display.update();


A temperature display

digit2 float4 digit3 digitDeg

Code:
LEDDisplayDriver display(data,clock,false,4);// Turn auto update off, I want to call multiple show before updating display

display.showNum1decimal(24.3,0,3);
display.showDigit(digitDeg,3);
display.update();
This routine uses a floating point routine to display a number with 1 decimal and shows a character after the temperature.


Displaying text

digitH digitE digitL digitL digitO digitEmpty digitEmpty digitEmpty
Code:
LEDDisplayDriver display(data,clock,true,8);// Use a 8 digit display

display.showText("Hello");



Optimizing library for the applications: #define

There is a couple of #define in the header file to control how the library is build.


Display type select
Some displays requires interrupts, the following defines makes a macro to call the interrupt handler and adds code to initialize a timer. For this to work "DISPLAY_INTR(display)" must be included in your program. It is not required to use this interrupt code, it is possible to call the display interrupt handle from you own interrupt routine ("display.updateIntr()"), this is required on non-MEGA processors.

DELAY_TIME

This controls the delay between clock and data changes on the communication lines, low value will make it fast (i.e. 1 or 0), high value (i.e. 10) will make it slower and less susceptible for noise and long wires.


_FAST_CLOCK_

When defined the library will use direct IO, this is faster than Arduino standard functions, but not compatible with all processor types. The direct IO will also use a few bytes more memory. Using direct IO with DELAY_TIME 0 will make the display update very fast!


_ENABLE_6_DIGITS_

When defined the library supports long, this is only needed for 5 or more digit displays. For displaying float/double on 5 digit displays long is required.
As standard it is included, but some memory may be saved on displays with 4 or less digits by commenting this #define


_INCLUDE_BYTE_

Include a byte version of show, this is slightly faster than the standard int version.
As standard it is included, but some memory may be saved by commenting this #define, then byte will be handled by the int routines.


MAX_DIGITS

Define the frame buffer size, default is 8, but when chaining multiple MAX7219 more space is needed. Displays with more than 8 digits may automatic increase this value.
1 byte of ram is used for each digit.



Constants

The library has some useful constants for handling the display.

segments

First there is all the segment bit masks: SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G and SEG_DP
They are defined with #define and the definition will change change depending on selected display type. A on segment is always a 1 bit, any needed inversion for this is done by the library.

All the following digit definitions are defines as bytes, there are a few duplicates, i.e. same segment definition for different symbols.

digit0 digit1 digit2 digit3 digit4 digit5 digit6 digit7 digit8 digit9

The standard numbers: digit0, digit1, digit2, digit3, digit4, digit5, digit6, digit7, digit8 and digit9

digitA digitB digitC digitD digitE digitF

Including hex digits: digitA, digitB, digitC, digitD, digitE and digitF
They are also available as an array: segmentPatterns[] that can be indexed with 0 to 15.

digitcc digitG digitH digithh digitI digitii digitJ digitL digitN digitO digitP digitQ digitR digitS digitT digitU digituu digitY

And all the obvious letters, all are named with a upper case letter, except if there are both a upper and lower case version.
digitDp digitMinus digitTop digitBottom digitRight digitLeft digitDeg digitEmpty digitOpen digitClose

Some segments combinations:
In addition to the segment and digit definition there is also a MAX_BRIGHTNESS constant, it will be 0 for display without brightness control and 7 or 15 for displays with brightness control. It is the maximum value the display support, any higher value will be limited to this value.



All functions

General notes
The parameters first,count is nearly always optional, when present it specify the first digit and the number of digits to use. The first digit is the leftmost digit and is number 0, count must be 1 to use exactly one digit and 4 to use exactly 4 digits.
Digit number: Digits%20numbering
The specified digits will always be cleared and depending on what to display and display format they may be filled again.

When leaving out the first,count parameter most routines will use the full display width, exceptions are the ...left, ...center, ...right routines and some single digit functions.


Constructors

The constructor can be used two ways:
Code:
LCDDisplayDriver display(data,clock);
LCDDisplayDriver display(data,clock,load);   
LCDDisplayDriver display(data,clock,autoUpdate,digits);   
LCDDisplayDriver display(data,clock,load,autoUpdate,digits);
The first two lines will create a object for a 4 digit display with autoUpdate, the 3 & 4 lines makes it possible to specific autoUpdate and change number of digits. When using more than 8 digits, remember to change the define "MAX_DIGITS". For displays that requires 3 control lines the versions without "load" parameter is not available. A display with two control lines can always be created with 3 control lines, the load parameter is ignored.
Specifying more digits than there is space for in the frame buffer may give some strange compilation errors!



Bytes and integers

Code:
showNum(number);
showNum(number,first,count);
This will show an integer, depending on defines it will be locked to int type or select between byte, int and long. Numbers are right adjusted within the available space.
These routines support negative numbers, if there are space on the display.

Code:
showNum(number,true);
showNum(number,first,count,true);
Same as above, but with leading zeros, this will not work with negative numbers. The minus takes precedence over the zeros.

Code:
showNum2Left(number);
showNum2Center(number);
showNum2Right(number);
showNum2LeftLZ(number);
showNum2CenterLZ(number);
showNum2RightLZ(number);
Show two digit on either the left, center or right part of the display, these function are for bytes, i.e. unsigned numbers. The LZ version will include a leading zero.

Code:
showNum4Left(number);
showNum4Right(number);
showNum4LeftLZ(number);
showNum4RightLZ(number);
Show four digit on either the left or right part of the display, these function are mostly useful for 6 or more digit displays. The LZ version will include leading zero.

Code:
showNumWithPoint(number,pointPosition);
showNumWithPoint(number,pointPosition,first,count);
Will show an integer number, but include a point on the display at the specified position. The point is specified from the right digit and leading zeros will be added as needed:

showNumWithPoint(1000,0) will show 1000.
showNumWithPoint(1000,1) will show 100.0
showNumWithPoint(1000,2) will show 10.00
showNumWithPoint(1,2) will show 0.01

Code:
showNumWithPrefix(prefix,number,pointPosition);
showNumWithPrefix(prefix,number,pointPosition,first,count);
Same as point routines, but first digit is reserved for status information, except it will be used for sign and point when required:

showNumWithPrefix(digitBottom,100,1) will show _10.0

I.e. prefix specifies what segments to turn on at the leading digit.



Bytes and integers in hex (BCD)

Code:
showHex(number);
showHex(number,first,count);
Show a hex number on the display, hex numbers always includes leading zeros. BCD can be display with the hex functions, it is exactly the same, but only uses 0-9.

Code:
showHex2Left(number);  
showHex2Center(number);
showHex2Right(number); 
Shortcuts to place two hex digits on a display.

Code:
showHex4Left(number);  
showHex4Right(number); 
Shortcuts to place four hex digits on a display.


Bytes and integers in binary

Code:
showBin(number);
showBin(number,format);
showBin(number,format,first,count);
Show a binary number in the display, it has a couple of different formats, some of them will pack two bits in each digit:
format=0: Use normal number digits: digit0 digit1 (This format is used for showBin(number))
format=1: Use small digits: digitO digitf11
format=2: Use small digits in the upper part of the segments: digitHigho digitf21
format=3: Pack two digits in each segment and only show ones: digitEmpty digitf11 digitf12 digitf13
format=4: Use the upper segments: digitEmpty digitf21 digitf22 digitf23
format=5: Use both segments: digitEmpty digitf31 digitf32 digitf33



Float and double (They are the same on a MEGA)
Code:
showNum(number);
showNum(number,first,count);
The same routines as for integers, but this time a point will be used depending on the number. It can show from 0.001 to 9999. on a four digit display, it supports negative numbers, but that will be one numeric digit less, i.e. -0.01 to -999., overflow will be shows as ----.

Code:
showNumWithPrefix(prefix,number);
showNumWithPrefix(prefix,number,first,count);
This reserve one digit for status usage (called prefix), but do not limit the floating display to only 3 digit, the point and sign is shown on the status digit.
This means: .001 to 999 and -.001 to -999 can be displayed.
On the status digit it is best not to use the point and minus segments and avoid patterns that can look like a number.

Code:
showNum1decimal(number);
showNum1decimal(number,first,count);
showNum2decimals(number);
showNum2decimals(number,first,count);
showNum3decimals(number);
showNum3decimals(number,first,count);
Showing float with fixed decimal location is fairly simple, these routines uses "showNumWithPoint" and simply multiplies the number with 10/100/1000 and rounds correctly.

See also showNumWithPoint() in the "Bytes and integers" section.



Text, strings and characters

Many characters are available as digit... constant, there is also a routine to display text that has a few more characters defined.
Code:
showChar(digit,character);
showText(string)
showText(string,first,count)
showText(character_array)
showText(character_array,first,count)
The showChar() is for a single character at specified position, the showText will work with either a String or a char[] type. The actual text length do not affect the display, with short strings it will be filled with blanks and with long strings only the first characters will be shown.
I have tried to make the characters as legible as possible (Some are hopeless like KMVWXZ), this means mostly ignoring upper/lower case and most symbols are empty.

Symbols and numbers (0x20..0x3f):
digitEmpty digitEmpty digitDoubleQuote digitEmpty digitEmpty digitEmpty digitEmpty digitQuote digitOpen digitClose digitEmpty digitEmpty digitDp digitMinus digitDp digitEmpty

digit0 digit1 digit2 digit3 digit4 digit5 digit6 digit7 digit8 digit9 digitEmpty digitEmpty digitEmpty digitEqual digitEmpty digitEmpty

Upper case letters (0x40..0x5f):

digitEmpty digitA digitB digitC digitD digitE digitF digitG digitH digitI digitJ digitK digitL digitM digitN digitO

digitP digitQ digitR digitS digitT digitU digitV digitW digitX digitY digitZ digitOpen digitRight digitClose digitEmpty digitBottom

Lower case letters, there is only a few letters that are different (0x60..0x7f):

digitEmpty digitA digitB digitcc digitD digitE digitF digitG digithh digitii digitJ digitK digitL digitM digitN digitO

digitP digitQ digitR digitS digitT digituu digitV digitW digitX digitY digitZ digitOpen digitRight digitClose digitEmpty digitBottom


Indicator segments

Some displays has indicators, these are handled outside the standard show functions.
Code:
showIndicators(bitmask);
getIndicators();
This routine is only defined for displays that support indicators, there may also be defined some constants for the indicators.
The actual data type of the bitmask will depend on the number of indicators supported on the display.


Direct segment access

Code:
showDigit(digit,index);
showDigits(digits,first,count);
The first routine shows a byte with segment definitions on the specified digit, the second routines takes an array of bytes and show it on sequential digits. Use the "digit.." constants to get the values needed or build them with the SEG_x definitions. Do not write a binary or hex value, it will not be compatible with all display types.

Code:
getDigits();
Returns a pointer to the actual digit data, this makes it possible to manipulate the final result before displaying it. There is generally very little reason for using this function, raw digit access is better done with showDigit or showDigits. The returned pointer will always be valid, the internal data are not reallocated or moved.

It can be used like this:
*(display.getDigits() + 1) = digitEmpty;
or
*(display.getDigits() + 1)|= digitDp;

For this to work autoUpdate must be off and update called after the manipulations.



Key input

A few display types supports keys, there are some routines to read these. The library do not do any scanning or debouncing, it will only read the keys when called. The call must not be done from an interrupt routine, that will disrupt the display updates!

Code:
readKeys()
readKeyIndex()
readKeyIndexOnce()

The readKeys will return a bitmask of all the keys, it may be an byte, unsigned int or unsigned long with a 1 in the positions with keys pressed.
readKeyIndex will use readKeys, and return the index of a pressed key or 0 when no key is pressed.
With readKeyIndexOnce each key press will only be returned once, a working debounce can be implemented by waiting at least 10ms between calls to read the keys.
When only a single key is used at a time, the readKeyIndex and readKeyIndexOnce will work fine, the readKeys is for handling multiple simultaneous pressed keys (The hardware may have some limits on this).
For displays with keys there is usual defined constants for the keys, they are called "KEY_xx" where xx is the key name/number on the circuit board. The defined values match what is returned by readKeyIndex and readKeyIndexOnce.


Support routines

Code:
clear();
clear(digit);
Clear the display, this is not necessary to call before any of the show functions, but may be useful for cleaning a status digit. This will clear digits and indicators, but will not affect the setDp() function.

Code:
update();
update(digit);
setAutoUpdate(false);
The setAutoUpdate can enable/disable the automatic updating after clear, setDp, setBrightness, setOn or show functions. This can also be defined in the constructor.
When automatic update is not enabled the update function must be called to update the full display, if only one digit is change the update(digit) can be used. When more than one digit is updated it is always recommended to use a "update()", not the single digit version.

Code:
setBrightness(value);   
setOn(true);            
setDp(digit);           
removeDp();
showTest();
begin();
The brightness can be adjusted from 0 to 7 or 15 depending on display type. The define MAX_BRIGHTNESS will be 0, 7 or 15 depending on supported brightness settings. The setBrightness routine will limit higher values to MAX_BRIGHTNESS.
The setOn can turn the display on or off. The setDp will add a decimal point or colon on the display, this is controlled outside the show functions and will stay on until removeDp is called or setDp is called with a invalid digit. The library do not use this function for decimal points in numbers. The showTest will turn all segments and indicators on, calling other show functions will override this.
The Arduino programs most timers to slightly below 1kHz update rate (Except MegaU4 intr4), to get precisely 1kHz update rate place the display.begin() in the "void setup()" section.

Code:
isPresent();
Some display protocols gives a feedback during communication, the last feedback is stored in an internal variable and can be checked with this function. If this function is false, no feedback was received from the display and it is probably not connected or defective. Displays without feedback will always return true.



Print and LCD API

I do not like the LCD API for a 7 segment display, it is a very bad match for it, but some people want it. To solve this I have added a class called "LEDLCDAPIDriver", it is build on LEDDriverDisplay and Print, it exposes the LCD API.

Because this API is based on text, the LEDDriverDisplay library will include the code for text display, but no other show function.
The API from LEDDriverDisplay is hidden, to include both change the declaration of LEDLCDAPIDriver (Change private to public in the class line)



Constructors
Code:
LEDLCDAPIDriver display(data,clock);
LEDLCDAPIDriver display(data,clock,load);   
LEDLCDAPIDriver display(data,clock,autoUpdate,digits);   
LEDLCDAPIDriver display(data,clock,load,autoUpdate,digits);
The first two lines will create a object for a 4 digit display with autoUpdate, the 3 & 4 lines makes it possible to specific autoUpdate and change number of digits. When using more than 8 digits, remember to change the define "MAX_DIGITS". For displays that requires 3 control lines the versions without "load" parameter is not available. A display with two control lines can always be created with 3 control lines, the load parameter is ignored.
Specifying more digits than there is space for in the frame buffer may give some strange compilation errors!



LCD API

See here for official specifications
Code:
init();// Uses begin to initialize driver
print(value);// Print a value as characters
println(value);// Print a value as characters then move cursor to home
clear();// Clear the display
home();// Move cursor to home
setCursor(Row,Col);// Row is is ignored
setBacklight(val);// Set brightness for LED display
on();// Turn LED display on
off();// Turn LED display off
keypad();// see "readKeyIndex()"

When the end of the display is reached it will scroll sideways.
The , and . character will be moved to the point on the previous digit, if there is one.

Code:
update();// Update the display, default it is automatic

If the library is initialized with autoUpdate to false this function must be used after some print's.



My favorites and dislikes

Playing with all these display I found some I really likes and some I definitely did not like.

Favorites

DSC_7200

HT1621 6 digit LCD: Very clear LCD display with the background light and fairly low power consumption, it have mounting holes.

DSC_8054

This display has large digits, it includes mounting holes (but they are small) and they can be placed next to each other for longer display. It is possible to use both colon and decimal point on this display.

DSC_7197

HS595 static: Completely static display and multiple modules of different sizes can be connected, there is mounting holes. Only dislike is that there must be some spacing between modules, it is not possible to make a 5+ digit display.

DSC_6628

MAX7219: I like to have 8 digits and it is possible to adjust the brightness, the displays are a bit small. The module has mounting holes.

DSC_6624

TM1637 4 digit: These are nice display, but you really have to search if you want a version with decimal point instead of colon. Just because both is present on the display, do not mean they are both supported. It has brightness adjustment and mounting holes.



Dislikes

DSC_7191

HC164: This display flickers while updating it and requires interrupt.

DSC_7194 DSC_6631

HC595: These displays requires interrupt.

DSC_7203

HT1621 12 digit LCD: It has no background light and all the indicators are Chinese words.

DSC_7751

TM1638 24 keys: I do not like that it requires a 1kOhm pull-up. The display on/off switch is a bit silly and the buzzer do not work. I did not see any documentation on the communication protocol for the microprocessor.



Conclusion

If I can spare 3 pins on a Arduino processor it is basically possible to use any display with it, with a very small software change (un/comment some #define), at least if the number of digits are the same. It will also work if the display has more digits, but I would probably want do redo the display layout then.
If I want more than one display on a Arduino I can either chain a couple of MAX7219/Static HC595 or instantiate multiple copies of the driver and have displays on different pins.

I have added a lot of shorthand routines, they do not take up any extra space in the Arduino and make it a bit easier to use the display.



Notes and download

Over time I will probably add more displays to this library. If manufacturer or dealers would like me to support a display I will probably do it if they give me one or two displays of that type. The library is for displays with a 2 or 3 wire interface, do not ask about support for displays that needs more wires.
My email is "info" at my domain "lygte-info.dk"

Version: 1.01: Fixed serious bug in showChar (Oops) and added LCD API.
Version: 1.02: Add support for timer1 to 5 on the Mega2560, marked most of LEDLCDAPIDriver inline and change the init function.
Version: 1.03: Added support for 4 digit HT16K33 display with both colon an point. Both HT16K33 drivers now support multiple displays.

Download as library This includes examples and highlights of keywords

Download as sketch This is a skeleton project with the driver included.