Shop OBEX P1 Docs P2 Docs Learn Events
I am code blind - MCP3208 continous reading into global LONGs - no longer works — Parallax Forums

I am code blind - MCP3208 continous reading into global LONGs - no longer works

ErlendErlend Posts: 612
edited 2014-10-26 16:02 in Propeller 1
I am re-building my project to move from birds nest style to a more robust build. The rebuildt ADC board works fine when I test it with MCP3208_DEMO, but when I run the code that continously reads all channels (jm_mcp3208_auto) and put the values into a set of 8 consecutive LONGS that I have passed the pointer of, the values passed are 0 - 4095 - 0 - 4095 - 0 - 4095 - 0 - 4095, no matter what the adc inputs are. The drives-me-crazy factor is that I finished debugging this a year ago, and it worked perfect. I have stripped my code of everything not to do with the adc values, and this looks like this:
CON
        _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
        _xinfreq = 5_000_000

        'pin assignments:
        
  
        PinADCdata    = 7      'DAT   pin 11&12
        PinADCclk     = 8      'CLK   pin 13
        PinADCcs      = 9      'CS    pin 10
        
        'parameters
        LCD_BAUD               = 19_200


VAR
        
        'Variables to hold I/O values
        '============================
        
        'ADC analogue input values - obeying the requirement for declaring 8 consecutive LONGs       
        LONG gAnLevelWater           
        LONG gAnTempWater            
        LONG gAnPressWater           
        LONG gAnPanic       
        LONG gAnWeightCup            
        LONG gAnVoltageSupply                                              
        LONG gAnUVflame               
        LONG gAnAmperage


   
OBJ
 lcd     : "Parallax Serial Terminal"
 adc     : "ADCreader"
  
  
PUB Main

'Startup procedures
'==================
  lcd.start(LCD_BAUD)        'not lcd, but pst here
   
  'start ad converter reader
  adc.startx(PinADCcs, PinADCclk, pinADCdata, 8, @gAnLevelWater)        'gAnLevelWater is the first in the block of 8 LONGs

  waitcnt(clkfreq + cnt)

'Testing:

  lcd.str(STRING("ADC reading starts:", 13))
  waitcnt(clkfreq + cnt)


Repeat
  lcd.dec(adc.read(0))                'just to check if reading a channel direct works better  
  lcd.str(STRING(" read direct", 13))
  
                               
  lcd.dec(gAnLevelWater)   
  lcd.str(STRING(" ADC", 13))                     
   
  lcd.dec(gAnTempWater)
  lcd.str(STRING(" degC,", 13))

  lcd.dec(gAnPressWater)
  lcd.str(STRING(" Bar,", 13))
                                                                                                                                   
  lcd.dec(gAnPanic)                             
  lcd.str(STRING(" mSec,", 13))                                                                                                 
                                                                                                                                     
  lcd.dec(gAnWeightCup)
  lcd.str(STRING(" gram,", 13))

  lcd.dec(gAnVoltageSupply)
  lcd.str(STRING(" Volt,", 13))
  
  lcd.dec(gAnUVflame)
  lcd.str(STRING(" UV%,", 13))

  lcd.dec(gAnAmperage)
  lcd.str(STRING(" mA,", 13))

 
  waitcnt(clkfreq + cnt) 
  lcd.clear 
               
 
DAT

-and JonnyMac's (very nice) code looks like this:
CON
        _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
        _xinfreq = 5_000_000
'' =================================================================================================
''
''   File....... jm_mcp3208_auto.spin
''   Purpose.... S/E auto/continuous reader for MCP3208/MCP3204 ADCs
''   Author..... Jon "JonnyMac" McPhalen
''               Copyright (c) 2010-2013 Jon McPhalen
''               -- see below for terms of use
''   E-mail..... jon@jonmcphalen.com
''   Started.... 03 JUL 2010
''   Updated.... 19 JAN 2013
''
'' =================================================================================================

{{

    Auto-reader for MCP3208 (use .start or .startx) and MCP3204 (use .startx method) ADCs.

                               3v3-5v0
                   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├──┫
             └─────────────────┘  │
                                  

                               3v3-5v0
                   MCP3204        
             ┌─────────────────┐  │
    ch0 ────┤1  CH0     VDD 14├──┫                
    ch1 ────┤2  CH1    VREF 13├──┘           
    ch2 ────┤3  CH2    AGND 12├──┐ 
    ch3 ────┤4  CH3     CLK 11├──│──────── clk
            ─┤5  NC     DOUT 10├──│──┐ 3k3
            ─┤6  NC      DIN  9├──│────┻── dio   
          ┌──┤7  DGND    /CS  8├──│──────── cs
          │  └─────────────────┘  │
                                     
                              
}} 


var

  long  cog                                                     ' cog running reader

  long  cs                                                      ' pins used
  long  clk
  long  dio
  long  channels
  long  p_adcvals                                               ' pointer to adc readings
 
  long  adc[8]                                                  ' adc readings
  long  stack[32]                                               ' memory for reader cog
  

pub start(cspin, clkpin, diopin)

'' Start free-running MCP3204/8 reader
'' -- store readings in object var space
'' -- assumes 8-channel MCP3208

  return startx(cspin, clkpin, diopin, 8, -1)


pub startx(cspin, clkpin, diopin, nchans, p_analog)

'' Start free-running MCP3204/8 reader
'' -- store readings at user-specified location (parent var space)
'' -- nchans is number of channels, 1..8
'' -- p_analog is a pointer to a block of eight longs
''    * use -1 for local storage
      
  stop                                                          ' kill if already running

  longmove(@cs, @cspin, 3)                                      ' copy pins

  channels := 1 #> nchans <# 8                                  ' keep channel count legal
  
  if (p_analog < 0)
    p_adcvals := @adc                                           ' use internal array
  else
    p_adcvals := p_analog                                       ' use specified array

  cog := cognew(mcp3208, @stack) + 1                            ' start reader cog

  return cog

  
pub stop

'' Unload MCP3204/8 reader cog

  if (cog)                                                      ' if running
    cogstop(cog - 1)                                            '  stop 
    cog := 0
    longfill(p_adcvals, 0, channels)   

  
pub read(ch)

'' Get last read channel value

  if ((ch => 0) and (ch < channels))                            ' valid?
    return long[p_adcvals][ch]                                  ' return channel value
  else
    return 0


pub address

'' Returns address of adc results storage

   return p_adcvals
   

pri mcp3208 | ch, mux, level                                    ' call with cognew()

  outa[cs] := 1                                                 ' output high
  dira[cs] := 1

  outa[clk] := 0                                                ' output low
  dira[clk] := 1

  repeat
    repeat ch from 0 to (channels-1)                            ' loop through channels
      outa[cs] := 0                                             ' activate adc  

      ' output mux bits, MSBFIRST

      dira[dio] := 1                                            ' dio is output
      mux := (%11000 + ch) << (32-5)                            ' single-ended mode
      repeat 5                                                  ' send mux bits
        outa[dio] := (mux <-= 1) & 1                            ' output a bit
        outa[clk] := 1                                          ' clock the bit
        outa[clk] := 0      
          
      ' input data bits, MSBPOST
       
      dira[dio] := 0                                            ' dio is input
      level := 0                                                ' clear work var  
      repeat 13                                                 ' null + 12 data bits
        outa[clk] := 1                                          ' clock a bit
        outa[clk] := 0                                           
        level := (level << 1) | ina[dio]                        ' input data bit
                                                                 
      outa[cs] := 1                                             ' de-activate adc
                                                                 
      long[p_adcvals][ch] := level & $FFF                       ' update results array      


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. 

}}  

thanks for any guidance,
Erlend

Comments

  • ErNaErNa Posts: 1,752
    edited 2014-10-26 07:13
    If I had to dbg this, I would first return known values like" long[p_adcvals][ch] := ch " Now you should have different results
  • ErlendErlend Posts: 612
    edited 2014-10-26 07:38
    Thanks ErNa,
    doing that mod in the code results in this output:
    0 read direct
    0 ADC
    1 degC,
    2 Bar,
    3 mSec,
    4 gram,
    5 Volt,
    6 UV%,
    7 mA,
    Which proves that writing back to the global vars works fine. Now that's sorted: my code is not faulty, and JonnyMac's code simply is not wrong, so. ...waitaminute...(.....connecting scope, checking signals, compare with when running code that works, eureka...).... I go over the pin assignments and wiring one more time: it appears I have swapped CLK and CS. I was fooled by that the communication seemed to work, as well as when something doesn't work I instinctively blame my own code.

    Thanks for the guidance : )
    Erlend

    Erlend
  • mynet43mynet43 Posts: 644
    edited 2014-10-26 16:02
    Check the MCP3208. I've had similar results when the chip goes bad.

    Jim
Sign In or Register to comment.