Shop OBEX P1 Docs P2 Docs Learn Events
Writting text to external EEPROM — Parallax Forums

Writting text to external EEPROM

EugalazEugalaz Posts: 39
edited 2009-08-05 07:24 in BASIC Stamp
Hello,
I have recently purchased a BS2p and have interfaced with an 24lc256 EEPROM. While I have no trouble writting and reading data (numbers)·using i2Cout/in I can't seem to find any examples on how to write text and read text from the EEPROM. ie. I need to write a list of names (firstname lastname) to the EEPROM. Then be able to read them sequentially first entry to last entry.
Can anybody help me with a code snippet to do these operations please?
Kind regards
E·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-07-30 03:57
    First question ... Is this a fixed list? Can it be determined when the program is downloaded to the Stamp or does it need to be changed over time? Do entries have to be able to be deleted or modified? How long are the first and last names? How many entries on the list?

    Second question ... What are you going to do with the list? Are you comparing existing entries to a potential new entry? Are you sending the entries to some I/O device?

    Remember that Stamps don't have string variables or values. You can include strings in output statements, but they're really treated as a sequence of byte values that happen to be written as characters with quotes around them. There's no string manipulation included in Stamp Basic.

    There are no ready examples because it's complicated and depends too much on what you're trying to accomplish.
  • vaclav_salvaclav_sal Posts: 451
    edited 2009-07-30 03:57
    Text = ASCII code = data
    Cheers Vaclav

    Sorry Mike for stepping on you· - again.

    Post Edited (vaclav_sal) : 7/30/2009 4:04:12 AM GMT
  • EugalazEugalaz Posts: 39
    edited 2009-07-30 04:30
    The list is going to be a fixed list that will be added to untill EEPROM is full. The program will read the list (names) from first to last names over and over again. The names will be limited to 25 characters per entry. I will periodically need to add names to the list untill the EEPROM is full. Once written the names will not be edited just added. When the program reads names from the list it will display on serial LCD.
    Does this make it easier to acomplish?
    Thanks again
  • Mike GreenMike Green Posts: 23,101
    edited 2009-07-30 13:20
    What I understand so far:
    1) There will be an initial list included as part of the program itself. This initial list could be empty.

    2) The normal behavior of the program is to repeatedly cycle through the list, outputting each entry to a serial LCD in some format

    3) Somehow this normal behavior will be interrupted and a new list entry will be provided somehow, maybe serially

    4) This new entry will be added to the end of the list without checking for duplicates

    5) These entries have been described as <first name> <last name>, but it's acceptable for there to be no checking for proper format.
    They would be any sequence of characters terminated by the first carriage return, but it's assumed that there are two sequences of non-blank characters separated by a single blank and at most 25 characters are allowed including the blank.
  • EugalazEugalaz Posts: 39
    edited 2009-07-31 02:16
    Absolutly correct Mike.
    The list can be added to by stopping the program and even running a separate program to add to the list.
    There will be no checking for duplicates as this is done by Microsoft Excel. I will manually take new names from Excel and enter them somehow to the EEPROM. The List Reading Program will then be started again to cycle through the list and output to LCD.
    Thanks Mike.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-07-31 02:50
    NameTable   DATA   "firstName1 lastName1",0   ' Notice <text> <space> <text> <zero>
                DATA   "firstName2 lastName2",0   ' Everything before the zero byte will be displayed
                DATA   "firstName3 lastName3",0   ' Notice one item follows the next in order
                DATA   0   ' Last item is followed by a zero byte (must be present!)
    


    copyToLCD:   ' Subroutine to copy the whole table to a serial LCD
       p = NameTable   ' Start at the beginning of table
       DO
          READ p,v   ' Get the first character of the string from the EEPROM
          IF v = 0 THEN RETURN   ' End of table.  Keep p value for updating table
          p = p + 1
          DO
             SEROUT <pin>,<Baud>,[noparse][[/noparse]v]   ' Outputs character to LCD
             READ p,v   ' Get the next character from the EEPROM
             p = p + 1   ' Advance EEPROM pointer
          LOOP UNTIL v = 0   ' End of string.  p points to next string
       LOOP
    


    addToTable:   ' Copy a new string from serial input to EEPROM
       DEBUG   "Send new entry.  End with Return",CR
       DO   ' Must be called after copyToLCD so variable p is set properly
          DEBUGIN v
          IF v = CR THEN   ' Note: You can call addToTable after addToTable
             WRITE p,0   ' Write end of string marker
             p = p + 1
             WRITE p,0   ' Write end of table marker
             RETURN   ' Leave p pointing to end of table marker for another call
          ENDIF
          WRITE p,v   ' Write next character
       LOOP
    


    These subroutines are really the heart of what you need. Go through what I've written until you understand it, then you can modify it as needed. I assume that EXCEL would output the initial DATA list using a script of some sort and you'd cut and paste this into your program, recompile, and download. The addToTable routine is intended for making manual additions although it could certainly be used with an EXCEL program.
  • EugalazEugalaz Posts: 39
    edited 2009-07-31 03:58
    Thank you Mike, your a champion.

    Just to be sure.. I thought I would be using i2Cout/in comands to get or put data to an external EEPROM?
    If I understand the above;

    - The first SUB is DATA (from Excel) declared at the beginning of the program which I could add to if I wish.
    - The second SUB Reads the DATA (NameTable) and displays on LCD.
    - The third SUB takes entries from DebugIn and adds to Stamp EEPROM or External EEPROM 24LC256?

    The idea is to create a list on an external EEPROM 24LC256. Usind this EEPROM I understand that I can have up to 8 connected on the same bus giving me the ability to store up to 2MB of names. I understand that it will take some time for the Stamp to cycle through this list while displaying each name on the LCD. That's not a problem, actually it's exactly what I intend.
    Thanks again.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-07-31 04:19
    I completely forgot that you wanted to use an external EEPROM rather than the one used for program storage (since there's lots of such room, but not quite as much as you're planning). The idea is the same, but you'd use I2CIN instead of READ and I2COUT instead of WRITE. You'd need a larger pointer (than 16 bits) to address the whole thing. Since the EEPROM address naturally splits into an 8 bit portion and a 16 bit portion, you'd just use that. There would not be a DATA area and any I2COUT would have to have a 5-10ms PAUSE after it to allow the EEPROM to go through its write cycle.

    copyToLCD:   ' Subroutine to copy the whole table to a serial LCD
       p8 = 0   ' Start at the beginning of table in the first EEPROM
       p16 = 0   ' Start at the first byte of the EEPROM
       DO
          I2CIN <sda>,$A1+p8<<1,p16.highbyte\p16.lowbyte,[noparse][[/noparse]v]   ' Get the first character from the EEPROM
          IF v = 0 THEN RETURN   ' End of table.  Keep p8/p16 value for updating table
          IF p16 = $FFFF THEN
             p16 = 0
             p8 = p8 + 1
          ELSE
             P16 = p16 + 1
          ENDIF
          DO
             SEROUT <pin>,<Baud>,[noparse][[/noparse]v]   ' Outputs character to LCD
             I2CIN <sda>,$A1+p8<<1,p16.highbyte\p16.lowbyte,[noparse][[/noparse]v]   ' Get the next character from the EEPROM
             IF p16 = $FFFF THEN   ' Advance EEPROM pointer
                p16 = 0
                p8 = p8 + 1
             ELSE
                P16 = p16 + 1
             ENDIF
          LOOP UNTIL v = 0   ' End of string.  p points to next string
       LOOP
    


    addToTable:   ' Copy a new string from serial input to EEPROM
       DEBUG   "Send new entry.  End with Return",CR
       DO   ' Must be called after copyToLCD so variable p is set properly
          DEBUGIN v
          IF v = CR THEN   ' Note: You can call addToTable after addToTable
             I2COUT <sda>,$A0+p8<<1,p16.highbyte\p16.lowbyte,[noparse][[/noparse]0]
             PAUSE 5
             IF p16 = $FFFF THEN   ' Advance EEPROM pointer
                p16 = 0
                p8 = p8 + 1
             ELSE
                P16 = p16 + 1
             ENDIF
             I2COUT <sda>,$A0+p8<<1,p16.highbyte\p16.lowbyte,[noparse][[/noparse]0]   ' Write end of table marker
             PAUSE 5
             RETURN   ' Leave p8/p16 pointing to end of table marker for another call
          ENDIF
          I2COUT <sda>,$A0+p8<<1,p16.highbyte\p16.lowbyte,[noparse][[/noparse]0]   ' Write next character
          PAUSE 5
          IF p16 = $FFFF THEN   ' Advance EEPROM  pointer
             p16 = 0
             p8 = p8 + 1
          ELSE
             P16 = p16 + 1
          ENDIF
       LOOP
    


    Somewhere along the line, you have to initialize the EEPROM to empty. You can do that by simply writing a zero byte at location zero of the first EEPROM. Note that the maximum amount of EEPROM storage you can attach is 512K bytes (8 x 64K).

    Post Edited (Mike Green) : 7/31/2009 4:25:45 AM GMT
  • EugalazEugalaz Posts: 39
    edited 2009-07-31 07:29
    Now I am starting to understand.. Except for one thing, your last coment.

    Somewhere along the line, you have to initialize the EEPROM to empty. You can do that by simply writing a zero byte at location zero of the first EEPROM. Note that the maximum amount of EEPROM storage you can attach is 512K bytes (8 x 64K).

    Not sure what initialize the EEPROM to empty means. AND the maximum amount of storage I can attaxh is 512K? Can I not attach 8 EEPROMs to the same bus to the stamp.. I can only attach 2 x 24lc256 EEPROMs?

    Thanks Mike.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-07-31 14:28
    What do the subroutines use to determine that they've reached the end of the table? What would the table look like when it's empty? What's the initial content of the EEPROM? How would it be initialized to a known (hopefully desired) state?

    A 24LC256 EEPROM has 256K BITS of storage. It's a little misleading, but that's the way I2C and other EEPROMs have always been marketed. 256K bits = 64K bytes. Eight of these = 512K bytes. You could use the other possible pair of I/O pins (8/9) for a 2nd I2C bus and another 512K bytes.

    There are other ways to use external memory with a Stamp, but they're completely different and generally more expensive. Winbond makes some flash memories that use 4 I/O pins and SPI protocol and hold up to 2MBytes (in an easy to use DIP package), but you'd have to develop your own code. Parallax sells its Memory Stick Datalogger that uses a USB memory stick that's PC compatible and has Stamp sample code.

    Post Edited (Mike Green) : 7/31/2009 2:37:28 PM GMT
  • EugalazEugalaz Posts: 39
    edited 2009-08-01 11:48
    Thanks Mike I understand your answer.
    There seems to be a problem with your latest code though as it won't write data to the lc256. I have declared p8 p16 & v as WORD variables however addToTable does not write to the EEPROM. When I run the CopyToLCD sub the entries dont show up.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-08-01 14:31
    You might try changing the "$A1+p8<<1" to "$A1+p8+p8" and the "$A0+p8<<1" to "$A0+p8+p8".

    The 3rd I2COUT in addToTable should be:

    I2COUT <sda>,$A0+p8<<1,p16.highbyte\p16.lowbyte,[noparse][[/noparse]v] ' Write next character

    There was a "[noparse][[/noparse] 0 ]" by mistake. Also, p8 can be a byte variable.

    Please remember that I make mistakes sometimes. You do need to look at the code and try to understand my intention.
  • EugalazEugalaz Posts: 39
    edited 2009-08-02 11:05
    You don't make mistakes Mike.
    There just lies and inuendo spread by malicious people bent on discriminating against your impeccible character.
    Don't believe it.
    The code works just fine now mate. Thank you again for all your help and patience in this matter.
    Just one more question if I may..
    If I was to add a second lc256 to the same bus. It's just a matter of joining SDK and SCL to the same input pins (0/1) with their own resistors? How would I address the second lc256.. would it be $a2 & $a3?
  • Mike GreenMike Green Posts: 23,101
    edited 2009-08-02 13:31
    The code I wrote will actually not work with multiple LC256 devices because each LC256 device only provides the first 32K of each 64K address space. You'd need to either use LC512 devices (or AT24LC1024B devices) or modify the code to roll over to the next device after 32K (change the $FFFF constants to $7FFF). 8 x LC256 devices nets you a total of 256K bytes.

    Best "bang for your buck" would be to use 4 x AT24LC1024B for a total of 512K bytes.

    You only need one pair of pullup resistors for the input pins for all connected devices.
  • EugalazEugalaz Posts: 39
    edited 2009-08-03 10:25
    I see. An LC256 is actually 8 x 32K devices in one package. In effect I already have 8 devices on the same line. In order to store information in the whole LC256 (giving me 256K bytes of data) I would have to increment by 1 the p8 variable after address $7FFF to point to the next device (ie. the next avaliable 32k and so on until device #7 (p8 = 7))?
  • EugalazEugalaz Posts: 39
    edited 2009-08-05 00:41
    OK after going over all the coments and studying the data sheets I think I now understand the issue. I have included my edited sample code for reading and writing to external EEPROM.

    The problem with trying to address all of the 24LC256 is that the WORD variable will only hold $FFFF as the highest address. So given that, you can not address any further than that number (64k).

    In order to write more data than that you could daisy chan 8 x LC2464 EEPROMs on the same bus giving you a total of 512k. This way you could write to each chip to address $FFFF.

    I understand that I could use the other chips you mentioned but I want to try to get 8 chips on the same bus so I can learn how to address these individual devices.

    If I am on the right track with my understanding so far.. How would I address these other chips on the same bus (ie. EEPROM #2 - 7)? The first EEPROM would be addressed with the code below, but what about numbers 2 - 7, what modification to the code below do I need?

    Slowly getting there
    E


    '
    [noparse][[/noparse] SAMPLE CODE WRITE DATA ]

    I2Cpin CON 8 ' SDA on 8; SCL on 9

    p8 VAR Byte ' Device variable
    v VAR Word ' Input char variable
    p16 VAR Word ' EEPROM address variable

    v = $ff
    DO
    I2COUT i2cpin,$A0+p8+p8,p16.HIGHBYTE\p16.LOWBYTE,[noparse][[/noparse]v] ' Write next character
    PAUSE 10

    DEBUG ? v : DEBUG " Address Written To = ",DEC p16,CR
    PAUSE 10

    IF p16 = $7FFF THEN
    GOSUB Finish
    ELSE
    P16 = p16 + 1
    ENDIF

    LOOP

    Finish:
    DEBUG "Done writting to all addresses"
    END

    '
    [noparse][[/noparse] SAMPLE CODE READ DATA ]

    DO
    I2CIN i2cpin,$A1+p8+p8,p16.HIGHBYTE\p16.LOWBYTE,[noparse][[/noparse]v]
    PAUSE 10

    DEBUG ? v : DEBUG " Address Read From = ",DEC p16,CR
    PAUSE 10

    IF p16 = $7FFF THEN
    GOSUB Finish
    ELSE
    P16 = p16 + 1
    ENDIF

    LOOP

    Finish:
    DEBUG "Done reading all addresses"
    END
  • Mike GreenMike Green Posts: 23,101
    edited 2009-08-05 05:01
    1) You still don't quite get the addressing scheme and the capacity of various EEPROMs

    a) The LC256 is 256K BITs which comes out to 32K bytes. It responds to addresses $0000 to $7FFF for a particular device code set by pins A0-A2.
    ... Strictly speaking, the LC256 ignores the most significant address bit so $0000-$7FFF is identical to addresses $8000-$FFFF

    b) There are 8 device code pairs available for EEPROMs, $A0/1, $A2/3, $A4/5, $A6/7, $A8/9, $AA/B, $AC/D, $AE/F.
    ... The 3 bits in the device code are used by the routines for the next 3 bits of the address so we have addresses from $00000 to $7FFFF.

    2) The routines I wrote use two variables, a byte called p8 and a word called p16 to hold a total of 24 bits.
    ... This 24 bits is incremented together to make a 24 bit counter. The lower 19 bits is used to address an EEPROM location.
    ... Because the LC256 has only 32K bytes, the increment routine is written to increment from $7FFF to $0000 with a carry to p8.

    Post Edited (Mike Green) : 8/5/2009 3:47:46 PM GMT
  • EugalazEugalaz Posts: 39
    edited 2009-08-05 07:24
    Oh man it's so obvious now. I understand completly. Thanks again!
Sign In or Register to comment.