Shop OBEX P1 Docs P2 Docs Learn Events
What am I doing wrong? (mcp3208) — Parallax Forums

What am I doing wrong? (mcp3208)

turbosupraturbosupra Posts: 1,088
edited 2012-02-22 06:04 in Propeller 1
I am trying to interface the mcp3208 ADC with my propeller. I have taken a picture of the setup, and I know it is hard to make sense of a 3d setup on a 2d picture, so I will describe it as well. I am using object 488 in the object exchange (Brandon Nimons), http://obex.parallax.com/objects/488/ .

As you can see in the picture (see picture below), the pressure sensor I am using as my analog voltage item is outputting 0.41vDC and that output is going to adc pin 1 of the 3208. Adc pins 2-8 are empty. Adc pin 9 goes to ground, Adc pin 10 goes to pin 14 in my prop (which is configured as the CS pin my object), Adc pins 11/12 are tied together and go to pin 13 on my prop (which is configured as the data in/out pin my object), Adc pin 13 goes to pin 15 on my prop (which is configured as the CLK pin my object). Adc pin 14 is grounded, Adc pin 15/16 go to 5v supply voltage.


ADC pin 1 = analog voltage from sensor
ADC pins 2-8 = not connected
ADC pin 9 = grounded
ADC pin 10 = prop pin 14
ADC pin 11/12 = prop pin 13
ADC pin 13 = prop pin 15
ADC pin 14 = grounded
ADC pin 15/16 = supply +5vDC

I hooked up my prop scope and I'm seeing voltage spikes (see picture below), but the output to the terminal is empty (see picture below). Since I'm getting > 2v digital signals to pin 13 on my prop, can anyone tell me what I'm doing wrong here? It appears to be the way I'm using the driver, and since this is my first time using it, it is something I am overlooking or doing wrong.





adcsetup1.png


adcoutput1.png


adcscopeoutput1.png


