Pages: 1 [2]   Go Down
Author Topic: My most beloved topic - the PCF8574 with a HD44780  (Read 3116 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi! I have a modified LCDI2C4Bit that runs very well with PCF8574 and HD44780

I can post it here if you like!  smiley-wink
Logged

Bonn, Germany
Offline Offline
God Member
*****
Karma: 2
Posts: 903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

that'd be just awesome, why invent the wheel a second time? ;0)
Logged

Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupid[ch8230] and I went ahead

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nachtwind, I half expected to hear you say that you would prefer to try to do it yourself for the learning experience smiley-wink
It would be good to see what angelito has done. Perhaps I can convince him to do a version for the LiquidCrystal library to save me doing it
Logged

Bonn, Germany
Offline Offline
God Member
*****
Karma: 2
Posts: 903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

well... i am fiddeling with that code for more than a week now.. and somehow its nothing hard at all, so i guess that i can learn more from watching how a working version was done than to keep trying to figure out what i have done wrong..
I guess t is something quite simple, my bet is on the Nibble stuff, yet i cant figure it out and so.. well, i would like to see how it is done ;0)
Logged

Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupid[ch8230] and I went ahead

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I agree, I was just teasing  smiley-wink
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi! Here it's the code, I modified original library from http://www.arduino.cc/playground/Code/I2CPortExpanderAndLCDs to code it and added some methods to manage scroll and cursor settings.

It's only tested with 2x16 LCD and will be need to rewrite cursorTo() method for different size LCD, the original method don't runs with PCF8574, it never go to second line so I have to rewrite it completely, but I don't have different LCD to try it. You can find visible DDRAM addresses for diferent LCD in http://home.iae.nl/users/pouweha/lcd/lcd0.shtml#visible_ddram

The rest of the code is almost the same (diferences are commented to locate it easily), the wiring it's the same that you can find in the original lib example.

Hope it helps

If I got time tonight I will look your lib code


LCDI2C4Bit.h
Code:
#ifndef LCDI2C4Bit_h
#define LCDI2C4Bit_h

#include <inttypes.h>

// IMPORTANT! Wire. must have a begin() before calling init()

/*
 *  Modified 21-Feb-2009 for use with PCF8574
 *  Angel Sancho <angelitodeb@gmail.com>
 *
 *  Original source from:
 *  http://www.arduino.cc/playground/Code/I2CPortExpanderAndLCDs
 */

class LCDI2C4Bit {
public:
  LCDI2C4Bit(int devI2CAddress, int num_lines, int lcdwidth);
  void commandWrite(int command);
  void init();
  void print(int value);
  void printIn(char value[]);
  void clear();
  void backLight( bool turnOn );

  // New methods to manage cursor settings and scroll with PCF8574
  void setInvisibleCursor();
  void setVisibleCursor();
  void setBlinkingCursor();
  void scrollRight();
  void scrollLeft();
  //--


  //non-core---------------
  void cursorTo(int line_num, int x);
  //void leftScroll(int chars, int delay_time);
  //end of non-core--------

  //4bit only, therefore ideally private but may be needed by user
  //void commandWriteNibble(int nibble);

private:
  //void pulseEnablePin();
  //void pushNibble(int nibble);
  //void pushByte(int value);

  int myNumLines;
  int myWidth;
  int myAddress;
};

#endif

LCDI2C4Bit.cpp
Code:
/*
 *  Modified 21-Feb-2009 for use with PCF8574
 *  Angel Sancho <angelitodeb@gmail.com>
 *
 *  Original source from:
 *  http://www.arduino.cc/playground/Code/I2CPortExpanderAndLCDs
 */

#include "LCDI2C4Bit.h"
#include <Wire.h>

extern "C" {
  #include <stdio.h>  //not needed yet
  #include <string.h> //needed for strlen()
  #include <inttypes.h>
  #include "WConstants.h"  //all things wiring / arduino
}

//command bytes for LCD
#define CMD_CLR 0x01
#define CMD_RIGHT 0x1C
#define CMD_LEFT 0x18
#define CMD_HOME 0x02
#define CMD_CURSOR_RIGHT 0x14

//stuff the library user might call---------------------------------

//constructor.  num_lines must be 1 or 2, currently.

byte dataPlusMask = 0; // TODO!!!

LCDI2C4Bit::LCDI2C4Bit( int devI2CAddress, int num_lines, int lcdwidth) {
  myNumLines = num_lines;
  myWidth = lcdwidth;
  myAddress = devI2CAddress;
}

void SetMCPReg( byte deviceAddr, byte reg, byte val ) {
  Wire.beginTransmission(deviceAddr);
  //Wire.send(reg);  // not need this for PCF8574
  Wire.send(val);
  Wire.endTransmission();
}

void SendToLCD( byte deviceAddr, byte data ) {
  data |= dataPlusMask;
  SetMCPReg(deviceAddr,0x0A,data);
  data ^= 0x80; // E
  delayMicroseconds(1);
  SetMCPReg(deviceAddr,0x0A,data);
  data ^= 0x80; // E
  delayMicroseconds(1);
  SetMCPReg(deviceAddr,0x0A,data);
  delay(1);

}

void WriteLCDByte( byte deviceAddr, byte bdata ) {
  SendToLCD(deviceAddr,bdata >> 4);
  SendToLCD(deviceAddr,bdata & 0x0F);
}

