Library for double height display on character LCDs

There have been a few projects to get double height characters on LCD displays, but none that I found particularly easy to use. I’ve created two libraries which hopefully make this easy.

One library, BigCrystal is for LCDs connected directly to an Arduino, whilst the other, BigCrystalTWI is for LCDs connected via I2C. The code is based on the original fonts and code written by Michael Pilcher, documented in an old forum post.

I’ve put additional documentation on my blog.

I no longer have an I2C backpack for my LCD, so couldn’t test the BigCrystalTWI library. I’d appreciate it if someone with one handy can give the library a quick test and confirm it all works.

nice work (not tested)

two small points:

  • several small loops using ints where an uint8_t would be enough (less RAM and a usec faster:)
    for (int i = 0; i < 8; i++)

  • uint8_t* table = getTable(tableCode);
    does not check the possible NULL return value.

You might want to take a look at this LCD library: https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home Because of the way it is layered, you can put a library class on top of it and now it will work on all the interface layers supported below, 4bit parallel, shiftregisters, i2c, etc...

Here is a bitmap library that sits on top of fm's library: http://code.google.com/p/arduino-lcd-bitmap/

--- bill

Thanks for the review Rob. I’ve incorporated both of your comments and pushed to guthub.

bperrybap: You might want to take a look at this LCD library: https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home

Thanks for the head's up Bill, I wish I'd known about that library earlier. It sounds like something that should be considered to replace the current LiquidCrystal library in the core.

I'll have a go at using new-liquidcrystal as the base for my code and see how it turns out.

Hi Greg,
I have access to a 16*2 i2C LCD. I quickly downloaded your library just before going to work today but was not quite sure how to set up the i2C address. From memory my device 12C address was 0 x 27. I realise that I will need to change the LCD size to (16, 2) but exactly where to I insert my device i2C address in your AllCharacters code. If you let me know I will try it when I get home today,
Thanks Pedro.

#include <Arduino.h>
#include <BigFont.h>
#include <Wire.h>
#include <LiquidTWI.h>
#include <BigCrystalTWI.h>

// Set up to your i2c address
BigCrystalTWI lcd(0);

void setup() {
  lcd.begin(20, 4); // Set to your LCD size
}

Hi Pedro,

Thanks for volunteering to test the library. You just need to change the constructor that creates the lcd. So change

BigCrystalTWI lcd(0);

to

BigCrystalTWI lcd(0x27);

I played with some big font code that looks like it originated from the same code base you started with. I did a few tweaks on some numbers, to make them look better (at least to my eyes). Here are the mods for the character table: (See the ones with my initials on them: "bap")

    0,  1,  2,  3,  4,  5,      //  0x30    0
//  1,  2,  32, 32, 5,  32,     //  0x31    1 (bad: looks like a seven)
    1,  2,  32, 4, 255, 4,      //  0x31    1 (looks better - bap)
//  6,  6,  2,  3,  7,  7,      //  0x32    2 (doesn't look good if rows have spaces)
    6,  6,  2,  3,  4,  4,      //  0x32    2 (looks better - bap)
//  6,  6,  2,  7,  7,  5,      //  0x33    3
    6,  6,  2,  4,  4,  5,      //  0x33    3 (looks better - bap)
    3,  4,  2,  32, 32, 5,      //  0x34    4
//  0,  6,  6,  7,  7,  5,      //  0x35    5 (same as 'S')
//  255,6,  6,  7,  7,  5,      //  0x35    5
    255,6,  6,  4,  4,  5,      //  0x35    5 (looks better - bap)
//  0,  6,  6,  3,  7,  5,      //  0x36    6
    0,  6,  6,  3,  4,  5,      //  0x36    6 (looks better - bap)
    1,  1,  2,  32, 0,  32,     //  0x37    7
//  0,  6,  2,  3,  7,  5,      //  0x38    8
    0,  6,  2,  3,  4,  5,      //  0x38    8 (looks better - bap)
    0,  6,  2,  32, 32, 5,      //  0x39    9
//  32,  1, 32, 32,  4, 32,     //  0x3A    :
    32,  111,   32, 32,  111,   32,     //  0x3A    : (looks better - bap)

Have a look, see what you think.

--- bill

Hi Greg, I am at work at the moment so I only have access to the IDE. I installed the BigCrystal TWI , Big Crystal and the Arduino-LiquidTWI libraries into my Arduino libraries folder and when I tried to verify the AllCharacters code in the BigCrystalTWI folder I get these errors -

In file included from AllCharacters.ino:5:
C:\Program Files\arduino-1.0.3\libraries\BigCrystalTWI/BigCrystalTWI.h:7: error: expected class-name before '{' token
AllCharacters.ino: In function 'void setup()':
AllCharacters:11: error: 'class BigCrystalTWI' has no member named 'begin'
AllCharacters.ino: In function 'void loop()':
AllCharacters:22: error: 'class BigCrystalTWI' has no member named 'setCursor'
AllCharacters:23: error: 'class BigCrystalTWI' has no member named 'write'
AllCharacters.ino: In function 'void clear()':
AllCharacters:30: error: 'class BigCrystalTWI' has no member named 'setCursor'
AllCharacters:31: error: 'class BigCrystalTWI' has no member named 'print'
AllCharacters:32: error: 'class BigCrystalTWI' has no member named 'setCursor'
AllCharacters:33: error: 'class BigCrystalTWI' has no member named 'print'

