hi guys!
I recently bought a new arduino duemilanove and I need Your help for some easy stuffs.
I have one
-20X2 display
-One external eeprom (24c16, 24c256 in the future)
I would like to realize a device where pushing a botton I could see, on the display, some sentences written on the eeprom
Then, you could isolate the problem by disconnecting the LCD, and using the serial monitor instead.
A likely source of the problem, although this is strictly a guess since I don't know your code, is that you wrote a byte to the LCD, not a char,and the LCD interpreted it as a char.
Thank you PaulS for your help. As you said I post the code:
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//gestione eeprom esterna
#include <Wire.h>
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();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddresspage >> 8)); // MSB
Wire.send((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.send(data[c]);
Wire.endTransmission();
}
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;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.receive();
}
void setup() {
i2c_eeprom_write_byte( 0x50, 1, 'C' );
// set up the LCD's number of rows and columns:
lcd.begin(20, 2);
//lcd.setCursor(0,7);
// Print a message to the LCD.
char test;
test = i2c_eeprom_read_byte( 0x50, 1 );
lcd.print(test);
delay(1000);
}
void loop() {
}
When you do your "Serial.print", you should use the DEC or HEX qualifier to find the actual value of the char value, not the ASCII representation of it if you're in doubt about what it will print.
Another thing is that some EEPROMs require a delay or a wait-on-write-cycle-complete after a write operation, before you can read back the value.
However, I don't know if that's the problem here.
I executed the following tests:
I tried to disconnect the display, I put the delay after write operation, I used the serial monitor.
The code that I used is this:
#include <Wire.h>
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();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddresspage >> 8)); // MSB
Wire.send((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.send(data[c]);
Wire.endTransmission();
}
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;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.receive();
}
void setup() {
Serial.begin(9600);
byte vdm=(byte)'C';
i2c_eeprom_write_byte( 0x50, 1, vdm );
delay (2000);
char test;
test = char(i2c_eeprom_read_byte( 0x50, 1 ));
Serial.println("Begin TEST");
Serial.println(vdm);
Serial.println(test);
Serial.println("End TEST");
}
void loop() {
}
Now here's the code I'm using. There's no need to shift anything anywhere. This is actually using 5 chips, tested and works on them all, fairly easy to edit to get just one:
#include <Wire.h> // specify use of Wire.h library.
// address in 24ATC02 values from 0 to 255.
int BEGIN = 0;
int ADDR[] = {
0x50, 0x51, 0x52, 0x53, 0x54};
char* TEST[] = {
"Chip0", "Chip1", "Chip2", "Chip3", "Chip4"};
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // setup serial for output
// send test message "Arduino"
for(int x = 0; x < 6; x++){
Wire.beginTransmission(ADDR[x]); // connect to 24LC08 device address
Wire.send(BEGIN); // beginning address within EEPROM
Wire.send(TEST[x]);
Wire.endTransmission();
delay(10);
}
}
void loop()
{
for(byte x = 0; x < 6; x++)
{
Wire.beginTransmission(ADDR[x]); // link to 24LC08
Wire.send(BEGIN); // must act as a position pointer
Wire.endTransmission();
delay(10);
Wire.requestFrom(ADDR[x], 5); // request 7 bytes from slave device 24LC08
delay(10);
// below will loop until 7 bytes are received.
while(Wire.available()) // slave may send less than requested
{
char c = Wire.receive(); // receive a byte as character
Serial.print(c); // print the character
}
Serial.print("\n"); // next line
}
delay(10000); // wait one second.
}
This was obviously just for testing, but it took me a while to realize there is no reason to bit shift.. or change anything really, just using the library as it is works fine.
Thanks, CaptainObvious the EEPROM with your code is written and read, but there is a problem. I can write only the first 16 bytes for each page. For example, if I insert a sentence of 20 characters, it is truncated.
Well if you read the data sheet, some will allow 8-byte page writes, while others will allow 16-byte page writes, sounds like you have a 16-byte.
Basically, you need to send a stop bit at the end of every 16 bytes, then send again.
This is just an example:
Wire.beginTransmission(0x50);
Wire.send(0); // start at location 0 inside eeprom
Wire.send("1234567890123456"); // sends 16 bytes
Wire.endTransmission(); // this is what you need to call after 16 bytes, the "stop byte"
Wire.beginTransmission(0x50);
Wire.send(16); // start where we left off
Wire.send("7890");//
Wire.endTransmission();
You can use the eeprom examples from the website, for write page, but edit it to work with the EEPROM settings. For example, don't shift out, edit it to 16-byte page write, etc.
You can always call two 8-byte page writes, just to keep better track.
This sounds a lot like what I have going on with my LCD and my DS1307 RTC. There seems to be a conflict between the LCD library and the Wire library... (See my thread here.) I have yet to find the cause.
I've got 5 arduino's, and 5 external eeprom all sharing the same i2c line. One of the Arduino's is running an LCD and reading data and storing it from the other Arduinos, then prints it to the screen.
BUT, I'm not using the LiquidCrystal library, I'm using the LCD-4bit library, a modded version to work with LCD-Smartie.
So I suggest trying a different library if you're getting conflicts, if you don't mind switching of course. lol
Pardon the newbish question, but is that library on the playground? Also is it a one-for-one swap with the liquid crystal library? How difficult is the change over?
I'm not 100% sure it's on the playground, I know they have one very close which uses the same commands but I haven't tried it.
Well, it's a little bit different from liquidcrystal library, the commands are fairly similar. I know that LiquidCrystal offers some stuff that this library doesn't, so I guess it depends what you need exactly.
LCD-smartie is a program that basically runs on your computer and talks to your LCD through your Arduino. There are alot of plugins out there that people have made, and you can make your own.
For example, there's a WinAmp plugin that displays the song name/title/etc on your LCD, there's uhh, programs to do bar-graphs, you can display text from a file, display your hard drive space, or used/free hard drive space.
There's a LOT of plugins.. I used to use the Yahoo weather plug-in.. but I guess Yahoo took that ability away. It would tell me the temperature, if it's sunny/rainy, could check the weekly forecast.. all on an LCD on the Arduino. Pretty snazzy.
Of course the library can't do it by itself, you need a sketch (provided on the Nuelectronics website) that'll run the LCD-smartie.
The website hasn't been updated in years.. you can find more information/plugins and such in the forums. People are still very active on the forums.
You can also check some videos to see examples, google Arduino LCD Smartie and you should get a good amount of hits. And oh yeah, got to love Spokane! There's quite a few people here in Washington I was surprised.