An i2c Object Question
MasterC
Posts: 39
Hi,
I·have been·starting in on making some higher level i2c objects to communicate with various devices.· I was going to base them around the use of a slightly modified version of Dave Custer's I2C Spin Object.· However, I got to wondering how well vetted this object is to use as a starting point.· I have no prior experience with I2C, so I might be missing a few things, but some of the stuff in there wasn't adding up for me.· If you wouldn't mind, please see the attached object.· I have added some questions to it, usually in comments like: "{*******Corey Q: ... *******}," or something like that.
Please note:· I was not intending to nitpick at the original author's code.· I am new to this stuff, so it is just as likely that I am confused--I'm only·seeking some clarification here to make sure I get this going on the right track.·
Thanks!
I·have been·starting in on making some higher level i2c objects to communicate with various devices.· I was going to base them around the use of a slightly modified version of Dave Custer's I2C Spin Object.· However, I got to wondering how well vetted this object is to use as a starting point.· I have no prior experience with I2C, so I might be missing a few things, but some of the stuff in there wasn't adding up for me.· If you wouldn't mind, please see the attached object.· I have added some questions to it, usually in comments like: "{*******Corey Q: ... *******}," or something like that.
Please note:· I was not intending to nitpick at the original author's code.· I am new to this stuff, so it is just as likely that I am confused--I'm only·seeking some clarification here to make sure I get this going on the right track.·
Thanks!
Comments
The ability to directly handle 8, 16, 24, or 32 bit values at a low level is not as useful as you might think since they're all just multiples of bytes. Basic_I2C_Driver does its low level I/O in bytes and simply does multiple bytes at a higher level. Look at routines like ReadWord and ReadLong for examples.
Mikes basic_i2c_driver is truly excellent and its what i've based the version 2.x i2cObjects on. I'd look at that code for i2c routines.
As to your comments in the code - just use Mike's driver instead - mine was very basic and not very good in some places. (but it did work!)
james
Well, aside from the ability to do·more than 1 byte at a time (which I understand isn't that useful),·there were a couple of other factors that drove me to use the object being discussed (javalin's object, apparently?) as a starting point.· For one, I liked being able to assign whatever pin I wanted for both SCL and SDA.· In addition, I liked that it had the framework to function as more of a standalone object that would remember its SDA and SCL pins and stuff, so I wouldn't have to send it every time.·
However, now it occurs to me that a better place for that stuff might be in my device specific driver objects.· For instance, I envision making an ADS1100 object that has an init method where the device address and·IO pins are assgned.· From then on, I just have to say things like·object.read and object.write, or whatever.· That way, if I have several ADS1100 chips on my board (and I do), I can set ADC1, ADC2, ADC3, etc. all to the ADS1100 object.· Then I can say "ADC1.init(address1,SCL,SDA)", "ADC2.init(address2,SCL,SDA)", etc.· From then on, I can forget about who's at what address and what the SCL and SDA lines are.· I can just say things like·"ADC1.read", "ADC2.read, "ADC3.cfg(mode)", and etc.
Does that make sense?· So, maybe Mike's basic_i2c_driver is a better starting point, and it can be a child of my ADS1100 object.· But in my ADS1100 object, I need to figure out what to do for the start, stop, init, etc.· I figured javalin's code was a good start for that, but then I got confused by what he was doing with some of it.· Hence the comments I left in his code, so it would still be helpful if somebody could straighten me out on my questions there.·
[noparse][[/noparse]Edit] I see why you're having trouble. Most of the I2C libraries (mine, anyway) take care of the grunt level stuff without revealing it. The chip you're using doesn't use register addressing per se, so the mid-level code we wrote was confusing you. I freed my library by making the low-level stuff public so that those methods can be used in other objects. Have a look at jm_ads1100.spin and compare the code to the I2C diagrams in the documentation; I think you'll find this gets you started. Once you're successfully talking to the chip then you can port the code to an object for us in other programs.
[noparse][[/noparse]Edit] Removed use of .wait(); changed to .start() -- still not tested by JM because I don't have an ADS1000
Post Edited (JonnyMac) : 8/31/2009 11:17:53 PM GMT
2) Use James' objects as models for the devices you want to use. He has a whole variety of devices supported. Pick the one that's closest to what you need, then modify his object until it works for the device you want the way you want it.
3) Although the Basic_I2C_Driver is written to use a pair of I/O pins for SCL and SDA, you could easily modify the routines to use a separate parameter to specify the SDA pin rather than using SCL+1. There's nothing magic in how the routines are written. The assembly routines would be harder to change to use unrelated I/O pins for SCL and SDA, but it could be done.
that i2c-code is dead. Use Mikes.
James
Ok, ok.· But what I'm really trying to get at with those questions is how to make a stand-alone object for my device that can be used from a parent program, with start() and stop() methods and all that.· Your·object sort of did that, but I wasn't sure about some·of it and was·trying to sort it out better in my head.· I guess I'll get the i2c part working·first and·move on·from there.
Thanks again!
Basically, I·used JohnnyMac's code, adding the tv_text object and using the following for main:
It hangs up as soon as I do rdconfig apparently in an infinite loop.
[noparse][[/noparse]Edit:· OK, no it·doesn't--see next post.]
Thanks for any insight!
Post Edited (MasterC) : 8/31/2009 7:05:49 PM GMT
1.· The results of rdconfig and rdadc are both·printing out as inifnity.· What am I doing wrong there?
[noparse][[/noparse]Edit:· Never mind this one either--I should have used text.hex(rdconfig,2) and text.hex(rdadc,4) for these.]
2.· Say there is a problem with my SCL and SDA lines--I'd rather not just hang up indefinitely.· How can I detect the problem and return an error instead?
Thanks!
Post Edited (MasterC) : 8/31/2009 7:12:48 PM GMT
If you try to see if the two lines go to high (pulled by the 4.7k pull-up's) without the object started - so the lines are un-driven by the propeller - is one way.· Otherwise some form of timout code specific for your application/device might be the way forward.
i.e. (pseudo code)
James
OK, another issue.· The way things·have been·going, I'll probably figure it out myself again as soon as I post, but for the moment I'm stumped.· Using the code below for main in the jm_ADS1100 object, I get "FF" and "FFFF" as the results every time.· According to the device's datasheet, the default config. register value should be "8C."· So, it appears that something isn't quite working right with either the read routines or my hardware setup.
Did you check your device type versus what's in the code (see CON section)?
instead of:
OK.· So I'm talking to my i2c device now, and it only took a full day's work.·
If you have some fixed delay between reads I'd just use .start(). The .wait() method works really well with EEPROMs that might be busy writing when you attempt to access them.
Post Edited (MasterC) : 9/2/2009 12:18:57 AM GMT
If anyone is willing to take a peek at my ADS1100 object, I'm just hoping to get some idea if this is a decent way to make an object like this or not.· Did I do anything that is poor form, a waste of resources, confusing, or·a bad idea for some other reason?· The object seems to work fine, and I'm working on several other objects for·other i2c devices.
Thanks!
Corey
I'm probably different than other programmers because in my "other life" I write film scripts which have a very strict visual structure/look, especially here in Hollywood -- people won't ever read a script that doesn't look right. My point is that if you make your code listings visually appealing others are more likely to feel comfortable with them right away. A listing that is all run together is hard on the eyes and many won't look through and review for this reason.
As far as the content of the ADS1100 object itself--anybody have any comments?