I2c driver MCP3426
DigitalBob
Posts: 1,513
Greetings everyone;
Has anyone ever used the MCP3426, 16 bit ADC I'm looking for a spin driver for that device.
Thanks to everyone in advance
Bob
Has anyone ever used the MCP3426, 16 bit ADC I'm looking for a spin driver for that device.
Thanks to everyone in advance
Bob
Comments
If you find something that works I hope you let us know.
I had wrote Forth-code for MCP3425 in last year .
#444 in [Propforth v5.5 is available for download]thread.
Not spin.
MCP3425 is like MCP3426.
MCP3425 is 1channel A/D and don't have reference voltage.
Thanks
http://forums.parallax.com/showthread.php/160950-Need-code-for-MCP3428-Please
Here is a link to another approach. See post #14. You need the jm PASM driver from post #2.
http://forums.parallax.com/showthread.php/161040-Another-i2c-assembly-driver
_clkmode = xtal1 + pll16x 'clock mode
_xinfreq = 5_000_000 '* crystal frequency
CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
'MCP3428 ADC Values
SCL = 17 ' Clock MCP3428 Pin 8
SDA = 18 ' Data In/Out MCP3428 Pin 7
OBJ
SN : "Simple_Numbers"
'pst : "Parallax Serial Terminal Plus"
DEBUG : "FullDuplexSerial"
adc : "jm_mcp342x"
VAR
Byte DataH, DataL, DataC
PUB Main
' pst.Start(57600)
DEBUG.start(31, 30, 0, 9600)
'MCP3428 Initialized
adc.startx(SCL, SDA, 0, 0)
' adc.set_channel(0,0)
adc.set_channel(0,16,1)
repeat
DataH := adc.raw2mv(0,16,1)
DataL := adc.raw2mv(1,16,1)
DataC := adc.raw2mv(2,16,1)
DEBUG.tx($D)
DEBUG.str(string("Data H... "))
DEBUG.Dec(DataH)
DEBUG.tx($D)
'pst.Position(1, 16)
' pst.Dec(DataL)
'pst.Position(1, 22)
'pst.Dec(DataC)
' pst.Str(String(" "
http://forums.parallax.com/showthread.php/161040-Another-i2c-assembly-driver.
That being said, I think after you do the adc.start, your loop should look like:
You should define myrawdata and millivolts both as longs.
JonnyMac or CelticLord or DuaneD, feel free to jump in here anytime. I'm a little out of my depth; I just ever used JonnyMac's PASM I2C driver.
Edit: I removed the first adc.read_raw call.
I tried both Tom's demo code from the other thread and the code below without luck.
Here's the output:
As can bee seen from the output, the code never gets past waiting for ready.
My first guess is I didn't wire something correctly (if any of you saw my PCB you'd likely agree). I'm hoping someone could check over the demo code I used for Jon's object to see if did something wrong.
Edit: I'm not sure if I'm using the correct parameters with the start call. I'm using float on each address bit but I'm not sure this is correct. I have a few more things to try.
Edit again: Sorry for not including the child objects to the above program. The archive attached to post #14 includes the child objects used by both this program and my latest demo program (neither programs appear to work).
I decided to try each possible combination of addresses (I suppose they're not really bits since there are three possible states).
Here's my latest (failed) demo attempt:
Here's the output from the code:
I'm attaching an archive of the program so the child objects are available. The "Format" object is used in the "ReadableBin" method (which I think makes it easier to read binary data).
I'm not sure what else to try with the software so for now, I'll check my wiring. Hopefully I made an easy to fix wiring error.
BTW, I'm running the program on a QuickStart board and I'm using the EEPROM's I2C bus.
Duane, I think you did two things wrong (well, not wrong, just different from what works)
1. You have to use adc.startx rather than adc.start so that you override the default i2c pins (28 and 29).
2. After starting the conversion with adc.set_channel, you have to execute a read prior to each time you do adc.ready. adc.ready does NOT actually read the config register.
3. It is probably easiest to use all the adc#CONSTANTs from the driver to set bits and gain.
Edit: I take back item 1 since you are using the EEPROM i2c. EndEdit
I'm glad to know I wasn't doing it wrong.
I was only doing #2 "different from what works." Since I was using the default I2C pins I think the start method shouldn't have been a problem.
I moved my I2C lines to match yours and sure enough the code works!
Thank you very much!
Now I need to add a voltage divider to my circuit since I didn't realize this ADC is saturated at 2.048mV.
Thank you again. You've saved me from a lot of frustration.
Edit: The saturation point is 2.048V not 2.048mV.
Regards
Bob
Tom has a tendency to do that.
I'm glad you let us know you got your chip working too. I was just wondering if you had seen Tom's code.
Of course JonnyMac also deserves some praise for contributing the driver. (I learned PASM (and a bunch of other stuff) from reading Jon's Spin Zone columns.)
What a great forum.
I have a fixed divider going to one side of the (differential) input and a potentiometer between 3.3 and VSS to the other, so I can test both positive and negative.
I have a fixed divider going to one side of the differential input and a variable divider (pot) going to the other. So I can test positive and negative values.
When I first ran this, I observed that the voltage returned varied with the gain variable. Higher gain, lower indicated voltage. It turned out the my voltage dividers were very high impedance (100s of Kohms). I changed the dividers to a few hundred ohms and got much more consistent results. It turns out that the impedance impedance is on the order of 1 Mohm and varies with the gain.
This will allow you to use your original higher resistor values (verify it with your test program, of course) and greatly reduce your current draw, which is probably why you chose the higher values in the first place.
I only see small differences reading voltages without a bypass cap on, say, an MCP3304, but when I read small voltages from a shunt, it can be off by a factor of 2 without the caps. Your TI ADC must be rather power hungry.
Thanks for the reminder. I saw capacitors mentioned in the datasheet but I personally hadn't added them to my circuit. I'll make sure and do this.
I'm curious to learn how Tom does with caps added to his circuit.
Ideally, the input source impedance should be
zero. This can be achievable by using an operational
amplifier with a closed-loop output impedance of tens
of ohms.
I did try a 104 ceramic cap *between* the differential inputs and it didn't really make any difference. I would worry about frequency response with large Rs and Cs (even knowing the max sample rate is 10s or 100s of Hz already).
http://cds.linear.com/docs/en/datasheet/2487ff.pdf