Shop OBEX P1 Docs P2 Docs Learn Events
Unable to write a long to EEPROM 24LC256 — Parallax Forums

Unable to write a long to EEPROM 24LC256

Hello everybody,

I want to first thank you all for all the previous help that you have provided to me. Once again my name is Jaime Montenegro, this is my first propeller project. I am writing a program that reads the optical ports of several power meters. To accomplish that I first had to be able to detect and time stamp pulses coming from the optical ports; so I first had to setup a RTC clock DS1307 which I did with the help of some of you (Mike Green and Chris Savage) in a previous discussion.

I am currently using a propeller demo board, I have already programmed the propeller to use six cogs to read 6 optical ports coming from 6 power meters and store the values in variables. Now, I want to be able to save those values in a EEPROM for backup and also send those values wirelessly via Xbee.

This is my setup::

RTC DS1307 (kit from adafruit https://www.adafruit.com/product/264 )
EEPROM 24LC256 (EXTERNAL, NOT THE ONE ON THE DEMO BOARD, I HAD TO DO THAT BECAUSE THE ONE IN THE DEMO BOARD USES P28 AND P29, BUT I DO NOT HAVE PHYSICAL ACCESS TO CONNECT THE RTC CLOCK TO THOSE PINS)
EEPROM ADDRESS = %1010000 (GIVEN IN THE SPECS OF THE EEPROM)
SCL = PIN 6
SDA = PIN 7
BAUD RATE = 57600

I am using P0 ..P5 as the inputs for the optical pulses coming from the power meters, I am also running individual cogs per meter, cog1 reads P0, cog2 reads P1 and so on .

I was able to get my hands on 2 different i2c drivers:

Basic I2C Driver

http://obex.parallax.com/object/155
(Suggested by Mike Green)

Very Basic I2C Driver
The other one was given to me by Chris Savage

So I decided to write two different projects for each driver:

PROJECT 1 USING THE: Basic I2C Driver (my code 6b)

I am capable of detecting a pulse with the code and time stamp it. I created an array pdata[8] to hold all my data, and then I send the data to the eeprom via i2c.WriteLong and i2c.WriteByte.
To see if it works, I also created another array rdata[8] to retrieve the values that (supposedly) I had already saved in the eeprom, but all I get is -1. I am attaching the entire project, please take a look at it, I must be doing something wrong but I do not know what.


PROJECT 2 USING THE: Very Basic I2C Driver (my code 8b)

I am capable of detecting a pulse with the code and time stamp it. For this project, I also created an array pdata[8] to hold all my data and another array rdata[8] to retrieve the values that (supposedly) I had already saved in the eeprom. The issue with this driver is that it only has a method to write/read a byte (ByteWrite and RandomRead). I am capable to write to the eeprom and read from it all the variables that are byte size, but I need to write and read from the eeprom a variable with long size (pdata[0] this variable will be higher than 255), and I do not know how to go about it. I am also attaching the entire project, please take a look at it.



Thank you!!

Comments

  • You can only write bytes to an eeprom, however...

    In the DIY I2C tutorial on the last page is a method for storing integer type values to an eeprom and retrieving back as an integer type.

    http://learn.parallax.com/tutorials/language/propeller-c/propeller-c-simple-protocols/diy-i2c/more-data-types-and-devices
  • The WriteLong method writes the 4 bytes of the long using the EEPROM's write page mode. As mentioned in the comments, the 4 bytes have to all fit in one page (usually 64 or 128 bytes). If you use a starting EEPROM address divisible by 4, you won't have a problem there.

    If you're always reading back a -1, probably the data isn't being written. Remember that the write protect (/WP) pin has to be grounded.

    We can't tell you what's going on with the Basic_I2C_Driver without looking at your code. The object does work.
  • I've never used the Very Basic I2C Driver, but I am familiar with the Basic I2C Driver. For the Basic I2C Driver I see that you are calling the start method and the stop method for every long that you write. You should not be calling start and stop. These are low level methods that are used by the higher level methods. Also, you are using a device address of %1010000. You should be using $10100000, or $A0. And I believe you need to call WriteWait after writing each long to the EEPROM.
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    As was mentioned you can only write bytes to the EEPROM one at a time. I usually have a method that writes the low byte of my long, then increments the address pointer and shifts the variable 8 bits right, writes the next byte and so on. You can do this for 16-bit, 24-bit and 32-bit values no problem. When the method returns the address pointer should already be set for the next write.
  • Mike GreenMike Green Posts: 23,101
    edited 2016-07-14 22:52
    You need to allow the EEPROM to finish its write operation. The EEPROM will ignore subsequent operations until the write is finished. This takes about 3ms for most current EEPROMs. WriteWait is provided to speed this up. It attempts to read from the EEPROM repeatedly until the EEPROM responds. At that point, the EEPROM is ready to do another write. If you use WriteLong, WriteWord, or WritePage, all of the bytes are written in a single EEPROM operation.

    If you want to provide a 3ms or longer delay by doing something else, you don't need to use WriteWait.

    The start and stop methods are for internal use only. They are left as PUB methods in case someone wants to write a high-level routine for some other I2C device as some people have done.
  • As was mentioned you can only write bytes to the EEPROM one at a time. I usually have a method that writes the low byte of my long, then increments the address pointer and shifts the variable 8 bits right, writes the next byte and so on. You can do this for 16-bit, 24-bit and 32-bit values no problem. When the method returns the address pointer should already be set for the next write.
    Mike Green wrote: »
    You need to allow the EEPROM to finish its write operation. The EEPROM will ignore subsequent operations until the write is finished. This takes about 3ms for most current EEPROMs. WriteWait is provided to speed this up. It attempts to read from the EEPROM repeatedly until the EEPROM responds. At that point, the EEPROM is ready to do another write. If you use WriteLong, WriteWord, or WritePage, all of the bytes are written in a single EEPROM operation.

    If you want to provide a 3ms or longer delay by doing something else, you don't need to use WriteWait.

    The start and stop methods are for internal use only. They are left as PUB methods in case someone wants to write a high-level routine for some other I2C device as some people have done.

    Hello guys, I could not work on the project for some time because I was at the hospital. I started working again on it, and was able to write/read the long to the eeprom, I implemented these codes:

    To write long to EEPROM:

    repeat index2 from 0 to 3
      repeat index2 from 0 to 3              
        
           i2c.ByteWrite(addallo[index] + index2, pdata[0])   
           if index2 < 3
               pdata[0] >>= 8
    
    
    To read long from EEPROM:
    
     rdata[0] := 0
      repeat index2 from 3 to 0
         temp := i2c.RandomRead(addallo[index] + index2)    
         rdata[0] += temp
         if index2 > 0
           rdata[0] <<= 8
     
    

    I want to thank all of you for your comments and suggestions. Now my next step/challenge is transferring data thru an xbee network. I have a question, does anybody know how to get the data from the eeprom to a PC and save it in a CSV file so I can read it using Excel?

    Thank you for your help.
  • Since the EE is byte oriented, you want to be careful of page boundaries when writing a long (in four consecutive bytes).
Sign In or Register to comment.