Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Interfacing / Re: JohnZero - Port Expander - I2C - LCD on Playground on: December 12, 2008, 06:43:21 pm
Sorry for the late reply, I don't get PMs in email :-(

This is my latest version, from 2007, it might work or not, but I am sure it worked for me. Put it under arduino-XXXX/hardware/libraries/LCDI2C4bit.cpp

LCDI2C4Bit.cpp file:
Code:
#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

//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);
  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
  SetMCPReg(myAddress,0x00,0x00); // set IOREG (0x00) to 0
  //
  delay(50);
  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);
}

void LCDI2C4Bit::cursorTo(int line_num, int x) {
  commandWrite(CMD_HOME);
  int targetPos = x + line_num * myWidth;
  for ( int i = 0; i < targetPos; i++)
    commandWrite(0x14);
}

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


LCDI2C4bit.h file:
Code:
#ifndef LCDI2C4Bit_h
#define LCDI2C4Bit_h

#include <inttypes.h>

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

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 );

  //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

Example use:
Code:
#include <Wire.h>
#include <LCDI2C4Bit.h>

/*
;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 - E1
*/


int ADDR = 0xA7;

byte x = 0;
byte data = 1;
byte c;
int val;

LCDI2C4Bit lcd = LCDI2C4Bit(ADDR,4,20);

void setup()
{
  Serial.begin(9600);
  Wire.begin(); // join i2c bus (address optional for master)
  lcd.init();
  lcd.printIn("test");
}

void loop()
{
/*  lcd.backLight(true);
  delay(1000);
  lcd.backLight(false);
  delay(1000);*/
  
  val = analogRead(0);
  if (val != 1023) {
    Serial.print(", ");
    Serial.println(val,DEC);
    delay(300);
  }
}
2  Forum 2005-2010 (read only) / Interfacing / Re: Arduino and 1-wire on: October 24, 2007, 12:14:39 pm
Thank you for the lovely OneWire library, it works well!

The only problem I had with it is that it really eats up SRAM. The CRC tables use about 256 bytes of RAM (from the 1 kbytes the atmega168 has).
On my system I have temporarily commented out that section, but I think a good solution would be to use PROGMEM for the CRC tables. (Some links about PROGMEM:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003
http://tinker.it/now/2007/03/04/avr-and-of-course-arduino-ram-limits-overcome/
http://www.arduino.cc/en/Reference/PROGMEM )
3  Forum 2005-2010 (read only) / Interfacing / Re: Wire Library 32 byte limit on: November 07, 2007, 06:55:02 pm
Atmega168 has 1kbyte SRAM which is very scarce... You have to be careful!
Changing that 32 bytes to much more might eat up too much useful RAM. But I think you could change it to be a bit bigger.

About the I2C EEPROM, I have some code/functions here. Actually, you can only write 30 bytes, because 2 bytes are the offset.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1192425904/3#3

For other types of flash, look in the Playground/wiki (Dataflash)
4  Forum 2005-2010 (read only) / Development / Re: boarduino released on: November 03, 2007, 11:28:04 am
I got my board kit, too. Works wonderful, very nice and small design!
Only problem was while following the soldering tutorial (guide), the two "big" capacitors instructions were mixed up, I think.
Other than that, everything went fine!
5  Forum 2005-2010 (read only) / Interfacing / Re: About LED drivers IC on: December 13, 2007, 06:06:17 pm
I still think the 7219 might be a good option. It's about 3.77 EUR (from 25 pieces up) at a site I found: www.tme.eu
And you need next to nothing for the 7219, easier to fit, just one resistor needed, etc.
(This is not an advertisement, I bought twice from them and it's fast and mostly cheap :-)
6  Forum 2005-2010 (read only) / Interfacing / Re: external memory on: October 24, 2007, 03:41:56 pm
I2C EEPROMs are also a possibility.
Eg. AT24C256 from Atmel (256 kbyte EEPROM)

There's not too much code on the Arduino website about I2C EEPROM interfacing, but I could write my own. Maybe I'll post it on the wiki soon. If anyone is having the same issues as me looking for I2C EEPROM code, here's an excerpt of my code:

Code:
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8)); // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
  int rdata = data;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8)); // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.send(rdata);
  Wire.endTransmission();
}
Pages: [1]