Shop OBEX P1 Docs P2 Docs Learn Events
I'm confused - P2-ES to MCP3204 — Parallax Forums

I'm confused - P2-ES to MCP3204

I've connected an MCP3204 ADP to the P2-ES and programmed it using TAQOZ. The program (below) measures the voltage on each of the 4 channels and displays it on the terminal as "volts * 10" (e.g. 3.3v shows as 33 volts). The 4 channels and the MCP3204 are wired as shown in Chapter 4 of "Programming & Customizing the Propeller Microcontroller" book.

Channels 0 and 1 are connected to potentiometers for variable voltages. Channel 2 is connected to ground (0 volts) and channel 3 is connected to 3.3v on the P2-ES.
ch# 0 31 volts
ch# 1 49 volts
ch# 2 0 volts
ch# 3 15 volts

Everything works well, except the channel connected to 3.3v displays 15 (i.e. 1.5v). I have switched the 3.3v connection to different channels, but whatever channel it is connected to displays 15.

I have tried moving the P2-ES jumper to the LDO setting, but got the same result. If I disconnect the channel from 3.3v and connect it to 5v, it displays 4.9v as I expect. I've measured the voltage of the v0815 pin to gnd using a DVM and it shows 3.3v.

Any ideas?
Thanks
Tom

This is the code I am using:
---  ------------------------------------------------------
---  **** go3204 
---        This word uses the 3204 to measure volts on 4 channels
---  ------------------------------------------------------

--- define SPI pins
   8   := *SCLK    9   := *MISO    10   := *MOSI    11   := *CS
--- define number of command and indata bits
   5  := *CMDBITS     13 := *INBITS

: clockbit   *SCLK HIGH *SCLK LOW ;
: cmdvalue  ( channel_number -- command )    %11000 OR ;

: start3204   *CS HIGH *SCLK LOW *CS LOW ;

---       sendcmd    Send 1 startbit (high), 4 command bits, 1 don't care bit
: sendcmd 		( channel  --  )
 cmdvalue   	(  channel -- command ) 
32  *CMDBITS -   	( -- command, 32-CM )
<<   		(  -- command shifted to MSB ) 
*CMDBITS  0 
DO 
     1 rol dup 1 AND 
        if *MOSI high 
        else *MOSI low 
        then 
     clockbit
loop  drop  *MOSI low clockbit ;

---   END 3204 sendcmd

