Setting ADC range on MCP3208

I'm using MCP3208 8 channel ADC to read the wiper on a 10K multi-turn pot. I get no output from the ADC using the 'jm_mcp3208_ez' object for most of the range of the pot. I'm using 5v across the pot for the voltage. Is there a way to adjust the low end of the output so I get a value? The pot is reading about 500 ohm at the low end with an ADC output of 0.
The code listed below works but the value output to the PST is 0 for quite a bit of the pots rotation. Once the pot starts registering an output it keeps up for the rest of the rotation. It just doesn't want to read the low values. Looking to see if I'm overlooking something basic... The output of the pot wiper feeds directly to the channel 1 inpit of the ADC. The ADC is powered by 5V and the output of the ADC is fed to the prop through a 1k resistor.
Bob
The code listed below works but the value output to the PST is 0 for quite a bit of the pots rotation. Once the pot starts registering an output it keeps up for the rest of the rotation. It just doesn't want to read the low values. Looking to see if I'm overlooking something basic... The output of the pot wiper feeds directly to the channel 1 inpit of the ADC. The ADC is powered by 5V and the output of the ADC is fed to the prop through a 1k resistor.
obj
ADC: "jm_mcp3208_ez"
PST : "parallax serial terminal
Pub main
ADC.init(7,8,9)
PST.start(115200)
Waitcnt(MS_001 + cnt)
Adctest
Pub ADCTest | t! check, temp! I
T:= cnt
ch := 1
repeat
I := 0
Repeat temp from 0 to 9
I := I + ADC.read(ch, 0)
I := I/10
PST.str(string(pst#NL, "ADC: "))
PST.dec(I)
Waitcnt(t += constant(MS_001 * 250))
Bob
Comments
I've had trouble with the MCP3208. I'm pretty sure the trouble was caused by my reading samples to frequently. The MCP3208 doesn't like high impedance sources. I think 10K is a bit too high of a resistance for frequent sampling.
It was suggested I use a small cap on the ADC input pin in order to aid in getting stable readings when I asked about this problem once.
I think a cap and slower sampling rate should help.
Have you measured the wiper with a voltmeter?
You really should have a 3K or better resistor on a Prop input pin from a 5V source. I know 1K was used a lot early on but it was determined that it wasn't really safe to do so. The current through the clamping diode shouldn't be more than 500uA.
Somehow, I ended up putting a bogus mcp320x library into ObEx -- will take it down ASAP. I've attached a fixed-up mcp3208 object that should work for you. Note that there was also an error in the documentation: the mode value for single-ended is 1, not 0.
Give this code snippet a try.
pub adc_test | t, ch t := cnt repeat pst.char(pst#HM) ' move cursor home repeat ch from 0 to 7 ' loop through 8 channels pst.char(idx + "0") ' display channel # pst.char(":") pst.char(" ") pst.dec(adc.read(ch, adc#SE)) ' display channel level pst.char(pst#CE) ' clean-up end-of-line pst.char(pst#NL) ' next line waitcnt(t += (clkfreq >> 2)) ' update every 250ms
Note, too, that .init and .finalize have been properly renamed .start and .stop (this was a clue you had very old code). Again, sorry I posted an old file -- I guess some system purging is in order.
EDIT: Updated files posted in ObEx (16 DEC 2013)
-- http://obex.parallax.com/object/315
Worked well for reading the pot values, although I think they may have been 500 ohms.
pri mcpread | i '******************************************************************************************************** ' read all 8 channels from the ADC and store them. in(channel) : sample '******************************************************************************************************** repeat i from 0 to 7 step 1 mcpch[i] := mcp.in(i)
The object I used was chip's original MCP3208 demo, although it seems to have been updated. The link for the updated object is: http://obex.parallax.com/object/370
I'll report back on my results later.
I have updated my libary in ObEx.
-- http://obex.parallax.com/object/315
Again, I'm sorry I provided a bad file that gave you a bit of trouble.
the same time without scrolling the screen or anything.
Edit: I misread your post you only need one 3.3k between DOUT and DIN and make the Propeller connection on DIN only not on DOUT.
Con _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 Var long Samples[8] Obj ADC: "jm_mcp3208_ez" PST : "parallax serial terminal" Pub Main | channel ADC.start(7,8,9) PST.start(115200) Waitcnt(clkfreq + cnt) repeat GetAllChannels pst.char(pst#HM) pst.dec(Samples[0]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[1]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[2]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[3]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[4]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[5]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[6]) pst.char(pst#CE) pst.char(pst#NL) pst.dec(Samples[7]) pst.char(pst#CE) waitcnt(clkfreq/100 + cnt) Pub GetAllChannels | channel repeat channel from 0 to 7 Samples[channel] := ADC.read(channel, 1)
Thanks for the rapid turn around. I replaced the old object and everything is working as expected! Made for a much better evening spent testing programming. This is for a robot I'm building (see the Next Large Robot thread in the robotics forum for more details). I've been able to test and calibrate the femur and tibia motors. Next stop is the Coxa motor which will use the same routines.
I appreciate everyone else's input also, I can see a place for some of the other code fragments later.
Bob