i2c LCD Display

For those of you that are interested, I have created a library for the i2c LCD display that is available from web4robot.com. I have not financial interest in web4robot, I purchased one of their displays, and thought it would be nice to have a library.

The following commands are supported.

init() Init the LCD and library functions, Clears the display, turns off the cursors

commandWrite(command) Write a command not supported yet in the library to the display

position(Row, Column) Move the cursor to position valid range is Row[0-3], Column[0,19]

print(char) Send the single character char to the display at the cursor position.

println(string) Send the String to the display at the cursor position.

clear() Clear the display and place the cursor at 0,0

home() Home the cursor to 0,0 but do not clear the display

on() Turn the LCD display on

off() Turn the LCD display off

cursor_on() Turn the blinking line cursor on

cursor_off() Turn the blinking line cursor off

blink_on() Turn the blinking block cursor on

blink_off() Turn the blinking block cursor on

left() Move the cursor to the left

right() Move the cursor to the right

keypad() Read a value from the keypad. Returns 0 if no key press is in the buffer

Dale

I forgot to add a link to my webpage that has the library.
http://www.wentztech.com/radio/arduino/projects.html

Nice work :0)

Nice one.

Ive got one of there lcd controlers as well but had trouble getting it working.
May I see your code and give it a try?

Thanks

Gordon

Gordon,

I am sorry I forgot to put the link in when I posted this. I have added it to the bottom of the message. All the source code and samples are included in the zip file.

Dale

Thanks,

Ive got a realtime clock on the bench running with I2C. Ill try your library in conjunction with that over the next couple of days.

Gordon

Nice project :slight_smile: I've made a similar library myself for the I2C-LCD-driver from ByVac. One suggestion though - you can inherit the print-class so you don't have to implement your own print. This will let you print strings, integers and floats for "free" :slight_smile:

Guess what Ive got one of those byvac boards as well.
Any chance you can post your library?

Maybe there is some common ground and we can merge the libraries.
I should imagine the main differences will be the command codes and the rest very similar.
They both support keyboard input as well.

Gordon

Guess what Ive got one of those byvac boards as well.
Any chance you can post your library?

Sure, no problem. I have only used it for one small project, so it's not tested very well. It does work fine for me, but consider this beta software. It's mostly compatible with LiquidCrystal, and also contains some methods for reading and writing the EEPROM on the controller. This will let you store strings on the controller and enable you to print directly from this, thus saving precious flash on the Arduino.

Btw I also got one of these: http://www.byvac.com/bv/bv4219.htm. I'm in the process of writing a library for this as well.

ByVacLCD.cpp:

#include "ByVacLCD.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "WProgram.h"
#include <Wire.h>

#define BACKLIGHT_ON 0
#define BACKLIGHT_OFF 1
#define LCD_ON 1
#define LCD_OFF 0

ByVacLCD::ByVacLCD(uint8_t adr, uint8_t columns, uint8_t rows)
{
  _adr = adr;
  _columns = columns;
  _rows = rows;
}

void ByVacLCD::init()
{
  delay(15);
  command(0x0c); // Display on, cursor off, blink off
  command(0x06); // Increment mode, shift on
  clear();
}

void ByVacLCD::clear()
{
  command(0x01);  // clear display, set cursor position to zero
  delayMicroseconds(2000);
}

void ByVacLCD::home()
{
  command(0x02);  // set cursor position to zero
  delayMicroseconds(2000);
}

void ByVacLCD::setCursor(int col, int row)
{
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  command(0x80 | (col + row_offsets[row]));
}

void ByVacLCD::command(uint8_t value) {
  send(value, LOW);
}

void ByVacLCD::write(uint8_t value) {
  send(value, HIGH);
}

void ByVacLCD::send(uint8_t value, uint8_t mode) {
  Wire.beginTransmission(_adr);
  if (mode) // Write data
    Wire.send(2);
  else      // write command
    Wire.send(1);

  Wire.send(value);
  Wire.endTransmission();
  delayMicroseconds(45);
}

void ByVacLCD::backlightOn()
{
  Wire.beginTransmission(_adr);
  Wire.send(3);
  Wire.send(BACKLIGHT_ON);
  Wire.endTransmission();
}

void ByVacLCD::backlightOff()
{
  Wire.beginTransmission(_adr);
  Wire.send(3);
  Wire.send(BACKLIGHT_OFF);
  Wire.endTransmission();
}

void ByVacLCD::displayOn()
{
  Wire.beginTransmission(_adr);
  Wire.send(5);
  Wire.send(LCD_ON);
  Wire.endTransmission();
}

void ByVacLCD::displayOff()
{
  Wire.beginTransmission(_adr);
  Wire.send(5);
  Wire.send(LCD_OFF);
  Wire.endTransmission();
}

// Upload a user-defined character (5x8)
// See http://www.quinapalus.com/hd44780udg.html for
// character generator.
void ByVacLCD::uploadUdef(uint8_t character, uint8_t *data)
{
  uint8_t c = character << 3, i;

  for (i = 0; i < 8; i++)
  {
    command(0x40 | c | i);
    write((uint8_t)data[i]);
  }
}

void ByVacLCD::printFromEEPROM(uint8_t addr)
{
  Wire.beginTransmission(_adr);
  Wire.send(4);
  Wire.send(addr);
  Wire.endTransmission();
  delayMicroseconds(45);
}

uint8_t ByVacLCD::EEPROM_startAdr()
{
  Wire.beginTransmission(_adr);
  Wire.send(6);
  Wire.endTransmission();
  Wire.requestFrom((int)_adr, 1);
  if (Wire.available() == 1)
    return Wire.receive();

  return 0;
}