void LCDI2C4Bit::init( void ) {
  dataPlusMask = 0; // initial: 0
  //SetMCPReg(myAddress,0x05,0x0C); // set CONFREG (0x05) to 0   // not need this for PCF8574
  //SetMCPReg(myAddress,0x00,0x00); // set IOREG (0x00) to 0   // not need this for PCF8574
  //
  //delay(50);      // not need this for PCF8574
  SendToLCD(myAddress,0x03);
  delay(5);
  SendToLCD(myAddress,0x03);
  delayMicroseconds(100);
  SendToLCD(myAddress,0x03);
  delay(5);
  SendToLCD(myAddress,0x02);
  WriteLCDByte(myAddress,0x28);
  WriteLCDByte(myAddress,0x08);
  WriteLCDByte(myAddress,0x0C); // turn on, cursor off, no blinking
  delayMicroseconds(60);
  WriteLCDByte(myAddress,0x01); // clear display
  delay(3);
}

void LCDI2C4Bit::backLight( bool turnOn ) {
  dataPlusMask |= 0x40; // Lights mask
  if (!turnOn) dataPlusMask ^= 0x40;
  SetMCPReg(myAddress,0x0A,dataPlusMask);
}


void LCDI2C4Bit::print( int value ) {
  dataPlusMask |= 0x10; // RS
  WriteLCDByte(myAddress,(byte)value);
  dataPlusMask ^= 0x10; // RS
}

void LCDI2C4Bit::printIn( char value[] ) {
  for ( char *p = value; *p != 0; p++ )
    print(*p);
}

void LCDI2C4Bit::clear() {
  commandWrite(CMD_CLR);
}

//  Completely modified for PCF8574
//  Original method not runs correctly with this IC and was impossible to put
//  cursor on second line. With this new method you can put it anywhere and
//  quickly than the other, because it only write once to PCF8574. Although it
//  is only tested with 2x16 LCD and will be need to change it for different
//  size LCD. Here you can find visible DDRAMM addresses for different LCD:
//  http://home.iae.nl/users/pouweha/lcd/lcd0.shtml#visible_ddram
void LCDI2C4Bit::cursorTo(int line_num, int x) {
  int targetPos;

  targetPos = x + ((line_num-1) * (myWidth-1));

  if(targetPos > (myWidth-1)) {
     commandWrite( 0xC0 + (targetPos-myWidth) );  // 0xC0 = start of second line in 2x16 LCD
  } else {
     commandWrite( 0x80 + targetPos );  // 0x80 = start of first line in 2x16 LCD
  }
}

void LCDI2C4Bit::commandWrite( int command ) {
  // RS - leave low
  WriteLCDByte(myAddress,command);
  delay(1);
}

//  ++
//  New methods to manage cursor settings and scroll for PCF8574
void LCDI2C4Bit::setInvisibleCursor() {
   WriteLCDByte(myAddress,0x0C);
   delay(1);
}

void LCDI2C4Bit::setVisibleCursor() {
   WriteLCDByte(myAddress,0x0E);
   delay(1);
}

void LCDI2C4Bit::setBlinkingCursor() {
   WriteLCDByte(myAddress,0x0F);
   delay(1);
}

void LCDI2C4Bit::scrollRight() {
   WriteLCDByte(myAddress,0x1E);
   delay(1);
}

void LCDI2C4Bit::scrollLeft() {
   WriteLCDByte(myAddress,0x18);
   delay(1);
}
//  --
Logged

Bonn, Germany
Offline Offline
God Member
*****
Karma: 2
Posts: 903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for that code, it looks much like what i had in mind with mine, especially the part in it that works - that was one of my main goals in imy design ;0)
Anyway, would you mind if i try to change it a bit to add 4x20 support to it and repost it in here?
Logged

Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupid[ch8230] and I went ahead

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Feel free to change it what you want! I modified it from original LCDI2C4bit and this one came from LCD4bit.. and I think it is GPL (I hope it  :smiley) and improving libraries is good for all of us that use arduino
« Last Edit: February 25, 2009, 06:07:25 pm by angelito » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mem, I didn't look on LiquidCrystal library until I read it on your post. I used LCD4bit some months ago and the past week I need it again and directly search for an I2C interface for it and found LCDI2C4bit

I have been viewing LiquidCrystal and definetely it is much "finished" than the others, thanks a lot!
Logged

Bonn, Germany
Offline Offline
God Member
*****
Karma: 2
Posts: 903
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

*unintended push*

Hm, is there any documentation about connecting the HD44780 to the I2C expander somewhere? I tried following the original libraries wiki entry, but to no success... i know that lib works, but i seem unable to reproduce this ><
Logged

Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupid[ch8230] and I went ahead

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 thanks for the code Angelito,
only one question: the pin assignments for pcf8574 is equal to the original (MCP23008)?

*
;Connect the following pins from MCP23008 to LCD
;
;P0 - D4
;P1 - D5
;P2 - D6
;P3 - D7
;P4 - RS
;P5 - RW (not used, set to 0 to ground for write)
;P6 - Bl (backlight switch)
;P7 - E
*/
Logged

NL
Offline Offline
Newbie
*
Karma: 0
Posts: 37
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nachtwind,

Perhaps this can be of help.
http://www.xs4all.nl/~hmario/arduino/LiquidCrystal_I2C/

Cheers,

Mario
« Last Edit: March 23, 2010, 05:08:19 pm by Mario_H » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks Mario

I use your lib, works fine with my lcd modules

Ale

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
sercona audio
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

has anyone found that the philips (nxp) and TI versions are NOT compatible??  I cannot get the -a version from both places to work.

the NXP works fine.  uses the -a style addressing (0111xxx).  but the TI chip will not work!  others have reported this but I have not found any answers ;(

anyone??

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 94
sercona audio
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

replying to my own post smiley-wink

I found the problem.  see this:

 http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233786313/3#3

THAT solved it.

next time anyone runs into this, try the pullup trick.
Logged

Pages: 1 [2]   Go Up
Jump to: