Pages: [1]   Go Down
Author Topic: i2c EEPROM modifier with LCD interface  (Read 548 times)
0 Members and 1 Guest are viewing this topic.
Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Only thing missing is figuring out why PS2Keyboard doesn't work, although I'm sure the interface could be modified to use an array of button inputs...

Anyway, this is a program I whipped up overnight to reprogram a laptop battery that I'd replaced the cells in, that had a corrupted "last discharge" reading... honestly, going into it I had no idea what I was in for, but once I was able to pull the string "SANYO" out of the memory, based on the controller's data sheet, I knew I was in the right place. From there I edited the values for the "last discharge", and sure enough, after resetting the controller (disconnecting/reconnecting the leads), it worked beautifully.

But that's beside the point. smiley-wink This is a great little tool for reading small-capacity (8-bit address) EEPROMs. Taken from the code sample provided here (by the way, the link to ghettohax.com on that page is dead, anyone know an alternative? I had to wing-it on the I2C wiring), and modified for 8-bit addressing. Modify as desired for 16-bit addressing.

It's a little quick-and-dirty but I figured that, with all the internet-searching I was doing with this thing, this is the least I could do to contribute something back. smiley

Without further adieu...
Code:
//#include <PS2Keyboard.h>
#include <LiquidCrystal.h>
#include <Wire.h>

LiquidCrystal lcd(12,13,3,4,5,6);
//PS2Keyboard keyboard;

char lcdBuffer[17] = "                ";
char byteBuffer[3] = "00";
int result = 0;
char outputString[3] = "00";
byte cursorPos = 0;
byte addrByte = 0;
boolean rwMode = false;

//const int DataPin = 9;
//const int IRQpin =  2;

boolean redrawScreen = true;

void setup() {
  Wire.begin();
  delay(1000);
//  keyboard.begin(DataPin, IRQpin);
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.cursor();
  lcd.blink();
  lcd.setCursor(0,0);
  lcd.print("Addr   Data    R");
}

void loop() {
  if (Serial.available()) {
    // do sh#t if key pressed
    char c = Serial.read();
    if (c == '!') {
      if (rwMode) {
        // write
        addrByte = strtol(byteBuffer,0,16);
        result = strtol(outputString,0,16);
        i2c_eeprom_write_byte(B1010000,addrByte,result);
      } else {
        // read
        addrByte = strtol(byteBuffer,0,16);
        result = i2c_eeprom_read_byte(B1010000,addrByte);
        itoa(result,outputString,16);
      }
      redrawScreen = true;
      lcd.setCursor(14,0);
      lcd.print('!');
    } else if (c == '<') {
      if (cursorPos > 0) cursorPos--;
      if (cursorPos == 6) cursorPos = 1;
      lcd.setCursor(cursorPos,1);
    } else if (c == '>') {
      if (rwMode) {
        if (cursorPos < 8) cursorPos++;
        if (cursorPos == 2) cursorPos = 7;
      } else {
        if (cursorPos < 1) cursorPos++;
      }
      lcd.setCursor(cursorPos,1);
    } else if (c == 'w') {
      rwMode = rwMode?false:true;
      if (!rwMode && cursorPos > 1) cursorPos = 1;
      redrawScreen = true;
    } else {
      // detect and enter keys
      // catch numbers
      if (c >= '0') {
        if (c <= '9') {
          if (cursorPos > 1) outputString[cursorPos-7] = c;
          else byteBuffer[cursorPos] = c;
        }
      }
      // catch capital A-F
      if (c >= 'A') {
        if (c <= 'F') {
          if (cursorPos > 1) outputString[cursorPos-7] = c;
          else byteBuffer[cursorPos] = c;
        }
      }
      if (cursorPos < 1) cursorPos++;
      redrawScreen = true;
      lcd.setCursor(14,0);
      lcd.print(' ');
    }
  }
  // sh#t to do every loop
  if (redrawScreen) {
    lcd.setCursor(15,0);
    lcd.print(rwMode?'W':'R');
    lcd.setCursor(0,1);
    lcd.print("                ");
    lcd.setCursor(0,1);
    lcd.print(byteBuffer);
    lcd.setCursor(7,1);
    lcd.print(outputString);    
    lcd.setCursor(cursorPos,1);
    delay(100);
    redrawScreen = false;
  }
}

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

void i2c_eeprom_write_byte( int deviceaddress, byte eeaddress, byte data ) {
  int rdata = data;
  Wire.beginTransmission(deviceaddress);
//  Wire.send((int)(eeaddress >> 8)); // MSB
  Wire.send(eeaddress); // LSB
  Wire.send(rdata);
  Wire.endTransmission();
}

And a little Fritzing (also my first time playing with that), and a photo...


Usage:

Screen shows two indicators in the upper-right corner: "!" and R/W. The "!" will appear when the read/write operation was completed (otherwise, well... the Arduino locks up). R or W indicates if it's currently in Read or Write mode.

Currently, in a serial console, you can send the following commands:
"w" (lowercase w): switch between read/write mode
"!": perform the read/write action (displays the value in read mode, writes the "Data" value in write mode)
"<": move the cursor to the left
">": move the cursor to the right
0-9, A-F: modify the selected digit under the cursor. Data can only be modified in write mode.

And of course, any tips for improvement will only help my Arduino addiction. smiley-wink

Extra special thanks to you (specifically p. 38-40), and you, and for helping me with the distinction between I2C device address and data address... smiley-grin
« Last Edit: October 20, 2010, 10:59:50 am by FalconFour » Logged

Pages: [1]   Go Up
Jump to: