Go Down

Topic: i2c EEPROM modifier with LCD interface (Read 675 times) previous topic - next topic

FalconFour

Oct 20, 2010, 05:48 pm Last Edit: Oct 20, 2010, 05:59 pm by FalconFour Reason: 1
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. ;) 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. :)

Without further adieu...
Code: [Select]
//#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. ;)

Extra special thanks to you (specifically p. 38-40), and you, and you for helping me with the distinction between I2C device address and data address... :D

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy