I am code blind - MCP3208 continous reading into global LONGs - no longer works
Erlend
Posts: 612
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:
-and JonnyMac's (very nice) code looks like this:
thanks for any guidance,
Erlend
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
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
Jim