--- Receive 13 bits from 3204 and drop initial bit 
: getdata ( -- 12bit_raw ) 0 ( will become raw ) *INBITS ( includes 1st don't care bit ) 
  FOR 2* clockbit *MISO pin@ 1 and or NEXT ( -- 13bit_raw ) 
  4095 and ( -- 12bit_raw ) ;

--- Calculate volts from 12bit raw
: volts ( 12bit raw -- volts x 10 )  50 * 4096  / ;

--- main word
: read3204 ( channel number --  volts ) 
  start3204 sendcmd getdata volts *CS HIGH ;

--- Get data from all 4 channels and display it
: go3204  
    CRLF 4 0 do i dup ." ch# " . ."  " 
    read3204 . ."  volts " CRLF loop CRLF ;

--- **** Type go3204 to run program  ****


Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-05 02:22
    Try looking at the raw data as well. Use this version that uses the formatted number print .AS"
    --- main word
    : raw3204 ( chan num -- data )			start3204 sendcmd getdata *CS HIGH ;
    \ : read3204 ( channel number --  volts )		raw3204 volts ;
    
    --- Get data from all 4 channels and display it
    : go3204    4 0 do CRLF i .AS" ch#| # " i raw3204 DUP .AS" raw=####  " volts .AS" #.# volts "  loop CRLF ;
    

    Testing (without any chip)
    TAQOZ# go3204 
    ch# 0 raw=4095  4.9 volts 
    ch# 1 raw=4095  4.9 volts 
    ch# 2 raw=4095  4.9 volts 
    ch# 3 raw=4095  4.9 volts 
     ok
    
  • Peter,
    Thanks.
    I ran the code you posted and got the following:
    Channel 3 connected to V0815 (LDO)
    Channels 0 and 1 connected to potentiometers
    Channel 2 connected to GND
    
    ch# 0 raw=2765  3.3 volts
    ch# 1 raw=2373  2.8 volts
    ch# 2 raw=0000  0.0 volts
    ch# 3 raw=1255  1.5 volts
    
    Channel 3 connected to 5v (in 0815 bank)
    
    ch# 0 raw=2765  3.3 volts
    ch# 1 raw=2373  2.8 volts
    ch# 2 raw=0000  0.0 volts
    ch# 3 raw=4093  4.9 volts
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-05 02:59
    There's nothing wrong with the functioning of the software but I wouldn't count on an unloaded LDO regulator as a voltage reference. Put a 1k load on that and see what it does then. It could well be oscillating and you are reading an average perhaps.

    Believe what your ADC is telling you, don't assume it is your software.
  • twm47099twm47099 Posts: 867
    edited 2019-01-05 03:52
    I did a few tests, and I'm not sure about either the ADC or my wiring. I measured the voltage on each channel using the DVM. All ADC channels show 4.9v when the DVM shows 5 v. But as I reduce the voltage (either by using the potentiometers or even applying 3v from 2 AA batteries, the voltage reading on the ADC is significantly less than that on the DVM.

    The ADC is wired up on a breadboard using 100mm long jumpers. (In the past I've used a similar setup on my Propeller Professional Development Board with joysticks & an MCP3208 and the readings were accurate. But the wiring was not as rat's nesty as my current setup).

    I didn't collect enough data this time to plot ADC vs DVM so I don't know if there is a linear relation or not.

    I'm going to rewire and also try a different 3204.

    Any ideas as to what is causing the voltage difference as voltage is reduced?

    And Peter thanks for the example of .AS"

    Tom




  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-01-05 04:22
    @twm47099
    Since you are only using one decimal place without rounding you will see 4.9V instead of 4.9. You will never get 5V because your calculation is based on 4096 as the highest value when the ADC can only read back 4095.

    Have a look at this slightly modified version of your code that uses two decimal place (but no rounding) and reports 5.00 volts for maximum reading.
    TAQOZ
    ---  ------------------------------------------------------
    ---  **** go3204
    ---        This word uses the 3204 to measure volts on 4 channels
    ---  ------------------------------------------------------
    
    --- define SPI pins
       8   := *SCLK    9   := *MISO    10   := *MOSI    11   := *CS
    ( cmdbits and inbits are fixed and only used inside single word )
    
    : start3204   		*CS HIGH *SCLK LOW *CS LOW ;
    
    
    : PIN! ( dat0 pin -- )	SWAP 1 AND IF HIGH ELSE LOW THEN ;
    : MOSI! ( state -- )	*MOSI PIN! ( ALSO CLOCKS BIT )
    : clockbit   		*SCLK HIGH *SCLK LOW ;
    
    ---       sendcmd    Send 1 startbit (high), 4 command bits, 1 don't care bit
    : sendcmd 		( channel  --  )
    	%11000 OR   	(  command )
    	27 << REV ( flipped command<<32-CM )
    	--- clock command bits plus dummy don't care bit
    	6 FOR DUP MOSI! 2/ NEXT DROP
    	;
    
    ---   END 3204 sendcmd
    
    --- Receive 13 bits from 3204 but first bit is null anyway
    : getdata ( -- 12bit_raw )
    	0 13 FOR 2* clockbit *MISO pin@ 1 AND or NEXT
    	;
    
    --- Calculate volts from 12bit raw
    : volts ( 12bit raw -- volts x 10 )  500 * 4095  / ;
    
    --- main word
    : raw3204 ( chan -- data  )			start3204 sendcmd getdata *CS HIGH ;
    \ : read3204 ( channel number --  volts )		raw3204 volts ;
    
    --- Get data from all 4 channels and display it
    : go3204    4 0 do CRLF i .AS" ch#| # " i raw3204 DUP .AS" raw=####  " volts .AS" #.## volts "  loop CRLF ;
    
    --- **** Type go3204 to run program  ****
    END
    
  • @ Tom
    I did a few tests, and I'm not sure about either the ADC or my wiring

    Ok I'll try it too. I have a bucket of old pots, lots of wire and hopefully there are some(4) 5k or 10k pots in the pile . I have a MCP3208 which is the same thing with 4 extra channels . Hopefully it still works correctly after my last experiments with it. LOL I don't have the reference book you mentioned above however, I will use the MPC3208 PDF to figure the pinouts.I will try Peter's code . I have the soldering station heating up and will start on it tonight but it's late and may have to finish it sometime tomorrow. I played with TAQOZ a little last night and it's been fun! (Thanks Peter). This will be my first experiment with the P2-ES . :)
  • OK, Now I'm going nuts. I cleaned up the wiring a bit and then ran some tests to plot ADC_reading vs DVM reading (using a potentiometer to adjust the voltage.)

    Results:
    DVM          ADC
    5.00		5.00
    4.60		4.06
    4.40		3.67
    4.00		2.89
    3.60		2.10
    3.30		1.51
    3.30		1.52
    3.00		0.90
    2.60		0.14
    2.57		0.06
    
    
    Plotted in EXCEL it is linear. But as I reduced the voltage more this happened:
    DVM         ADC
    2.50		4.94
    2.40		4.75
    2.30		4.54
    2.00		3.96
    1.00		1.96
    0.60		1.18
    0.40		0.81
    
    
    Also linear, but it seems that between 2.57 and 2.50v the ADC = 0 and then it started high again ???
    Any idea what is going on???

    Tom
  • Where do you have pins14 and Pin 13 of the ADC tied to ?
  • jmgjmg Posts: 15,173
    twm47099 wrote: »
    Also linear, but it seems that between 2.57 and 2.50v the ADC = 0 and then it started high again ???
    Any idea what is going on???
    Looks pretty much like an off-by-1 problem, in the data alignment.
    eg if you lose the MSB, and scale the remaining bits, that's the plot you would expect - two sawtooths, with a ~ zero at 50% scale.

  • Where do you have pins14 and Pin 13 of the ADC tied to ?

    +5v on the P2-ES board
  • I tried Peter's code and it appeared to give values that were 2x high. I put a 2/ (shift 1bit right) in the raw3204 definition after the getdata and before the *CS.
    : raw3204 ( chan -- data  )			start3204 sendcmd getdata *CS HIGH ;
    

    That appears to work. Now I have to figure out what is wrong with my code.
    Tom
  • What value pot are you using?

    The ADC input on the MCP320x needs something reasonably stiff (or ideally an op amp buffer to drive the ADC)
  • twm47099twm47099 Posts: 867
    edited 2019-01-07 06:33
    Removing the last line (4095 and) in the definition of getdata gives me the same result as Peter, which was 2x the DVM measured data. looking at the raw values, I saw one was 8183 (9.98v). That was a 13 bit number, which didn't make sense since the first bit was supposed to be a low null.
    EDITED
    I think that in the word sendcmd the last line (*MOSI low clockbit) needed to be deleted. When I did that I got good values. Channel 3 that was connected to 3.3 v showed an ADC value of 3.25 v, and I didn't get the reversal of values like I saw above.

    Peter suggested that the problem was having clockbit before reading the MISO pin in the getdata definition. putting clockbit after the pin@ and adding "*MOSI low clockbit" back as the last line of the sendcmd definition works.

    The cleaned up code is:
    ---  ------------------------------------------------------
    ---  **** go3204 
    ---        This word uses the 3204 to measure volts on 4 channels
    ---  ------------------------------------------------------
    
    --- define SPI pins
       8   := *SCLK    9   := *MISO    10   := *MOSI    11   := *CS
    
    : clockbit   *SCLK HIGH *SCLK LOW ;
    : cmdvalue  ( channel_number -- command )    %11000 OR ;
    : start3204   *CS HIGH *SCLK LOW *CS LOW ;
    
    ---    sendcmd    Send 1 startbit (high), 4 command bits, 1 don't care bit
    : sendcmd 	( channel  --  )
     cmdvalue   27 <<   (  -- command shifted to MSB ) 
    5  0 DO 
           1 rol dup 1 AND 
            if *MOSI high 
             else *MOSI low 
            then 
    clockbit loop  drop  
    *MOSI low clockbit   --- ***** This is added based on Peter's comments below
    ;
    ---   END 3204 sendcmd
    
    --- Receive 13 bits from 3204 and drop initial bit 
    : getdata ( -- 12bit_raw )
    
    --- ***** clockbit is moved after *MISO pin@ based on Peter's comment below
     0  13 FOR 2* *MISO pin@ clockbit 1 and or NEXT ( -- 13bit_raw ) 
     4095 and ( -- 12bit_raw ) 
    ;
    
    --- Calculate volts from 12bit raw
    : volts ( 12bit raw -- volts x 100 )  500 * 4096  / ;
    
    --- main word
    : raw3204 ( chan num -- )    start3204 sendcmd getdata *CS HIGH ;
    
    --- Get data from all 4 channels and display it
    : go3204    4 0 do CRLF i .AS" ch#| # " i raw3204 
       DUP .AS" raw=####  " volts .AS" #.## volts "  loop CRLF ;
    
    --- **** Type go3204 to run program  ****
    
    

    Thanks Peter and JMG

    Tom
  • Ok I'm wired up with 10K pots and I copy and pasted the TAQOZ code into Puddy. Now I need to read up on how to use TAQOZ :) but it's getting too late (3am) so it looks like tomorrow I can try it.
    2340 x 4160 - 3M
    2340 x 4160 - 3M
  • About your power connections, are you hooking up 3.3V, 5V and GND from one of the 12way PCB edge headers?

    That would be good.

    Sourcing power from anywhere else on the PCB is not recommended.
  • Bob,
    The circuit I referred to in the book has a 10k resistor in series with Dout (MISO) since the ADC is running on 5v.

    Tom
  • I looked at the datasheet again and I think that after 5+1 bits of the command that when you read you need to read the data before clocking, rather than after. You could try this version and when I get a chance I will check it on the scope and possibly the a chip as well although I only have the MCP3208s.
    TAQOZ
    ---  ------------------------------------------------------
    ---  **** go3204
    ---        This word uses the 3204 to measure volts on 4 channels
    ---  ------------------------------------------------------
    
    --- define SPI pins
       8   := *SCLK    9   := *MISO    10   := *MOSI    11   := *CS
    ( cmdbits and inbits are fixed and only used inside single word )
    
    
    : PIN! ( dat0 pin -- )	SWAP 1 AND IF HIGH ELSE LOW THEN ;
    : MOSI! ( state -- )	*MOSI PIN! ( ALSO CLOCKS BIT )
    : clockbit   		*SCLK HIGH *SCLK LOW ;
    
    ---       sendcmd    Send 1 startbit (high), 4 command bits, 1 don't care bit
    : CMD3204 		( channel  --  )
    	*CS HIGH *SCLK LOW *CS LOW
    	%11000 OR   	(  command )
    	27 << REV ( flipped command<<32-CM )
    	--- clock command bits plus dummy don't care bit
    	6 FOR DUP MOSI! 2/ NEXT DROP
    	;
    
    ---   END 3204 sendcmd
    
    --- Receive 13 bits from 3204 but first bit is null anyway
    : GET3204 ( -- 12bit_raw )
    	0 13 FOR 2* *MISO pin@ clockbit 1 AND or NEXT
    	$FFF AND ( optional mask - mainly for dummy testing )
    	*CS HIGH
    	;
    
    --- Calculate volts from 12bit raw
    : volts ( 12bit raw -- volts x 10 )  500 4095  */ ;
    
    --- main word
    : RAW3204 ( chan -- data  )			CMD3204 GET3204 ;
    
    --- Get data from all 4 channels and display it
    : go3204    4 0 do CRLF i .AS" ch#| # " i RAW3204 DUP .AS" raw=####  " volts .AS" #.## volts "  loop CRLF ;
    
    --- **** Type go3204 to run program  ****
    END
    
  • twm47099twm47099 Posts: 867
    edited 2019-01-07 06:35
    Peter,
    That was the problem. clockbit comes after reading the pin.

    I found an old data sheet that I had previously used with the 3208 (also shows the 3204), and the timing diagram is clearer showing that.
    EDIT
    I changed the code to incorporate Peter's fix in the listing approx 7 posts back..
    Tom
Sign In or Register to comment.