Shop OBEX P1 Docs P2 Docs Learn Events
Need Debug Help — Parallax Forums

Need Debug Help

Kirk FraserKirk Fraser Posts: 364
edited 2014-10-23 06:51 in Propeller 1
I'm trying to get a fairly simple Spin program to work. The current goal is to read upto 6 pots from a MCP3208 and display the value 0-4095. The problem is the values always stay at either 0 or 4095, nothing in between when I rotate a pot and no change when I remove the pot from the MCP3208 input.
obj
'  pwmA     : "jm_lfpwm_8x"                                      ' A pwm output
'  pwmB     : "jm_lfpwm_8x"                                      ' B pwm output
  adc      : "jm_mcp3208_se_fast"                               ' Pot multiplex input
  dbug     : "FullDuplexSerial"                                 ' pc serial IO
var
  long  pot[8]
  long  pot1 
  long  pot2 
  long  pot3
  long  pot4
  long  pot5 
  long  pot6    
  byte  dir                                                     ' adc channels
con
  _clkmode = xtal1 + pll16x
'  _xinfreq = 6_000_000                                         ' use 6MHz crystal  
  _xinfreq = 6_250_000                                          ' use 6.25MHz crystal
  CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
  clk = 20
  cs  = 21
  dio = 22                    'adc SPI buss  
  ca  = 15                    'coil 8a
  cb  = 14
  ch  = 8                     'channel for pot in
  cls = 14
PUB main
{{Start objects}}
  adc.start(cs, clk, dio, @pot[0])                              ' start ADC driver
  pwma.start(1, ca, 100)                                       ' start PWM drivers
  pwmb.start(1, cb, 100)  
' dbug.start(rxpin, txpin, mode, baudrate) 
  dbug.start(31, 30, 0, 115200)                             ' start debug object 
  waitcnt(clkfreq*3+cnt)                                        ' For Debug Startup
  dbug.tx(cls)

{{Run Loop}}
 repeat
    readPots                                                   ' read adc values   
'    pwma.set(ch-1, pot2 / 4)
'    pwmb.set(ch-1, pot3 / 4)

pub readPots
   dbug.str(string(13))

   pot1 := pot[1 - 1]
   dbug.str(string(" pot1 "))
   dbug.dec(pot1)

   pot2 := pot[2 - 1]
   dbug.str(string(" pot2 ")) 
   dbug.dec(pot2)

   pot3 := pot[3 - 1]
   dbug.str(string(" pot3 ")) 
   dbug.dec(pot3) 

   pot4 := pot[4 - 1]
   dbug.str(string(" pot4 ")) 
   dbug.dec(pot4)   

   pot5 := pot[5 - 1]
   dbug.str(string(" pot5 ")) 
   dbug.dec(pot5)

   pot6 := pot[6 - 1]
   dbug.str(string(" pot6 ")) 
   dbug.dec(pot6)

The object which drives the MCP3208.differs from those found on Obex but I don't suspect it. I think it's possibly my MCP3208 has gone bad or some other hardware problem. But I don't know. I have the chip in a socket so maybe I should buy a new one and swap it? The hardware has been sitting around so it may have gotten a static shock, but the Propeller chip is working. Suggestions? Thank you.

Here's the object which drives the MCP3208. This may be needed to show how it returns the pot values to be read by the main program. Perhaps I have some bug in my variable definition or use or something?
.
'' =================================================================================================
''
''   File....... jm_mcp3208_se_fast.spin
''   Purpose.... for MCP3208 -- single ended mode, runs automously
''   Author..... Jon "JonnyMac" McPhalen 
''               Copyright (c) 2010-2011 Jon McPhalen
''               -- see below for terms of use
''   E-mail..... jon@jonmcphalen.com
''   Started.... 
''   Updated.... 18 SEP 2011
''
'' =================================================================================================


