Shop OBEX P1 Docs P2 Docs Learn Events
Looking for help with an ADC interface — Parallax Forums

Looking for help with an ADC interface

turbosupraturbosupra Posts: 1,088
edited 2014-09-11 11:49 in Propeller 1
It's been about a year since I wrote prop code and apparently I've forgotten how to.

I'm trying to interface the mcp3204 with my prop and with the code below. I've double checked my wiring, there is 2.9v going into channel 1 of the 3204 and my prop scope nothing coming out of the data out and data in pins, which are tied together, then pass through a 3.9k resistor to pin5 on the prop. Prop pin 6 is wired to the CS pin on the 3204 and prop pin 7 is wired to the clock pin on the 3204.

Any ideas as to what I'm doing wrong? I do not see any clock signal coming from the prop to the 3204, can the object I am using be used with the 3204?

Thanks

{                             





}

CON

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




  Vclk_p        = 7     ' clock pin
  Vn_p          = 5     ' data in
  Vo_p          = 5     ' data out
  Vcs_p         = 6     ' 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, 115200)
  waitcnt(clkfreq + cnt)  
  DEBUG.tx($D)   

 { dira[11] := 1
  outa[11] := 1
  dira[12] := 1
  outa[12] := 1
  dira[13] := 1
  outa[13] := 1
  dira[14] := 1
  outa[14] := 1
  dira[15] := 1
  outa[15] := 1 }
  
  ADC.start(Vo_p, Vn_p, Vclk_p, Vcs_p, 4, 1, 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 (DTPin, INPin, ClkPin, RSPin,  ChCount, ActChannels, BitCount, SingDiff, FastMode)  

  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 Standard Example 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 Standard Example 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++
      

Comments

  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-09-11 11:11
    It's been about a year since I wrote prop code and apparently I've forgotten how to.

    Which is why I recommend spending at least a few minutes a day looking over your projects -- better than trying to cram.

    can the object I am using be used with the 3204?

    The MCP3204 and MCP3208 use the same protocol structure, the mux input for the '3204 is limited to four channels.


    I've attached my MCP3204 driver (with demo); you may find it easier to use. If this works for you and you want to do something like averaging analog inputs without upsetting the timing of your foreground code, you can always create a cog that handles the MCP3204, does the averaging, then writes to the hub. I did that for a friend's project (that uses the MCP3208) like this:
    con
    
      { --------------------- }
      {  B A C K G R O U N D  }
      { --------------------- }
    
      
    var
    
      long  adccog
      long  adcstack[32]
      
      long  pot[8]                                                  ' averaged pots
    
      long  accidx
      long  acc[32]                                                 ' 4 readings for 8 pots
      
    
    pri start_adc
    
      if (adccog)                                                   ' stop if already running
        cogstop(adccog-1)
    
      adccog := cognew(scan_pots, @adcstack) + 1 
      
    
    pri scan_pots | t, ofs, ch, sum
    
    '' Scans and averages adc inputs
    '' -- averages adc inputs over four readings
    
      adc.start(ADC_CS, ADC_CLK, ADC_DIO)                           ' mcp3208 (Spin)  
    
      t := cnt
      repeat
        ofs := accidx << 3                                          ' offset into accumulator array
        repeat ch from 0 to 7                                       
          acc[ch + ofs] := adc.read(ch, adc#SE)                     ' read channels
          
          sum := acc[ch]                                            ' rolling average
          sum += acc[ch + 08]
          sum += acc[ch + 16]
          sum += acc[ch + 24]  
          pot[ch] := sum >> 2
          
        if (++accidx == 4)
          accidx := 0
    
        waitcnt(t += (8 * MS_001))
    
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-11 11:39
    Hi Jon,

    That worked great and I was able to get it working in literally 90 seconds. Thank you for the object and for designing it so easy to read/understand. I don't get out to California hardly ever, but if I am ever in the Burbank area I will be offering to buy you quite a few beers.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-09-11 11:49
    Glad you got it working. The Irish blood in my veins especially enjoys Guinness draught. :)
Sign In or Register to comment.