uint8_t ByVacLCD::EEPROM_endAdr()
{
  Wire.beginTransmission(_adr);
  Wire.send(0x93);
  Wire.endTransmission();
  Wire.requestFrom((int)_adr, 1);
  if (Wire.available() == 1)
    return Wire.receive();
    
  return 0;
}

uint8_t ByVacLCD::EEPROM_read(uint8_t addr)
{
  Wire.beginTransmission(_adr);
  Wire.send(0x90);
  Wire.send(addr);
  Wire.endTransmission();
  Wire.requestFrom((int)_adr, 1);
  if (Wire.available() == 1)
    return (byte)Wire.receive();
  
  return 0;
}

void ByVacLCD::EEPROM_write(uint8_t addr, char *data)
{
  Wire.beginTransmission(_adr);
  Wire.send(0x91);
  Wire.send(addr);
  Wire.send(data);
  Wire.send('\0');
  Wire.endTransmission();
}

void ByVacLCD::EEPROM_write(uint8_t addr, char data)
{
  Wire.beginTransmission(_adr);
  Wire.send(0x91);
  Wire.send(addr);
  Wire.send(data);
  Wire.endTransmission();
}
/*
** Library for the ByVac BV4208 I2C-driver for HD44780 LCD displays.
** See www.byvac.com for datasheet.
*/

#ifndef ByVacLCD_h
#define ByVacLCD_h

#include <inttypes.h>
#include "Print.h"

class ByVacLCD : public Print {
public:
  ByVacLCD(uint8_t, uint8_t, uint8_t);
  void init();
  void clear();
  void home();
  void setCursor(int, int);
  virtual void write(uint8_t);
  void command(uint8_t);
  void backlightOn();
  void backlightOff();
  void displayOn();
  void displayOff();
  void uploadUdef(uint8_t, uint8_t*);
  void printFromEEPROM(uint8_t);
  uint8_t EEPROM_startAdr();
  uint8_t EEPROM_endAdr();
  uint8_t EEPROM_read(uint8_t addr);
  void EEPROM_write(uint8_t addr, char *data);
  void EEPROM_write(uint8_t addr, char data);

private:
  void send(uint8_t, uint8_t);
  uint8_t _adr;
  uint8_t _columns;
  uint8_t _rows;  
};

#endif

keywords.txt:

#######################################
# Syntax Coloring Map For ByVacLCD
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

ByVacLCD      KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

init      KEYWORD2
clear      KEYWORD2
home      KEYWORD2
print      KEYWORD2
setCursor      KEYWORD2
backlightOn      KEYWORD2
backlightOff      KEYWORD2
displayOn      KEYWORD2
displayOff      KEYWORD2
uploadUdef      KEYWORD2
printFromEEPROM      KEYWORD2
write      KEYWORD2
command      KEYWORD2
EEPROM_startAdr      KEYWORD2
EEPROM_endAdr      KEYWORD2
EEPROM_read      KEYWORD2
EEPROM_write      KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

Perfect timing, Dale: I just got mine a few days ago, and was lamenting the lack of a driver :wink:

Are you planning to do further development on it? I'm interested in adding code support its bargraph and custom character features, and would like to coordinate development with you if you're going to be changing code.

Thanks,

Ran

I have updated the drivers for the i2c LCD's

I have changed some of the commands to bring them in line with the crystal drivers. They have been optimized, for speed and code size. I have also inherited the print-class as recommended in this thread so you can do things like lcd.print(int,DEC)

I am willing to support other intelligent i2c LCD character displays within the library, if you manufacture a display and would like to send me a sample to write and test with please contact me.

i2c Library home: LCD i2c Libraries for Arduino | KB9JJA

Dale

great! I am using the original library with my 20X4 display....works great.

Hello, I have got the LCD 4x20 display, LCD03 - I2C, from robot-electronics.co.uk. The display is working well, after some testing, but not the keypad that is interfaced on backside of the display. Is there anyone who have got the keypad at LDC03 working on I2C?

The docs for that Robot Electronics module say that the keypad only works in serial mode, so the answer to your question is almost certainly "no".

Ran

I've written some new routines to use the graph features of the web4robot module, and am testing them now. I should have them ready for release in the next day or so.

I've written one example program that reads the values of the analog inputs and graphs them. Does anyone have suggestions for other examples?

Ran

Ran,

If you would send me your code and I will include them in the library.

I have received a 4 line display, and have tested it with the library. It works as is, but I have some changes that I want to make to make things more universal.

Dale

I'll contact you through a PM to make arrangements to get you the code.

I'm seeing a lot of display corruption when running my example. I think it may be because I left out what I thought were "wasted" calls to delay() after write operations. Did you see similar problems?

Ran

Yes that display requires a delay of 50ms for most commands, with the exception of the goto cursor position, it requires a delay of 100, this is not in the documentation. The delay is after the command has been transmitted on the buss. Hope this helps. If I get time this weekend I will get the graphing added to the library which takes care of all this for you.

Dale

Ran,

If you would send me your code and I will include them in the library.

I have received a 4 line display, and have tested it with the library. It works as is, but I have some changes that I want to make to make things more universal.

Dale

This is great to hear I just ordered one of these tonight!

:slight_smile:

"LCD03 - I2C, from robot-electronics.co.uk". I got the answer "no" but I just got a mail from UK that says:
"You can read the keypad from registers 1 and 2 in I2C mode."

OK, so it is a question how read the registers... Any idea?

You probably need something similar to the keypad() function in Dale's library to read the registers from the Robot Electronics module.

Ran