{{ 
                              VDD (2.7 to 5.0)
                MCP3208        
          ┌─────────────────┐  │
 ch0 ────┤1  CH0     VDD 16├──┫                
 ch1 ────┤2  CH1    VREF 15├──┘           
 ch2 ────┤3  CH2    AGND 14├──┐ 
 ch3 ────┤4  CH3     CLK 13├──│──────── clk
 ch4 ────┤5  CH4    DOUT 12├──│──┐ 3k3 
 ch5 ────┤6  CH5     DIN 11├──│────┻── dio
 ch6 ────┤7  CH6     /CS 10├──│──────── cs               
 ch7 ────┤8  CH7    DGND  9├──┫
          └─────────────────┘  │
                               
}}


con

  BIT_US   = 2                                                  ' bit timing ~us
  FRAME_MS = 1                                                  ' frame timing in millseconds
  

var

  long  cog                                                     ' cog used by driver

  long  cspin                                                   ' chip select pin
  long  clkpin                                                  ' clock pin
  long  diopin                                                  ' data i/o pin
  long  pntr                                                    ' hub pntr to results
  long  clktime                                                 ' timing for 1/2 bit (in ticks)                                                 ' 
  long  frametime                                               ' frame timing for hub updates


pub start(cs, clk, dio, dest) : ok

'' Starts MCP3208 measurements, single-ended mode
'' -- cs is chip select pin
'' -- clk is clock pin
'' -- dio is data io pin (di and do connnected with 3.3k resistor)
'' -- dest is hub address for values (8 longs)

  stop

  longmove(@cspin, @cs, 4)                                      ' copy parameters

  clktime   := (clkfreq / 1_000_000 * BIT_US) >> 1              ' half bit timing 
  frametime := clkfreq / 1_000 * FRAME_MS                       ' frame (8 ch) timing

  ok := cog := cognew(@entry, @cspin) + 1                       ' start the cog


pub stop

'' Stops cog (if running)

  if cog
    cogstop(cog~ - 1)
    longfill(pntr, 8, 0)


dat

                        org     0

entry                   mov     tmp1, par                       ' start of structure
                        rdlong  tmp2, tmp1                      ' read CS pin #
                        mov     csmask, #1
                        shl     csmask, tmp2
                        or      outa, csmask                    ' make output/high (disable)
                        or      dira, csmask

                        add     tmp1, #4
                        rdlong  tmp2, tmp1                      ' read CLK pin #
                        mov     clkmask, #1
                        shl     clkmask, tmp2
                        andn    outa, clkmask                   ' make ouput/low
                        or      dira, clkmask

                        add     tmp1, #4
                        rdlong  tmp2, tmp1                      ' read DIO pin #
                        mov     diomask, #1
                        shl     diomask, tmp2

                        add     tmp1, #4
                        rdlong  adcpntr, tmp1                   ' read hub address of output array

                        add     tmp1, #4
                        rdlong  clktix, tmp1                    ' read cnt ticks for half bit

                        add     tmp1, #4
                        rdlong  frametix, tmp1                  ' read cnt ticks per 8-ch frame

                        mov     chan, #0                        ' initialize channel channel

                        mov     frmtimer, cnt
                        add     frmtimer, frametix              ' set frame (8 channels) timing
                       
adcmain                 andn    outa, csmask                    ' activate adc
                        or      dira, diomask                   ' make dio an output

muxout                  mov     muxbits, #%1_1000               ' set for single-ended
                        add     muxbits, chan                   ' add channel
                        mov     count, #5                       ' send 5 bits
                        
:loop                   test    muxbits, #%1_0000       wc      ' move bit4 to C
                        muxc    outa, diomask
                        call    #bitdelay                       ' let dio settle
                        call    #clockbit                       ' clock the bit out  
                        shl     muxbits, #1
                        djnz    count, #:loop                        
                        
adcin                   andn    dira, diomask                   ' make dio an input
                        mov     level, #0                       ' clear workspace
                        mov     count, #13                      ' null + 12 data bits
                        
