PCF8591 input reads
I have a few questions about reading from a PCF8591. I'm read over the datasheet several times and there are some this that I just don't get.
Below is a small bit of code I'm using to attempt to read Input 3.
I seem to always get a 128. (When I have the input pin at 3.3 volts, which is what the PCF is running at, which should result in data2 reading 255).
My questions are:
- Obviously, this type of selective read isn't working? Any tips?
- The datasheet and the nuts and volts article I read refer to having to ditch the first read value because its the 'last' value. I'm doing this with the data1 variable in this case. Is this really needed in a selective read like this?
- I don't understand the auto increment. I'm not using it here, but if I used it, would I just perform 5 reads. (The first one being junked because of the above, and then I would read the 4 inputs?
- DO I need to re issue the control byte on every read like the above, or after executing it once, can I continuously perform the following to get constant updates
-
Below is a small bit of code I'm using to attempt to read Input 3.
PUB ReadAD(SCL, devSel) | ackbit,data1,data2 Start(SCL) ackbit := (ackbit << 1) | Write(SCL, (devSel&!(|<0))) ackbit := (ackbit << 1) | Write(SCL, %00000011) Start(SCL) ackbit := (ackbit << 1) | Write(SCL, (devSel|1)) data1:=Read(SCL,ACK) data2:=Read(SCL,NAK) Stop(SCL) return data2
I seem to always get a 128. (When I have the input pin at 3.3 volts, which is what the PCF is running at, which should result in data2 reading 255).
My questions are:
- Obviously, this type of selective read isn't working? Any tips?
- The datasheet and the nuts and volts article I read refer to having to ditch the first read value because its the 'last' value. I'm doing this with the data1 variable in this case. Is this really needed in a selective read like this?
- I don't understand the auto increment. I'm not using it here, but if I used it, would I just perform 5 reads. (The first one being junked because of the above, and then I would read the 4 inputs?
- DO I need to re issue the control byte on every read like the above, or after executing it once, can I continuously perform the following to get constant updates
Start(SCL) ackbit := (ackbit << 1) | Write(SCL, (devSel|1)) data1:=Read(SCL,ACK) data2:=Read(SCL,NAK) Stop(SCL)
-

Comments
(2) After that you can read ad infinitum; you either get the values from one channel or cycling through the 4.
(3) I think there is too much ado about this "first" value... It is just the last value sampled, as the sampling process will only start with the read command and takes some time, so it MIGHT be unclear from what channel and from what time this value comes...
(4) I am not sure with what channel each new read starts in auto-incrementing mode.. I THINK it will will go on with the last channel, so it might be a good practice to repeat the configuration setting before each sequence of reads...
Heres the current code running in a loop:
UB ReadAD(SCL, devSel) | ackbit,data1,data2 Start(SCL) ackbit := (ackbit << 1) | Write(SCL, (devSel&!(|<0))) ackbit := (ackbit << 1) | Write(SCL, %00000011) ackbit := (ackbit << 1) | Write(SCL, %00000000) Stop(SCL) Start(SCL) ackbit := (ackbit << 1) | Write(SCL, (devSel|1)) data1:=Read(SCL,NAK) Stop(SCL) return data1My circuit
PIN = Tied to
(1-3)AIN1-AIN2 = Vss
(4)AIN3 = (Sampling input, for testing I've tied this to 3.3 volts)
(5-7)A0-A2 = Vss
(8)Vss = Vss
(9-10)SDA-SCL = I2c bus
(11)OSC = Floating
(12)EXT = Floating
(13)AGND = Vss
(14)VRef = 3.3V(Vdd)
(15)AOut = Floating
(16)Vdd = 3.3v
Very, very strange, I'm stumped. This is such a basic component.
Thanks!
If that does not work, you should check the ACKs, they should all be 0....
If not here is code that is checked with my "smallI2Cdriver":
'' MPE_I2C_002 '' Minimal I2C driver 2008-01 by deSilva ' ----- The following section is a test routine _clkmode = xtal1 + pll8x _xinfreq = 10_000_000 DEVICE = $90 LEDPIN = 25 PUB checkOut | i , x , status { This checks my minimal I2C driver, using a PCF8591 DAC/4-Channel ADC +─  ─┐ A O + O + - O - C D ┌┴─┴─┴─┴─┴─┴─┴─┴┐ │(8591) │ │ │ └┬─┬─┬─┬─┬─┬─┬─┬┘     - - - - 0 1 2 3 At pin OO a 1.5 kHz signal should be measured (conversion clock) AO will output DAC } REPEAT engage i:=snd(DEVICE) i := (i<<1) + snd($00) ' read from Port 0 ' $04 : cycle through all ports release REPEAT engage i:= (i<<1) + snd(DEVICE+1) DIRA[noparse][[/noparse]LEDPIN]:= (i<>0) x := rcv { or read multiple values... ACK x := rcv } release ' An alternative: Generate a Ramp-Up REPEAT engage i:=snd(DEVICE) i := (i<<1) + snd($40) DIRA[noparse][[/noparse]LEDPIN]:= (i<>0) REPEAT x from 0 to 255 snd(x) release ' ===========Here starts deSilva's small I2C driver (V.002) CON SCL = 28 SDA = 29 PUB engage ' Pulls SDA to LOW whilst CLK is HIGH dira[noparse][[/noparse]SCL]~~ outa[noparse][[/noparse]SDA]~ 'The former two instructions need be done only once, if all is o.k. outa[noparse][[/noparse]SCL]~~ dira[noparse][[/noparse]SDA]~ ' Pulse SDA; HIGH by pullup (default) dira[noparse][[/noparse]SDA]~~ ' Enable = LOW outa[noparse][[/noparse]SCL]~ ' Keep SCL LOW PUB snd(by) : status | i ' Send a byte (and get status: 0: ACK 1: NAK) by := (!by) >< 8 ' Reverse bits and invert pattern REPEAT 8 dira[noparse][[/noparse]SDA] := by outa[noparse][[/noparse]SCL]~~ ' Transfer on rising edge by >>= 1 outa[noparse][[/noparse]SCL]~ ' Returns "acknowledge bit": 0 = ACK, 1 = NAK. dira[noparse][[/noparse]SDA]~ ' release SDA outa[noparse][[/noparse]SCL]~~ ' puls-in ACK status := ina[noparse][[/noparse]SDA] outa[noparse][[/noparse]SCL]~ ' keep CLK low PUB release ' Assert stop condition. ' SDA transits from LOW to HIGH whilst SCL is HIGH dira[noparse][[/noparse]SDA]~~ ' LOW outa[noparse][[/noparse]SCL]~~ dira[noparse][[/noparse]SDA]~ ' release SDA (HIGH) PUB rcv : val ' Get a byte REPEAT 8 outa[noparse][[/noparse]SCL]~~ ' Request bit val <<= 1 val |= ina[noparse][[/noparse]SDA] outa[noparse][[/noparse]SCL]~ ' Keep CLK low PUB rcvack : val ' new v002 ' Get a byte... and more REPEAT 8 outa[noparse][[/noparse]SCL]~~ ' Request bit val <<= 1 val |= ina[noparse][[/noparse]SDA] outa[noparse][[/noparse]SCL]~ ' Keep CLK low ' Send ackbit dira[noparse][[/noparse]SDA]~~ ' set LOW outa[noparse][[/noparse]SCL]~~ ' Pulse SCL outa[noparse][[/noparse]SCL]~ ' keep CLK low dira[noparse][[/noparse]SDA]~ ' release SDA PUB nak ' mod v002 ' Send ackbit dira[noparse][[/noparse]SDA]~ ' HIGH (korr!) outa[noparse][[/noparse]SCL]~~ ' Pulse SCL outa[noparse][[/noparse]SCL]~ ' keep CLK low PUB ack 'mod v002 ' Send ackbit dira[noparse][[/noparse]SDA]~~ ' set LOW outa[noparse][[/noparse]SCL]~~ ' Pulse SCL outa[noparse][[/noparse]SCL]~ ' keep CLK low dira[noparse][[/noparse]SDA]~ ' release SDAPost Edited (deSilva) : 1/23/2008 10:26:04 PM GMT