Here is the code I'm using
''****************************************************************
''* Read documentation at top of ADC_INPUT_DRIVER for complete   *
''* information on copyright and usage.                          *
''* Each method also has it's own explaination on functionality. *
''****************************************************************
CON

  { ==[ CLOCK SET ]== }       
  _CLKMODE      = XTAL1 + PLL16X
  _XINFREQ      = 5_000_000                          ' 5MHz Crystal

 {Vclk_p        = 12     ' clock pin
  Vn_p          = 13     ' data in
  Vo_p          = 14     ' data out
  Vcs_p         = 15     ' CS pin       }


  Vclk_p        = 15     ' clock pin
  Vn_p          = 13     ' data in
  Vo_p          = 13     ' data out
  Vcs_p         = 14     ' CS pin
OBJ

  DEBUG  : "FullDuplexSerial"    
  ADC    : "ADC_INPUT_DRIVER"

VAR    

  '===[ ONLY USED FOR start_pointed ]===
  LONG chanstate[8]   
  LONG chanval[8]     
  LONG chanmax[8]    
  LONG chanmin[8]

PUB Main
'' Select which type of driver start and value accessing you want

  Standard_example                                      ' Uses long blocks already in driver's object
  'Pointed_example                                       ' Requires the use of the above long blocks

PUB Standard_example | i
'' Start driver in normal mode and run some commands
      
  DEBUG.start(31, 30, 0, 115_200)
  waitcnt(clkfreq + cnt)  
  DEBUG.tx($D)   


  ADC.start(Vo_p, Vn_p, Vclk_p, Vcs_p, 8, 8, 12, 1, false) ' startup the ADC driver (Vo_p and Vn_p can be the same IO pin), 8 channel ADC,
                                                        ' scan all 8 channels, 12-bit ADC, mode 1 (single-ended), and using slow communication

  ADC.setthreshold(120, 200)                            ' not necisary if already setup in the ADC.start settings (but
                                                        ' these values can be altered at any time with this method), it
                                                        ' affects all of the chennels on the ADC


  DEBUG.str(string("Enable Standby"))
  ADC.standby_enable(6000)                              ' enable standby mode (put ADC and driver cog into wait mode to save power
                                                        ' it checks for the standby_disable every 6000 cycles (higher number could
                                                        ' save more power, but increase possible wait time during standby_disable
  waitcnt(clkfreq * 2 + cnt)
  DEBUG.str(string(" -- Disable Standby"))
  ADC.standby_disable                                   ' disable standby (any command will pull the driver out of standby, but
                                                        ' this one is specifically designed to wait for a complete exit and take
                                                        ' the least amount of time doing it        
  DEBUG.tx($D)                                                        
                
  i~   
  REPEAT
    IF (i // 10 == 9)
      DEBUG.str(string("Wait Hi... "))
      DEBUG.dec(ADC.waithigh(2, 2500, 0))               ' wait a maximum of 2.5 seconds or until channel 2's value is less than the
                                                        ' above threshold, it then displays the current value of the channel
                                                        ' (incase of watchdog timeout) a watchdog value of 0 would disable it, thus
                                                        ' it will wait indefinately
      DEBUG.tx($D)
      
      DEBUG.str(string("Wait Lo... "))
      DEBUG.dec(ADC.waitlow(2, 4000, 1))                ' wait a maximum of 4 seconds or until channel 2's value is below or equal
                                                        ' to the above threshold, it then displays the current value of the channel
                                                        ' (incase of watchdog timeout), If current state is low then there is no
                                                        ' wait.
      DEBUG.tx($D) 
      
      DEBUG.str(string("Reset Max/Min ")) 
      ADC.resetmaxminall                                ' reset all channel's maximum and minimum values to their defaults
      DEBUG.tx($D)
  
    DEBUG.str(string("Frequency: "))
    DEBUG.dec(ADC.getfreq(2, 1000, 3, 5, false))        ' attempt to determine a frequency on channel 2, but do not excede 1 second
                                                        ' get 8 sampless of the frequency before averaging the result, do not count
                                                        ' frequency clocks unless the channel is held high for at least 5 cycles
    DEBUG.str(string("Hz done in "))
    DEBUG.dec(ADC.getsamples)                           ' display number of ADC samples it took to determine the [above] frequency
    DEBUG.str(string(" samples"))
    DEBUG.tx($D)    

    DEBUG.str(string("Average:   "))
    DEBUG.dec(ADC.average_time(2, 500))                 ' gather the value of channel 2 for 500ms and calculate the average
    DEBUG.str(string(" average tested with "))
    DEBUG.dec(ADC.getsamples)                           ' display number of ADC samples it took to determine the [above] average
    DEBUG.str(string(" samples"))    
    DEBUG.tx($D)   
                        
    DEBUG.str(string("State:     "))
    DEBUG.dec(ADC.getstate(2))                          ' is channel 2 high (-1) or low (0) right now
    DEBUG.tx($D)

    DEBUG.str(string("Cur Value: "))
    DEBUG.dec(ADC.getval(2))                            ' what is the ADC value of channel 2 right now
    DEBUG.tx($D)
    
    DEBUG.str(string("Max Value: "))
    DEBUG.dec(ADC.getmax(2))                            ' what is channel 2's maximum value since the driver was started or since
                                                        ' it was last reset with ADC.resetmaxminall or ADC.resetmax
    DEBUG.tx($D)

    DEBUG.str(string("Min Value: "))
    DEBUG.dec(ADC.getmin(2))                            ' what is channel 2's minimum value since the driver was started or since
                                                        ' it was last reset with ADC.resetmaxminall or ADC.resetmin
    DEBUG.tx($D)

    DEBUG.tx($D)
    waitcnt(clkfreq + cnt)
    i++
    
PUB Pointed_example | i
'' Start driver with supplied variables and run some commands
      
  DEBUG.start(31, 30, 0, 115_200)
  waitcnt(clkfreq + cnt)  
  DEBUG.tx($D)   

  ADC.start_pointed(Vo_p, Vn_p, Vclk_p, Vcs_p, 8, 8, 12, 1, false, @chanstate, @chanval, @chanmax, @chanmin)
                                                        ' startup the ADC driver (Vo_p and Vn_p can be the same IO pin), 8 channel ADC,
                                                        ' scan all 8 channels, 12-bit ADC, and mode 1 (single-ended), and using slow communication.
                                                        ' Supplied are the addresses to 4 8-long blocks

  ADC.setthreshold(120, 200)                            ' not necisary if already setup in the ADC.start settings (but
                                                        ' these values can be altered at any time with this method), it
                                                        ' affects all of the chennels on the ADC

  
  DEBUG.str(string("Enable Standby"))
  ADC.standby_enable(6000)                              ' enable standby mode (put ADC and driver cog into wait mode to save power
                                                        ' it checks for the standby_disable every 6000 cycles (higher number could
                                                        ' save more power, but increase possible wait time during standby_disable
  waitcnt(clkfreq * 2 + cnt)
  DEBUG.str(string(" -- Disable Standby"))
  ADC.standby_disable                                   ' disable standby (any command will pull the driver out of standby, but
                                                        ' this one is specifically designed to wait for a complete exit and take
                                                        ' the least amount of time doing it        
  DEBUG.tx($D)                                                        
                
  i~   
  REPEAT
    IF (i // 10 == 9)
      DEBUG.str(string("Wait Hi... "))
      DEBUG.dec(ADC.waithigh(2, 2500, 0))               ' wait a maximum of 2.5 seconds or until channel 2's value is above 20, it
                                                        ' then displays the current value of the channel (incase of watchdog timeout)
                                                        ' a watchdog value of 0 would disable it, thus it will wait indefinately
      DEBUG.tx($D)
      
      DEBUG.str(string("Wait Lo... "))
      DEBUG.dec(ADC.waitlow(2, 4000, 1))                ' wait a maximum of 4 seconds or until channel 2's value is below or equal
                                                        ' to 12, it then displays the current value of the channel (incase of
                                                        ' watchdog timeout). If current state is low then there is no wait.
      DEBUG.tx($D) 
      
      DEBUG.str(string("Reset Max/Min ")) 
      ADC.resetmaxminall                                ' reset all channel's maximum and minimum values to their defaults
      DEBUG.tx($D)
  
    DEBUG.str(string("Frequency: "))
    DEBUG.dec(ADC.getfreq(2, 1000, 3, 5, false))        ' attempt to determine a frequency on channel 2, but do not excede 1 second
                                                        ' get 8 sampless of the frequency before averaging the result, do not count
                                                        ' frequency clocks unless the channel is held high for at least 5 cycles
    DEBUG.str(string("Hz done in "))
    DEBUG.dec(ADC.getsamples)                           ' display number of ADC samples it took to determine the [above] frequency
    DEBUG.str(string(" samples"))
    DEBUG.tx($D)    

    DEBUG.str(string("Average:   "))
    DEBUG.dec(ADC.average_time(2, 500))                 ' gather the value of channel 2 for 500ms and calculate the average
    DEBUG.str(string(" average tested with "))
    DEBUG.dec(ADC.getsamples)                           ' display number of ADC samples it took to determine the [above] average
    DEBUG.str(string(" samples"))    
    DEBUG.tx($D)   
                        
    DEBUG.str(string("State:     "))
    DEBUG.dec(chanstate[2])                             ' is channel 2 high (-1) or low (0) right now
    DEBUG.tx($D)

    DEBUG.str(string("Cur Value: "))
    DEBUG.dec(chanval[2])                               ' what is the ADC value of channel 2 right now
    DEBUG.tx($D)
    
    DEBUG.str(string("Max Value: "))
    DEBUG.dec(chanmax[2])                               ' what is channel 2's maximum value since the driver was started or since
                                                        ' it was last reset with ADC.resetmaxminall or ADC.resetmax
    DEBUG.tx($D)

    DEBUG.str(string("Min Value: "))
    DEBUG.dec(chanmin[2])                               ' what is channel 2's minimum value since the driver was started or since
                                                        ' it was last reset with ADC.resetmaxminall or ADC.resetmin
    DEBUG.tx($D)

    DEBUG.tx($D)
    waitcnt(clkfreq + cnt)
    i++
    
    
«1

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-20 11:39
    I didn't see it mentioned anywhere in your post about a resistor between the Prop and the ADC output.

    Since you're powering the chip with 5V, you'll want a 3.3K or more resistor between the ADC's output and the Prop. You could put the resistor between the chip's input and output pins and connect the Prop directly to the input pin.

    I'm not sure about any other problems you may be having; I just wanted to make sure you don't ruin a Prop while you figure this out.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 11:57
    Hi Duane,

    Thanks for the reply. The object creator (Brandon) told me the voltage divider circuit was optional? Are you saying there should be a single resistor (bare minimum) between the DO/DI ADC pins and the prop pin?

    I did connect pin 13 to +3.3vDC and got the following output on the terminal, so something is going on? Maybe the adc output pin needs a pull down?

    adc2output2.png
  • SRLMSRLM Posts: 5,045
    edited 2012-02-20 12:20
    If you'e powering your MCP3208 at 5v you'll need to protect the IO lines between the Propeller and ADC with a 3.3K+ resistor in line. This would be on the CLK, CS, and DOI lines.

    What is the voltage range that you expect to measure?

    You may also want to try out this code, just to see if you get something different. It's very simple to use:
    http://obex.parallax.com/objects/224/

    Note also that your VREF can't be higher than your VDD... It's not a problem, but it's caught me unawares before.
  • RaymanRayman Posts: 14,844
    edited 2012-02-20 12:27
    I think you only need a resistor on the data line output of MCP320X. Otherwise, it will put 5V directly on a Prop pin, which can damage the Prop...
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-20 12:38
    I'll second Rayman's "ouput only" needing the resistor.

    It's not to divide the voltage, it's to protect the IO pins as SRLM said. Though, the CLK, CS, and ADC input pins wont have 5V on them. You only need the resistor on the ADC's output pin since it will be outputting 5V with its logic signal.

    Just tie the ADC's pins 12&13 together with the resistor and connect pin 12 (if that's the ADC's input pin) to the Prop with a wire.
  • StefanL38StefanL38 Posts: 2,292
    edited 2012-02-20 12:48
    to state the obvius is the pressure-sensors ground connected to the propeller-ground?

    To test new circuits you can do a quick try with the whole thing (as you did) if this does not work
    go back to the most basic system that's possible. In this case the most basic system is a simple voltage-divider formed by two resistors between +5V and ground.

    GND
    Resistor1
    x
    Resistor2
    +5V

    Feed the voltage taken from "x" into the MCP3208. Now you should read the voltage.
    The measured 12-bit-value should correspond to the voltage if you measure it directly with your DMM.

    MCP3208-value * 5000 / 4095 should result in the voltage in millivolts.

    Do this check with a MCP3208-demo-code that is well known to work properly

    best regards
    Stefan
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-20 12:49
    I don't see a bypass cap on the ADC's Vdd pin. I don't know if it's causing a problem but it's generally a good idea to use a 0.1uF cap on each chip's Vdd pin (including the Prop's (all of them)). I've had several circuits not work correctly when forgetting to include a bypass capacitor on one of the chips. Some chips can be very finicky about having bypass caps.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 13:34
    Thanks for the replies everyone.
    SRLM wrote: »
    If you'e powering your MCP3208 at 5v you'll need to protect the IO lines between the Propeller and ADC with a 3.3K+ resistor in line. This would be on the CLK, CS, and DOI lines.

    What is the voltage range that you expect to measure?

    You may also want to try out this code, just to see if you get something different. It's very simple to use:
    http://obex.parallax.com/objects/224/

    Note also that your VREF can't be higher than your VDD... It's not a problem, but it's caught me unawares before.

    Hi, I have placed a 3.9k resistor inline now, the prop seems to be ok when I did the old LED on, LED off test with that pin
    Rayman wrote: »
    I think you only need a resistor on the data line output of MCP320X. Otherwise, it will put 5V directly on a Prop pin, which can damage the Prop...

    3.9k resistor inserted
    Duane Degn wrote: »
    I'll second Rayman's "ouput only" needing the resistor.

    It's not to divide the voltage, it's to protect the IO pins as SRLM said. Though, the CLK, CS, and ADC input pins wont have 5V on them. You only need the resistor on the ADC's output pin since it will be outputting 5V with its logic signal.

    Just tie the ADC's pins 12&13 together with the resistor and connect pin 12 (if that's the ADC's input pin) to the Prop with a wire.

    Did you mean pins 11/12? The data input/output pins?
    StefanL38 wrote: »
    to state the obvius is the pressure-sensors ground connected to the propeller-ground?

    To test new circuits you can do a quick try with the whole thing (as you did) if this does not work
    go back to the most basic system that's possible. In this case the most basic system is a simple voltage-divider formed by two resistors between +5V and ground.

    GND
    Resistor1
    x
    Resistor2
    +5V

    Feed the voltage taken from "x" into the MCP3208. Now you should read the voltage.
    The measured 12-bit-value should correspond to the voltage if you measure it directly with your DMM.

    MCP3208-value * 5000 / 4095 should result in the voltage in millivolts.

    Do this check with a MCP3208-demo-code that is well known to work properly

    best regards
    Stefan

    HI Stefan!

    I did this with 3.3v, but I will do it with a voltage divider circuit as well. And I will report back with a follow up post. Everything has a common ground.
    Duane Degn wrote: »
    I don't see a bypass cap on the ADC's Vdd pin. I don't know if it's causing a problem but it's generally a good idea to use a 0.1uF cap on each chip's Vdd pin (including the Prop's (all of them)). I've had several circuits not work correctly when forgetting to include a bypass capacitor on one of the chips. Some chips can be very finicky about having bypass caps.

    I can add this, but when I spoke to Brandon Nimon, he said this was not necessary if you did not think your analog voltage would ever eclipse your ADC Vdd voltage, so I did not do this at first. I now have a 3.9k resistor inline, inbetween pins 11/12 (which are tied together) and the propellers input pin.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 13:43
    Stefan,

    It showed 4095 with 3.3v and it is showing 2047 with 2.33v, with (2047 * 5000)/4095 = 2499.4, which I believe should be 2.499vDC ... which is close to 2.33? What do you think?


    StefanL38 wrote: »
    to state the obvius is the pressure-sensors ground connected to the propeller-ground?

    To test new circuits you can do a quick try with the whole thing (as you did) if this does not work
    go back to the most basic system that's possible. In this case the most basic system is a simple voltage-divider formed by two resistors between +5V and ground.

    GND
    Resistor1
    x
    Resistor2
    +5V

    Feed the voltage taken from "x" into the MCP3208. Now you should read the voltage.
    The measured 12-bit-value should correspond to the voltage if you measure it directly with your DMM.

    MCP3208-value * 5000 / 4095 should result in the voltage in millivolts.

    Do this check with a MCP3208-demo-code that is well known to work properly

    best regards
    Stefan
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 14:02
    Here is what it reads in the terminal when I send it 3.04v. The voltage from this resistor divider is rock solid when I'm not connected to the prop, but it fluctuates a lot when I measure it with the scope while also connected to the props input pin. Is that normal?

    adc2output3.png
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-20 14:07
    turbosupra wrote: »
    Did you mean pins 11/12? The data input/output pins?

    Yes, 11 and 12.
    turbosupra wrote: »
    I can add this, but when I spoke to Brandon Nimon, he said this was not necessary if you did not think your analog voltage would ever eclipse your ADC Vdd voltage,
    The bypass caps don't have anything to do with the voltage you're measuring. When the chip sends it's output is pulls a little more current than normal which can create a problem for the chip (when there's not a cap to keep the voltage constant at the Vdd pin). It's good use them on all ICs and sometimes it will make a difference between the IC working correctly or not.
    turbosupra wrote: »
    I now have a 3.9k resistor inline, inbetween pins 11/12 (which are tied together) and the propellers input pin.

    This will probably work. In general, the resistor would go between the input and output pins with the input pin connected to the Prop with a just a wire.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-20 14:11
    turbosupra wrote: »
    Here is what it reads in the terminal when I send it 3.04v. The voltage from this resistor divider is rock solid when I'm not connected to the prop, but it fluctuates a lot when I measure it with the scope while also connected to the props input pin. Is that normal?

    Try adding a 0.1uf cap on the ADC Vdd pin. You might want a larger cap there too (1uf or 10uf).

    Edit: One lead goes to Vdd of the ADC chip the other lead to ground.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 15:08
    Something is wrong now (not because of the cap, although I did add that where you suggested) but my propscope does not see any value when measuring pin 11/12 of the ADC and my prop itself is now measuring different values for the same resistor divider?

    Another thing is that when I hook up my meter to measure the voltage of the resistor divider, the ADC does from 255 to 127 or something? I'm pretty confused.

    adc2output5.png


    adc2output4.png
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 18:49
    Well pin 14 and 15 on the prop are hosed

    Can anyone tell me what the fool proof way of connecting these two are?

    I now have a 1uF polarized capacitor in between Vdd/Vref and ground.

    Do I need three 3.9k resistors in between ADC pin 10 and the prop, ADC pins 11/12 and the prop and ADC pin 13 and the prop? Or do I need a resistor ladder in between each ADC pin and the prop?
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-20 20:05
    Ok, I have 3.3 zeners and 100ohm resistors inline for everything, so nothing > 3.3v or .033mA is going in either direction.

    I see the following on the scope, can anyone verify this as good data or not? I'd like to verify what is going on here and narrow this down, right now it looks like the prop is doing its thing, but not receiving any data from the 3208 ... agreed?

    CLK
    adc2output7clk.png

    CS
    adc2output8cs.png

    DATAIN
    adc2output9datain.png

    DATAOUT
    adc2output10dataout.png
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-20 20:37
    Here's a schematic from one of the MCP3208 objects.
          Vcc(+2.7V to +5.5V)        Vdd(+2.7V to +5.5V)
          │           MCP3208        │
          │                          │ 
      ┌───┫      ┌────────────────┐  │ 1µF             1µF capacitor is used to keep power clean
      │   ─────┤1 CH0    Vcc  16├──┻──────── Vss
      │   │      │2 CH1    Vref 15├──────────── Vref(+2.7V to +5.5V)
      │   │      │3 CH2    AGND 14├──────────── Vss
      │   │      │4 CH3    CLK  13├──────────── P1
      ──┼──────┤5 CH4    Dout 12├─────┐          
      │   │      │6 CH5    Din  11├───────┻──── P2    
      │   │      │7 CH6    !cs  10├──────────── P0   
      │   │      │8 CH7    DGND  9├──┳───────── Vss    
      │   │      └────────────────┘  │                1LSB     = Vcc/4096 
      └───╋──────────────────────────┘
          │                                            Pots are 10K and resisters are 3.3K
          Vss                                          if using more than 3.3V.
    

    It originally said resistor values were 1K which I changed to 3.3K which is about as low as one should go with 5V. I personally use 10K resistors with 5V signals because I have a lot of them and they always seem to work fine.
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-20 22:46
    You might want to try a simpler object to start with; the one you're working with has a lot of advanced features that may not be serving you -- once you get things sorted you can come back to it. Being a simple guy, I wrote a KISS driver for the mcp3208; you can find it here:

    -- http://obex.parallax.com/objects/625/
  • Mark_TMark_T Posts: 1,981
    edited 2012-02-21 02:09
    JonnyMac wrote: »
    You might want to try a simpler object to start with; the one you're working with has a lot of advanced features that may not be serving you -- once you get things sorted you can come back to it. Being a simple guy, I wrote a KISS driver for the mcp3208; you can find it here:

    -- http://obex.parallax.com/objects/625/

    I'd second that - some of those 'scope traces suggest you are trying to drive it too fast.

    Also there is no guarantee that you can drive a 5V powered 3208 with 3V3 logic, its just outside the specs (input logic high is 3.5V min in the specs). Certainly this will affect the speed you can drive it at even if it does work since the settling time will be higher. You could use 10k pull-ups to 5V on the CLK, MOSI and CS lines to improve the drive voltage.

    In SPI speak MOSI = DI, MISO = DO on the 3208.

    If you can spare another pin and not couple the DI / DO pins via a resistor you might find better behaviour - currently the prop pin can fight the DO pin via the resistor, further dropping the DI high voltage below 3V3 (which is already below spec)...
  • train nuttrain nut Posts: 70
    edited 2012-02-21 07:45
    turbosupra

    Is there a specific reason you are using 5v for the 3208? I have been using two 3208's on 3.3v for some time now with wonderful results. I am also using a 1k resistor between datain and dataout on the 3208. I also use JonnyMac's jm_mcp3208_se_fast.spin object.

    train nut
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-21 09:05
    Ok, thanks for the reply Duane.

    Here is how I will hook it up when I get home tonight, if you concur that this is correct? I'm sorry this schematic is so crude, I believe it is understandable though.

    propand32081.png


    Here is a template if that is wrong
    propand3208template1.png

    Duane Degn wrote: »
    Here's a schematic from one of the MCP3208 objects.
          Vcc(+2.7V to +5.5V)        Vdd(+2.7V to +5.5V)
          │           MCP3208        │
          │                          │ 
      ┌───┫      ┌────────────────┐  │ 1µF             1µF capacitor is used to keep power clean
      │   ─────┤1 CH0    Vcc  16├──┻──────── Vss
      │   │      │2 CH1    Vref 15├──────────── Vref(+2.7V to +5.5V)
      │   │      │3 CH2    AGND 14├──────────── Vss
      │   │      │4 CH3    CLK  13├──────────── P1
      ──┼──────┤5 CH4    Dout 12├─────┐          
      │   │      │6 CH5    Din  11├───────┻──── P2    
      │   │      │7 CH6    !cs  10├──────────── P0   
      │   │      │8 CH7    DGND  9├──┳───────── Vss    
      │   │      └────────────────┘  │                1LSB     = Vcc/4096 
      └───╋──────────────────────────┘
          │                                            Pots are 10K and resisters are 3.3K
          Vss                                          if using more than 3.3V.
    

    It originally said resistor values were 1K which I changed to 3.3K which is about as low as one should go with 5V. I personally use 10K resistors with 5V signals because I have a lot of them and they always seem to work fine.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-21 09:12
    JonnyMac wrote: »
    You might want to try a simpler object to start with; the one you're working with has a lot of advanced features that may not be serving you -- once you get things sorted you can come back to it. Being a simple guy, I wrote a KISS driver for the mcp3208; you can find it here:

    -- http://obex.parallax.com/objects/625/

    I love KISS stuff and your other driver worked great, so I can't wait to try this when I get home. Thank you.
    Mark_T wrote: »
    I'd second that - some of those 'scope traces suggest you are trying to drive it too fast.

    Also there is no guarantee that you can drive a 5V powered 3208 with 3V3 logic, its just outside the specs (input logic high is 3.5V min in the specs). Certainly this will affect the speed you can drive it at even if it does work since the settling time will be higher. You could use 10k pull-ups to 5V on the CLK, MOSI and CS lines to improve the drive voltage.

    In SPI speak MOSI = DI, MISO = DO on the 3208.

    If you can spare another pin and not couple the DI / DO pins via a resistor you might find better behaviour - currently the prop pin can fight the DO pin via the resistor, further dropping the DI high voltage below 3V3 (which is already below spec)...

    Hi,

    I have a 0-5vDC analog sensor, which is why I'm driving it with 5v as opposed to 3.3v. Are you saying I cannot use that analog sensor realistically, or that the prop would have no problem sinking the 1/2 mA if I used the pull up resistors and pulled the 3.3v to 5v? Also, do I need to worry about DI, to the 3208?
    train nut wrote: »
    turbosupra

    Is there a specific reason you are using 5v for the 3208? I have been using two 3208's on 3.3v for some time now with wonderful results. I am also using a 1k resistor between datain and dataout on the 3208. I also use JonnyMac's jm_mcp3208_se_fast.spin object.

    train nut

    Hi,

    I am using 5v because my analog in, is 0-5v and I'd like to have the entire voltage range for measuring with (it is a pressure sensor).

    I will try JonnyMacs program and hopefully have success tonight.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-21 12:08
    You only need the one resistor on the Dout pin on the ADC (as shown in the schematic I posted).

    As JonnyMac suggests, the other resistors could interfere with the ADC chip seeing the 3.3V logic.

    The Dout pin on the ADC is the only one that will be connected to the Prop that will have 5V on it.

    I've personally use MCP3208 at 5V many times with a Prop. I use a 10K ohm resistor on the Dout pin.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-21 12:35
    Duane,

    Thanks for the reply, I know this is granular, but just to confirm I have changed my rough schematic to reflect what I think you are saying for confirmation. There has been mention of using a resistor at the analog input channel for the 3208, I take it that is not necessary? I will not try the pull up resistors at this point, since you are using this IC in conjunction with the prop, without them.

    The i/o pin is a bit confusing though, why am I able to use the same pin on the prop to connect to the datain/dataout pin on the 3208? Does the propeller object make this duplex, so that it receives on that pin at the correct time and transmits on that pin during non receiving times? What data do I need to send to the 3208 from the prop?

    propand32082.png

    Duane Degn wrote: »
    You only need the one resistor on the Dout pin on the ADC (as shown in the schematic I posted).

    As JonnyMac suggests, the other resistors could interfere with the ADC chip seeing the 3.3V logic.

    The Dout pin on the ADC is the only one that will be connected to the Prop that will have 5V on it.

    I've personally use MCP3208 at 5V many times with a Prop. I use a 10K ohm resistor on the Dout pin.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-02-21 15:06
    turbosupra wrote: »
    There has been mention of using a resistor at the analog input channel for the 3208, I take it that is not necessary?

    I'd think a resistor on the analog input would cause trouble.
    turbosupra wrote: »
    The i/o pin is a bit confusing though, why am I able to use the same pin on the prop to connect to the datain/dataout pin on the 3208? Does the propeller object make this duplex, so that it receives on that pin at the correct time and transmits on that pin during non receiving times? What data do I need to send to the 3208 from the prop?

    Yes, the object takes care of switching between sending and receiving data. The Prop needs to tell the ADC what channels to read. There is at least one 3208 object that uses separate input and output lines which is desirable if you have multiple SPI devices since they can then share the input and output lines among the different devices and just use the CS line to indicate which device is to be active. I'm pretty sure the C3 has its ADC chip using separate input and output lines.

    I think your schematic looks fine now.
  • Mark_TMark_T Posts: 1,981
    edited 2012-02-21 15:51
    turbosupra wrote: »

    I have a 0-5vDC analog sensor, which is why I'm driving it with 5v as opposed to 3.3v. Are you saying I cannot use that analog sensor realistically, or that the prop would have no problem sinking the 1/2 mA if I used the pull up resistors and pulled the 3.3v to 5v? Also, do I need to worry about DI, to the 3208?

    The datasheet for the 3208 and 3204 says that for input the guaranteed logic HIGH is 0.7Vdd or greater, logic LOW is 0.3Vdd or lower. For 5V supply thats 3.5V and 1.5V as the critical values. Those are the worst case figures, so in practice most devices will be much more like 0.5Vdd as the threshold, and things will likely work, but the manufacturer is not guaranteeing it...

    I'd suggest that in practice this could mean that input responses to rising edges will be slower than you might expect as the signal will take a while to get up to 3V3 and the ADC might be wanting close to that voltage to respond. Or if you are unlucky it might fail (usually devices fare quite a lot better than worst case, especially at normal temperatures and when new - temperature and aging affect various parameters and the worst case values are taking this into account)

    My idea for weak pull-ups is to help raise the 3V3 a bit and improve matters - it could help if things are borderline, but on reflection I don't think it will make very much difference.

    Mainly I'm just giving a heads-up that the voltage difference is taking things just a bit outside the "safe" limits, which might cause unreliable behaviour, possibly affecting your circuit (or possibly not).
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-21 18:25
    You are the man Jon! Thanks a lot. It was literally working within 5 minutes of tinkering, between getting the resistor in place and loading your objects. :)

    Wow, this could have saved me many hours yesterday!

    It reads

    atmosphere (.20v) = 170
    1v = 820
    2v = 1638




    JonnyMac wrote: »
    You might want to try a simpler object to start with; the one you're working with has a lot of advanced features that may not be serving you -- once you get things sorted you can come back to it. Being a simple guy, I wrote a KISS driver for the mcp3208; you can find it here:

    -- http://obex.parallax.com/objects/625/
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-21 18:28
    Thanks for the replies Duane and Mark, those are good points.

    Mark, maybe I am seeing a certain behavior because of your points?

    When the ADC is reading analog voltage, say .2v, it displays the proper binary value of ~170, but when I have the ADC not powered it is displaying ~319. I checked just the dataout pin (they were not tied together for the scope check) on the ADC and there is some noise, even with the pull down resistor, any suggestions? Here is a screen capture of the noise scope finds once every second or two, it's quick and then goes to flatline again for another second or two.

    adc2output11dataout.png


    Duane Degn wrote: »
    I'd think a resistor on the analog input would cause trouble.


    Yes, the object takes care of switching between sending and receiving data. The Prop needs to tell the ADC what channels to read. There is at least one 3208 object that uses separate input and output lines which is desirable if you have multiple SPI devices since they can then share the input and output lines among the different devices and just use the CS line to indicate which device is to be active. I'm pretty sure the C3 has its ADC chip using separate input and output lines.

    I think your schematic looks fine now.
    Mark_T wrote: »
    The datasheet for the 3208 and 3204 says that for input the guaranteed logic HIGH is 0.7Vdd or greater, logic LOW is 0.3Vdd or lower. For 5V supply thats 3.5V and 1.5V as the critical values. Those are the worst case figures, so in practice most devices will be much more like 0.5Vdd as the threshold, and things will likely work, but the manufacturer is not guaranteeing it...

    I'd suggest that in practice this could mean that input responses to rising edges will be slower than you might expect as the signal will take a while to get up to 3V3 and the ADC might be wanting close to that voltage to respond. Or if you are unlucky it might fail (usually devices fare quite a lot better than worst case, especially at normal temperatures and when new - temperature and aging affect various parameters and the worst case values are taking this into account)

    My idea for weak pull-ups is to help raise the 3V3 a bit and improve matters - it could help if things are borderline, but on reflection I don't think it will make very much difference.

    Mainly I'm just giving a heads-up that the voltage difference is taking things just a bit outside the "safe" limits, which might cause unreliable behaviour, possibly affecting your circuit (or possibly not).
  • turbosupraturbosupra Posts: 1,088
    edited 2012-02-21 20:10
    Also, did you all code for a lookup table?

    With my 100psi analog pressure sensor ...

    40.95 = 1psi
    81.90 = 2psi
    and so on

    or do you do [binary value as a number] * 0.001221 to get a psi value and truncate after the tenth of a decimal point if that is what you wanted?

    To me the math seems easier, but there might be a reason not to do it that way, which is why I ask.
  • TubularTubular Posts: 4,706
    edited 2012-02-21 20:15
    Good that you got it working. Is that scope waveform of the analog input?

    When the ADC takes a sample, it has an internal capacitor (part of the sample and hold circuit) that needs to charge quickly. For that reason ADCs like to be driven from a low impedance source, and its not clear whether your pressure sensor is low impedance or not (have a link? does its datasheet specify a source impedance?) If the pressure doesn't change suddenly you could put a capacitor to ground on the analog input, so the ADC gets a more steady voltage into its internal sampling capacitor, and see if that reduces the noise.
  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-02-21 20:27
    You are the man Jon! Thanks a lot.

    I _am_ the man. ;) And you're welcome.
    Also, did you all code for a lookup table?

    Do you know how many volts the sensor puts out per psi? Knowing the range of the ADC it might be simple math.
Sign In or Register to comment.