What am I missing here, Pedro

Hey Pedro, BigCrystal is dependent on LiquidTWI. You need to have all the libraries installed as noted in your sketch before it will compile.

Hi arduinodib, I have all three installed

Pedro147: I installed the BigCrystal TWI , Big Crystal and the Arduino-LiquidTWI libraries into my Arduino libraries folder

Edit - I got it to compile; just had to remove the hyphen from the LiquidTWI library name, so when I finish work I will try it out with the LCD 8)

Hmmm. Well the error you're seeing is because it can't find the LiquidTWI library for some reason.

I seem to have a bit of trouble with library names having numbers or other characters in them, but it now compiles so shortly when work finishes and life resumes I will see if it uploads and does it's stuff XD Watch this space

Well as stated this code compiled o.k. but when uploaded showed nothing on the screen.

#include <Arduino.h>
#include <BigFont.h>
#include <Wire.h>
#include <LiquidTWI.h>
#include <BigCrystalTWI.h>

// Set up to your i2c address
BigCrystalTWI lcd(0x27);

void setup() {
  lcd.begin(16, 2); // Set to your LCD size
}

void loop() {
  // Displays all characters is big front from 0x00 (space) to 0x5A (Z)
  for (char c = 0x20; c <= 0x5A; c++) {
    // Clear out the maximum width so that pars of wider
    // characters are removed
    clear();

    lcd.writeBig(c, 0, 0);
    lcd.setCursor(7, 0);
    lcd.write(c);
    delay(1000);
  }
}

void clear() {
  for (int i = 0; i < 5; i++) {
    lcd.setCursor(i, 0);
    lcd.print(' ');
    lcd.setCursor(i, 1);
    lcd.print(' ');
  }
}

I then tried out two other i2c codes that I have previously used and they both displayed. I do not have pullups on the data lines but this is not affecting the other two codes or any that I have ever run on this display. So I don’t know what is going on. Any suggestions?

Hi Pedro,

I suspect this may have to do with the constructor in the underlying LiquidTWI code.

LiquidTWI::LiquidTWI(uint8_t i2cAddr) {
    if (i2cAddr > 7) i2cAddr = 7;
    _i2cAddr = i2cAddr; // transfer this function call's number into our internal class state
    _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; // in case they forget to call begin() at least we have something
}

It appears that any i2c addresses greater than 7 get set to 7. Your address of 0x27 is being overwritten. Try commenting out the first line in the LiquidTWI constructor to see if that works.

bperrybap: I played with some big font code that looks like it originated from the same code base you started with. I did a few tweaks on some numbers, to make them look better (at least to my eyes).

Thanks Bill.

They look better to me too. I linked all the changes, especially for the 1 as it's now wider to match the other numbers. I've incorporated all of your changes to the library.

I think that your technique of keeping a thinner centre horizontal stroke can work for some of the letters too. I'll have a look at that in the next couple of days.

which LiquidTWI library are you guy using? The ones I've seen are for the AdaFruit backpack that uses the MCP23008 i2c i/o expander vs the PCF8574 expander that is used in most i2c to hd44780 backpacks out there. The LiquidTWI libraries that I've seen also assume a base address, which is why the address in the constructor is only the lower 3 bits.

// now we set the GPIO expander's I/O direction to output since it's soldered to an LCD output.
Wire.beginTransmission(MCP23008_ADDRESS | _i2cAddr);

and MCP23008_ADDRESS is defined to be 0x20

While I've got an update for an i2c io class for fm's library that supports both PCF8574 and MCP23008 (It auto-detects which chip you have) it isnt yet available.

--- bill

gregington: LiquidTWI::LiquidTWI(uint8_t i2cAddr) { if (i2cAddr > 7) i2cAddr = 7; _i2cAddr = i2cAddr; // transfer this function call's number into our internal class state _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; // in case they forget to call begin() at least we have something }

Greg, so I should only comment out the whole four code lines above should I?

Bill - I used this one Greg had a link to in his blog https://github.com/Stephanie-Maks/Arduino-LiquidTWI

Pedro,

On Bill's prompting, I've had a closer look at the LiquidTWI library, and the original address of 0x27 should have worked. The address specified in the constructor is anded with 0x20. The code transforms any address higher than 7 to 7, which when anded with 0x20 gives you back the correct address of 0x27.

You could try using 7 as the address and let the LiquidTWI library add the base address. I suspect you'll find the same result, but it might be worth a try.

So I'm at a bit of a loss, but I'll have more thorough look when I'm back from work.

I will try that after work Greg and let you know how I go. If not just let me know if you would like me to try any other methods etc. Pedro

Edit - I set it at 0x07 but still no go