Shop OBEX P1 Docs P2 Docs Learn Events
I2C Code for the BS2, BS2e, and BS2sx — Parallax Forums

I2C Code for the BS2, BS2e, and BS2sx

Jon WilliamsJon Williams Posts: 6,491
edited 2009-01-03 03:09 in BASIC Stamp
As there seems to be growing interest in using I2C parts with non-BS2p/BS2pe modules, I spent the day updating my core I2C routines for the BS2, BS2e, and the BS2sx.· Above the low-level routines I have a Write_Byte subroutine and a Read_Byte subroutine that should work with any I2C device you throw at it -- but I can't guarantee that (if you have a problem with a particular part, please let me know).· These subroutines only write or read one byte at a time; if you want to do block writes or reads you'll have to add your own code (it shouldn't be too tough).

Now,·if you're not familiar with I2C please do a bit of research --·there is plenty of information on the Net.· I wrote an article for Nuts & Volts that might help you:

http://www.parallax.com/dl/docs/cols/nv/vol3/col/nv85.pdf

Understand, though, that the code attached here is updated using PBASIC 2.5 syntax.· It's also more flexible in that you can specify the slave ID as a variable, the device address as a variable (in case you have more than one of the same device on the line), as well as the number of address bytes for the register you want to read or write.· In addition to the core program, I have three demos, each demonstrating different address byte values:

PCF8574A - no address byte
MCP23016 - 1 address byte
24LC32 - 2 address bytes

And yes, I connected and ran all three demos on my trusty NX-1000 board.

I find this code helpful for my own projects, I hope it's helpful for yours as well.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas Office


Post Edited (Jon Williams) : 8/19/2004 2:54:06 AM GMT
«1

Comments

  • cabojoecabojoe Posts: 72
    edited 2004-08-19 02:44
    OMG thanx Jon!
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 03:14
    Here's another demo -- and the reason I decided to update my code today.· This demo is for the 24LC515 (64 kByte EEPROM).· It's a bit odd in that bit 15 of the address is stuffed into the slave ID byte.

    Please note that I wrote this code to help a customer and don't have a 24LC515 to test with.· If you find a problem, please let me know.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • ionion Posts: 101
    edited 2004-08-19 04:08
    Thanks Jon,

    The info is just in time because i do have problems with I2C. Mostly with eeproms as you know.

    For my previous post about eeprom i understood that is a two bytes address for the 16k . The addressing is still the same for the 4 k memory?

    Acording with Ramtron data sheet for the 4k memory, the address is made by 8 bits for the loction on the page (they are only two pages), and one bit for the page , which make 9 bits== 512 , locations to write or read. Do I have to use the same sample comand you posted before , or just a plain command. I know the question is silly and maybe obvious for you, but for me is still an unsolved mistery. Maybe a sugestion for Parallax to change the code for the comand in a such way that the user just put the phisical address number , with no wory about high and low bit , let say address 1097 and the code does all the house keeping in behind the curtains.

    I will go now to read your article on NV and maybe i· can go to sleep if i find my answer.

    Regards

    Ion
  • frasencifrasenci Posts: 34
    edited 2004-08-19 04:18
    Sorry to interrupt guys but :

    In terms of data , how much is a 4KByte eeprom capable of storing ???

    I mean for example Date,Time,and 2 numerical values for each write ??

    Thank you
  • ionion Posts: 101
    edited 2004-08-19 04:46
    Frasenci,
    i am completly new at that but reading the data sheet for a 4k memory i found out that:
    The FM24C04A is a serial FRAM memory. The
    memory array is logically organized as 512 x 8 and is
    accessed using an industry standard two-wire
    interface. Functional operation of the FRAM is
    similar to serial EEPROMs.

    When accessing the FM24C04A, the user addresses
    512 locations each with 8 data bits. These data bits
    are shifted serially. The 512 addresses are accessed
    using the two-wire protocol, which includes a slave
    address (to distinguish other devices), a page address,
    and a word address. The word address consists of 8-
    bits that specify one of 256 addresses. The page
    address is 1-bit and so there are 2 pages each of 256
    locations. The complete address of 9-bits specifies
    each byte address uniquely.

    Assuming that you want to store one byte for days,one for month,one for year,one for seconds,one for minutes ,and one for hours in a 24 hours format will use 6 bytes of the 512 on the chip. So you can store up to 85 logs until you run out of memory and have to rolover. Dependig how often you log data will give you an ideea how much you can store.
    I hope that this is the answer for your question. Here is the link for the data sheet of this memory. I use it because they claim that you can write for life with no limitation of write cycle like a conventional eeprom. I do a write every 5 seconds and i need it to work for 5 years 24/7 so this is my first choice for eeprom over nvram or standard eeprom.
    http://www.ramtron.com/doc/Products/serial.asp
    Ion
  • ionion Posts: 101
    edited 2004-08-19 04:50
    sorry, i forgot about your numerical values. What is the size of the numbers. do you have an example? assuming that they are byte size you add two more bytes and the total now is 8 bytes ,so you get only 64 logs.

    ion
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 04:54
    I think EEPROMs get rated (and usually named) based on the number of kBits, so a 4 kBit (4096 bit) EEPROM will store 512 bytes. Here's some examples from data sheets I keep handy:

    24LC04 - 4 kBits (512 bytes, organized as 2 blocks of 256 bytes) --·the block is specified in the Slave ID
    24LC16 - 16 kBits (2 kBytes, organized as 8 blocks of 256 bytes) --·the block is specified in the Slave ID
    24LC32 - 32 kBits (4 kBytes)
    24LC256 - 256 kBits (32 kBytes)
    24LC515 - 512 kBits (64 kBytes, organized as 2 blocks of 32 kBytes) --·the block is specified in the Slave ID

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office


    Post Edited (Jon Williams) : 8/19/2004 2:44:38 PM GMT
  • frasencifrasenci Posts: 34
    edited 2004-08-19 05:07
    Perfect !!

    Thank you ion , a nice and clean explanation.

    Thank you Jon ,..... I was suspicious of that NOT beeing 4 KBytes but 4K Bits. A small difference , huhhh !!!

    nice guys you both .... man there is SO MUCH to learn ....

    Francisco
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 05:29
    Okay, it's past midnight in Dallas and I've had just about enough fun for one day.· Attached are two more demos: DS1307.BS2 (which shows how to add block write and block read subroutines) and 24LC16B.BS2 (which puts the page selection in the slave address).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • ionion Posts: 101
    edited 2004-08-19 05:31
    Have Good Night Sleep Jon
  • Velvet LeopardVelvet Leopard Posts: 47
    edited 2004-08-19 05:32
    Hewwo.· I read your N&V article on I2C.· Mr.· Williams.· I don't know much about it, but what is I2C exactly?· Are my 25LC640 EEPROMs I2C compatible?· I would like to add them to my stamp II.· I have 5 of them.· The stamp I have is the homework board so I can add all five just to learn and then take them off for a "real" project later.· Do I need any special I2C components or just a compatible chip?· Thanks.


    · P.S.· I do want to program my stamp II.· I just wanted to learn how to braoden it as well.· That is why I have asked so many questions about the "outside" components.· I am sorry if I have annoyed anyone here.· [noparse]/noparse][noparse]:([/noparse
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 05:39
    Nobody's annoyed.· But at some point you've got to pull up your boots and get to work. Google is your friend, use it. You can find a ton of information about the I2C protocol on the Internet (that's what I did before writing my column). You can get the entire specification from Philips -- but you probably don't need it at this point.

    In just two seconds I found the spec sheet on the Internet for the 25LC640 -- it is NOT an I2C device; it is an SPI device which means that you can use SHIFTOUT and SHIFTIN to deal with it. First, though, you should probably spend some time learning the basics of the BASIC Stamp. Start with "What's A Microcontroller?" and then give "StampWorks" (written by me) a scan. If you'll just give yourself a little training time you will be an old pro in a matter of a few weeks.

    PS: Do you actually speak like Elmer Fudd too, or is it just in the writing?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office


    Post Edited (Jon Williams) : 8/19/2004 5:46:51 AM GMT
  • Velvet LeopardVelvet Leopard Posts: 47
    edited 2004-08-19 07:17
    Sorry.· I spend very little time on this computer.· It is my mom's and it is ancient, slow, and likes to freeze and die alot.· I just finished the What's a Microcontroller book projects.· I have not the money to get another book, unless it is an online pdf or something.· I am getting better at the stamp programming.· Tomorrow I am going to try and write my own program to help with a robotics project.· It might be hard being that I only have one stamp and the project would most likely need at least two.· I want to make a hierarchial system for the bot.· And as for my little "hewwo" thing.· I am a fur and I have my own fursonality.· You can take that any way you like, but it is my lifestyle.· One thing about furs is they love computers and bots and art.· Hewwo is my furry way of saying hello.· If I must, I will stop.· Thanks for your time.· And I don't mean to offend or be rude, but I do not like to be ridiculed for something as trivial as saying hewwo as opposed to hello.

    Post Edited (Velvet Leopard) : 8/19/2004 7:20:08 AM GMT
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 13:15
    Sorry, did not mean to offend,·I had no intention of ridiculing you, and I am not asking you·to stop with the "Hewwo" greeting -- it's just that every time I read it I hear Elmer Fudd's voice in my head so I had to ask.·

    ALL books publshed by Parallax are available as PDF downloads (no charge).· Here are links to books that will help:

    http://www.parallax.com/html_pages/edu/curriculum/sic_curriculum.asp·(Stamps In Class)
    http://www.parallax.com/detail.asp?product_id=27220·(StampWorks)

    And you can get to our Nuts & Volts articles (over 100) here:

    http://www.parallax.com/html_pages/downloads/nvcolumns/Nuts_Volts_Downloads.asp

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • ionion Posts: 101
    edited 2004-08-19 14:29
    Hello Jon,

    I did post·yesterday a question about 4 k memory and maybe it did passed unread. I will put it again and ask you kindly to help me on this mather. Here it is:

    "For my previous post about eeprom i understood that is a two bytes address for the 16k . The addressing is still the same for the 4 k memory?

    Acording with Ramtron data sheet for the 4k memory, the address is made by 8 bits for the loction on the page (they are only two pages), and one bit for the page , which make 9 bits== 512 , locations to write or read. Do I have to use the same sample command you posted before , or just a plain command like direct addresing ?

    Here is the info posted by Ramtron about their memory:

    The FM24C04A is a serial FRAM memory. The
    memory array is logically organized as 512 x 8 and is
    accessed using an industry standard two-wire
    interface. Functional operation of the FRAM is
    similar to serial EEPROMs.

    When accessing the FM24C04A, the user addresses
    512 locations each with 8 data bits. These data bits
    are shifted serially. The 512 addresses are accessed
    using the two-wire protocol, which includes a slave
    address (to distinguish other devices), a page address,
    and a word address. The word address consists of 8-
    bits that specify one of 256 addresses. The page
    address is 1-bit and so there are 2 pages each of 256
    locations. The complete address of 9-bits specifies
    each byte address uniquely.
    9 bits is biger then one byte, so how i can write and read to 10, and what is the diference to write and read to 410?
    Thank you
    ion
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 14:59
    The 24LC04 devices are organized into two pages of 256 bytes -- this lets the word address be just a single byte.· To select pages, bit 1 of the slave ID byte is used.· There are examples above (like the 24LC16B)·that show how to address similar devices when using a BS2, BS2e, or BS2sx.

    With the BS2p or BS2pe, I would tend to do something like this (written on-the-fly -- not tested):

    slvAddr  VAR  Byte   ' slave address 
    devNum   VAR  Nib    ' device number (0 - 3) 
    devAddr  VAR  Word   ' address in device 
    inChar   VAR  Byte 
    
    Test: 
      DEBUG "Testing...", CR, CR 
      devAddr = 0 
      slaveID = ($A0 << 4) | (devNum << 2) | (devAddr.BIT8 << 1)
      I2COUT 0, slaveID, devAddr, [noparse][[/noparse]"BASIC Stamp"] 
      PAUSE 1000 
      FOR devAddr = 0 TO 10
        slaveID = ($A0 << 4) | (devNum << 2) | (devAddr.BIT8 << 1)
        I2CIN 0, slaveID, devAddr, [noparse][[/noparse]inChar] 
        DEBUG inChar 
      NEXT 
      END
    

    If this works the way I intend, the string "BASIC Stamp" will be written to the EEPROM and then read back one character at a time.· When using this device, though, you must be careful·with the 16-byte page boundaries.· If you're writing/reading a single byte to/from the device you won't have any troubles with the page boundaries or block bit using the addressing demonstrated above.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office


    Post Edited (Jon Williams) : 8/19/2004 3:47:10 PM GMT
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 15:56
    Thanks to the rejuvenating powers of a warm breakfast and a big cup of Starbucks coffee, I am able to write code again and I've done two demos for the 24LC04 devices.· Please give these a try -- I found that the 24LC04 I have has occassional errors.· All the other EEPROM programs I've written using the same core code test perfectly.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • ionion Posts: 101
    edited 2004-08-19 16:06
    THANK YOU VERY MUCH MR. WILLIAMS.
    It did worked as expected. Like you said many times, READ THE MANUAL is a gold rule. After reading the addressing for 4k chip I found out that for page 0 we must use $A0
    and for page 1 is $A2. After all this troubles I will not forget it so easy. I am sorry for all the nagging to get the answer, but I am new to this and I have a lot to learn.
    The slave ID for chip is as follow:
    1010·· A2A1 for device select,· A0 for page select, and the last is R/W bit
    Thank you
    Ion
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 16:11
    Have a look at the demo code that I just posted -- it will show you how to set the Slave ID as a variable so that you can work with multiple 24LC04 devices in the same system, and properly set the address block bit too.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • ionion Posts: 101
    edited 2004-08-19 16:26
    I did and worked right. I am scratching my head now to get the meaning of some words but like you said GOOGLE is my best friend.
    Ion
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 16:29
    The key is to study the product documentation along with the code. At some point it will all click in and you'll say, "Okay, now I know what that maniac in Texas is doing!" It's not too hard ... just keep pushing and it will all come together. I promise.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 16:44
    ion said...

    <snip>

    Maybe a sugestion for Parallax to change the code for the comand in a such way that the user just put the phisical address number , with no wory about high and low bit , let say address 1097 and the code does all the house keeping in behind the curtains.

    Sorry, I didn't respond to this earlier ... yesterday turned into a VERY LONG day.

    Here're the deal: We can't do the housekeeping hehind the scenes because of the way different I2C devices are addressed.· Take the 24LC256 for example.· It uses two address bytes.· What if we told it to write to address 0?· How would the compiler know to send one byte or two?· It's not possible unless we create specialized commands for the various addressing schemes of I2C devices -- and remember that some devices (like your 24LC04) want address bit(s) included in the Slave ID byte.

    If you study the I2C bit timing diagrams that are included in most I2C component data sheets this will make sense.

    Here's the syntax for I2COUT (identical for I2CIN):

    · I2COUT pin, slaveID, {address {\lowAddress},} [noparse][[/noparse]output_data]

    You see the curly braces?· These mean the elements enclosed are optional.· So, valid I2COUT commands could look like this:

    I2COUT SDA, slaveID, [noparse][[/noparse]$FF]                                       ' for the PCF8574, for example 
    I2COUT SDA, slaveID, IODIR0, [noparse][[/noparse]$00]                               ' for the MCP23016, for example 
    I2COUT SDA, slaveID, eeAddr.BYTE1\eeAddr.BYTE0, [noparse][[/noparse]"BASIC Stamp"]  ' for the 24LC256, for example
    


    I hope this additional information helps.· Keep studying the examples, the help file, and the product data sheets and it will all come together!



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office


    Post Edited (Jon Williams) : 8/19/2004 4:47:05 PM GMT
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2004-08-19 16:48
    Okay, one more -- this program takes a very long time to run all the way through.· I've run out of I2C memory devices so I'll have to get into other parts now.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas Office
  • ionion Posts: 101
    edited 2004-08-19 17:14
    Jon,
    You are right. I believe that after more then 24 hours around the memory subject it will be time to move on.
    I hope that all the readers of this thread ( and they are a lot) had a lot to get as info and demo programs.
    Thanks again and see you soon with some other questions.
    By the way , i read all the posting in this forum and some of my questions are already answered.
    Ion
  • Wade SmithWade Smith Posts: 25
    edited 2004-08-19 19:25
    Velvet Leopard wrote: And as for my little "hewwo" thing.· I am a fur and I have my own fursonality.· You can take that any way you like, but it is my lifestyle.· One thing about furs is they love computers and bots and art.· Hewwo is my furry way of saying hello.· If I must, I will stop.· Thanks for your time.· And I don't mean to offend or be rude, but I do not like to be ridiculed for something as trivial as saying hewwo as opposed to hello.<!-- Edit -->

    What the hell is a fur? And where would we be if everybody just changed the spelling on words as a way to manifest their personality?
  • Wade SmithWade Smith Posts: 25
    edited 2004-08-20 04:15
    freaked.gif· You're right Chris,·I spent a few minutes bouncing around in the ·roleplaying part of the forum on the link, and these loonies make Michael Jackson look mainstream. It was like a fiction contest where everyone tries to write the worst prose possible on purpose, but sadly it wasn't a parody! Makes one appreciate the order and symmetry of solid state physics and electronics. I am hoping I don't see a furry Boe-Bot in the future!
  • basejumper9basejumper9 Posts: 4
    edited 2007-03-19 22:40
    Anyone know how to go about working with an Atmel 24c11? I am trying to figure out how to work with it and cannot seem to get it right. All the sample codes come out with FF for all registers no matter how I tweak the code. I think I must not have the addressing right. Here are some notes about it:
    www.atmel.com/dyn/resources/prod_documents/doc3409.pdf
    Any help would be greatly appreciated.

    Pete
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-19 22:56
    If you look carefully at the datasheet, the addressing is very different from most EEPROMs. There's no device select code. You just write a one byte address with the upper 7 bits containing a byte address and the LSB containing a read/write bit as usual. The next byte (or bytes) is a data byte. The "page" size is 4 bytes, so you can write up to 4 bytes at a time. A read cycle consists of a one byte address with read set in the LSB. The next byte (or bytes) are read from the EEPROM as usual, but without a need for a second start sequence as with most EEPROMs.
  • basejumper9basejumper9 Posts: 4
    edited 2007-03-20 16:59
    I'm sorry I'm not really understanding so the address is sent in a form like
    slvAddr = %11111111 ? by the way I am trying to use the I2C essentials posted earlier on this form.

    Thanks a bunch for the help.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-20 17:05
    Using Jon's I2C Essentials routines for the PCF8574A, slvAddr = (EEPROM location) << 1.
Sign In or Register to comment.