:loop                   call    #clockbit                       ' clock the bit in
                        call    #bitdelay                       ' let dio settle
                        shl     level, #1                       ' prep for new bit
                        test    diomask, ina            wc      ' get new bit in C
                        muxc    level, #1                       ' move to bit0
                        djnz    count, #:loop
            
                        or      outa, csmask                    ' deselect
                        call    #bitdelay

                        mov     tmp1, adcpntr                   ' point to hub array
                        mov     tmp2, chan                      ' channel index
                        shl     tmp2, #2                        ' adjust for longs
                        add     tmp1, tmp2                      ' point to array[chan] in hub
                        and     level, HX_FFF                   ' cleanup reading
                        wrlong  level, tmp1                     ' write to hub

                        add     chan, #1                        ' next channel
                        and     chan, #%111             wz      ' rolloever if required

        if_z            waitcnt frmtimer, frametix              ' wait for end of frame if done
                        jmp     #adcmain



clockbit                or      outa, clkmask                   ' CLK high
                        call    #bitdelay
                        andn    outa, clkmask                   ' CLK low
clockbit_ret            ret                                 

                        

bitdelay                mov     clktimer, cnt                   ' start timer        
                        add     clktimer, clktix                ' set for 1/2 bit tix        
                        waitcnt clktimer, #0                    ' wait for expiration
bitdelay_ret            ret

' --------------------------------------------------------------------------------------------------

HX_FFF                  long    $0FFF                           ' mask for 12 bits

csmask                  res     1
clkmask                 res     1
diomask                 res     1

clktix                  res     1
frametix                res     1

adcpntr                 res     1
chan                    res     1
muxbits                 res     1
count                   res     1
level                   res     1

frmtimer                res     1
clktimer                res     1

tmp1                    res     1                               ' work vars
tmp2                    res     1

                        fit                                    

                        
dat

{{

  Terms of Use: MIT License

  Permission is hereby granted, free of charge, to any person obtaining a copy of this
  software and associated documentation files (the "Software"), to deal in the Software
  without restriction, including without limitation the rights to use, copy, modify,
  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be included in all copies
  or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

}}  

Comments

  • kwinnkwinn Posts: 8,697
    edited 2014-10-22 20:43
    The attached program is untested but the routines are excerpts from a working program and do compile without errors. It requires the four port serial object and the MCP3208 object from the obex. It should print all 8 channels from the adc to PST once per second.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-10-22 20:56
    The standard Tachyon binary includes the drivers for MCP3208s etc. Just paste in this little definiton:
    pub LSADC 
        &04.02.03.01 !ADC  
         8 0 
           DO CR I .BYTE ." : " I ADC@ DUP .DEC SPACE 5 SHR 1+ FOR "*" EMIT NEXT LOOP 
         ;
    

    and run it like this:
    LSADC
    00: 0000 *
    01: 0000 *
    02: 0000 *
    03: 0000 *
    04: 0000 *
    05: 0000 *
    06: 0000 *
    07: 0000 * ok
  • MJBMJB Posts: 1,235
    edited 2014-10-23 06:51
    Hi Kirk,
    looks like your pins are different
    clk = 20 cs = 21 dio = 22 'adc SPI buss ca = 15 'coil 8a cb = 14 ch = 8 'channel for pot in cls = 14
    The standard Tachyon binary includes the drivers for MCP3208s etc. Just paste in this little definiton:
    pub LSADC 
        &04.02.03.01 !ADC     [SIZE=3][B][COLOR=#0000ff] \ hi Kirk, here you need to set your PINs  as  &ce.miso.mosi.sck [/COLOR][/B][/SIZE]
         8 0 
           DO CR I .BYTE ." : " I ADC@ DUP .DEC SPACE 5 SHR 1+ FOR "*" EMIT NEXT LOOP 
         ;
    

    and run it like this:
    LSADC
    00: 0000 *
    01: 0000 *
    02: 0000 *
    03: 0000 *
    04: 0000 *
    05: 0000 *
    06: 0000 *
    07: 0000 * ok
Sign In or Register to comment.