Shop OBEX P1 Docs P2 Docs Learn Events
TLC2543 scaling — Parallax Forums

TLC2543 scaling

FalconFalcon Posts: 191
edited 2012-01-09 18:37 in BASIC Stamp
I've recently switched from an ADC0834 to the TLC2543 because I needed to measure more than 4 LM34 temp sensors. I had the 0834 working fine.

I based my TLC2543 code (attached) on the example that everyone seems to use from Tracy Allen's web page. I wanted individual byte variables so I could then send them via Serial interface to a second BS2 so I expanded the code. Memory is not a problem in this application.
' {$STAMP BS2}
' {$PBASIC 2.5}

sclk PIN  15              'sclk PIN 15 ' clock out from BS2 to AD2543
sdo PIN 14                ' data out from BS2 to AD2543 sdi
sdi PIN 13                ' data in from AD2543 sdo to BS2
A2dChipSel PIN 12               ' AD2543 chip select, active low

ADch0 VAR Nib
ADch1 VAR Nib
ADch2 VAR Nib
ADch3 VAR Nib
ADch4 VAR Nib
ADch5 VAR Nib
ADch6 VAR Nib
ADch7 VAR Nib
ADch8 VAR Nib
ADch9 VAR Nib

a2dresult0 VAR Byte
a2dresult1 VAR Byte
a2dresult2 VAR Byte
a2dresult3 VAR Byte
a2dresult4 VAR Byte
a2dresult5 VAR Byte
a2dresult6 VAR Byte
a2dresult7 VAR Byte
a2dresult8 VAR Byte
a2dresult9 VAR Byte
demo:                     ' to show off the subroutine below.
DIRS=$FFFF                ' makes all Stamp pins outputs to start
OUTS=$1000                ' makes all pins except ADC chip select low to start

main:

 LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch0<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult0\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
 a2dresult0 = 14464 ** a2dresult0 + a2dresult0 ' convert count to millivolts.



 LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch1<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult1\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
 a2dresult1 = 14464 ** a2dresult1 + a2dresult1 ' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch2<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult2\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
 a2dresult2 = 14464 ** a2dresult2 + a2dresult2 ' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch3<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult3\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
 a2dresult3 = 14464 ** a2dresult3 + a2dresult3 ' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch4<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult4\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
  a2dresult4 = 14464 ** a2dresult4 + a2dresult4 ' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch5<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult5\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
  a2dresult5 = 14464 ** a2dresult5 + a2dresult5 ' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch6<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult6\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
  a2dresult6 = 14464 ** a2dresult6 + a2dresult6 ' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch7<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult7\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
  a2dresult7 = 14464 ** a2dresult7 + a2dresult7' convert count to millivolts.


  LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch8<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult8\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
  a2dresult8 = 14464 ** a2dresult8 + a2dresult8 ' convert count to millivolts.


   LOW A2dChipSel                 ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch9<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[a2dresult9\12] ' get result, 12 bits
 HIGH A2dChipSel ' deselect chip
  a2dresult9 = 14464 ** a2dresult9 + a2dresult9 ' convert count to millivolts.



 DEBUG  DEC a2dresult0, REP 32\5, " ",
 DEC a2dresult1, REP 32\5, " ",
 DEC a2dresult2, REP 32\5, " ",
 DEC a2dresult3, REP 32\5, " ",
 DEC a2dresult4, REP 32\5, " ",
 DEC a2dresult5, REP 32\5, " ",
 DEC a2dresult6, REP 32\5, " ",
 DEC a2dresult7, REP 32\5, " ",
 DEC a2dresult8, REP 32\5, " ",
 DEC a2dresult9, REP 32\5, " ", CR


 GOTO main

However, as written, the results from each of the channels is in the decimal 123-126 range.

I'm using 5.0 V as REF+. The accompanying article explaining the TLC2543 indicates, if I read it right, that "If the reference is 5.000 volts, it will read 4096 increments of 1.2207 millivolts per bit", and to use the following to scale the result:

"result = 14464 ** result + result ' convert count to millivolts.

To be honest, the result from Dr. Allen's code (attached below) returns a result that is 10 times the actual temp reading. My office is ~75F and the results are "751". I can deal with that with a simple /10 command if I could just get that result. I just don't see a difference between that and mine that would cause the difference. BTW, I'm using the same scaling factor
' {$STAMP BS2}
' {$PBASIC 2.5}

' ADread subroutine.
' On command, returns 12 bit digital data from one of 11 analog channels.
' The value of ADch from 0 to 10 selects external analog inputs.
' ADch=14 puts the converter into its sleep mode.
' converter has 5 volt reference, connection to the Vdd power supply, for 1.2207 mV per bit
sclk PIN  15
'sclk PIN 15 ' clock out from BS2 to AD2543
sdo PIN 14 ' data out from BS2 to AD2543 sdi
sdi PIN 13 ' data in from AD2543 sdo to BS2
ADcs PIN 12 ' AD2543 chip select, active low

ADch VAR Nib ' selects AD external channel 0-10
result VAR Word ' result, 12 bit A/D conversion

demo: ' to show off the subroutine below.
DIRS=$FFFF ' makes all Stamp pins outputs to start
OUTS=$1000 ' makes all pins except ADC chip select low to start


DO


  FOR ADch =0 TO 10 ' specify one of 11 input channels
  GOSUB ADread ' get millivolt data from that channel
  result = 14464 ** result + result ' convert count to millivolts.
  DEBUG DEC ADch,": ",DEC result,REP 32\5,CR ' display, use extra spaces to clear garbage


 NEXT

LOOP

ADread: ' entry point to give result as count from 0 to 4095
 LOW ADcs ' select chip
 SHIFTOUT sdo,sclk,MSBFIRST,[ADch<<8\12] ' mode, left justify ADch
 SHIFTIN sdi,sclk,MSBPRE,[result\12] ' get result, 12 bits
 HIGH ADcs ' deselect chip
RETURN

Does anyone have any advice? I've been reading every post I could find on the TLC2543 for the last 3 hours but every one refers to the same source code.

Thanks,

falcon

Comments

  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-01-08 19:42
    Hi falcon,

    Declare the variables as Words, not Bytes. There are ways around that if you do want to stick with bytes and less resolution.
  • FalconFalcon Posts: 191
    edited 2012-01-09 10:48
    Tracy,

    Thank you for the reply.

    I will make that change to WORD variables when I get home and give that a go.

    I chose the TLC2543 because to the 10 channels. I'm only measuring temps from 20 to 110 F so a much smaller resolution would be fine. It would be a bonus if it would save me tying up 10 WORD-sized variables. How can that be done?

    falcon
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-01-09 12:39
    Just read in the data into a word variable, but divide by 10 to store it in a byte.

    In your original program, all of the channel numbers were declared as variables, Nibs.
    I see no reason for doing that. One subroutine should be able to handle all of the channels.

    DO
       FOR ADch =0 TO 9 ' specify one of 10 input channels
         LOW ADcs ' select chip
           SHIFTOUT sdo,sclk,MSBFIRST,[ADch<<8\12] ' mode, left justify ADch
           SHIFTIN sdi,sclk,MSBPRE,[result\12] ' get result, 12 bits
         HIGH ADcs ' deselect chip
         a2dresult0(ADch) = (14464 ** result + result+5)/10 ' round off to Fahrenheit.
         DEBUG DEC ADch,": ",DEC a2dresult0(ADch),REP 32\5,CR ' display
       NEXT
      PAUSE 1000
    LOOP
    

    Note that a2dresult0(ADch) is what is called an implied array. It addresses a2dresult1 as the second element of the implied array, and so on.



  • FalconFalcon Posts: 191
    edited 2012-01-09 16:46
    Tracy,
    I see a mix of variables "result" and A2Dresult" in that last code snippet you attached. Can you confirm you are using "result" to extract the data from the TLC2543, and "A2Dresult" when each channel's data is saved to a variable?
    I have the following code displaying 2-digit readings for each channel.
    
    
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    sclk       PIN 15                'sclk PIN 15 ' clock out from BS2 to AD2543
    sdo        PIN 14                ' data out from BS2 to AD2543 sdi
    sdi        PIN 13                ' data in from AD2543 sdo to BS2
    A2dChipSel PIN 12                ' AD2543 chip select, active low
    
    ADch       VAR Nib
    result     VAR Word
    A2Dresult0 VAR Word(10)
    demo:                            ' to show off the subroutine below.
    DIRS=$FFFF                       ' makes all Stamp pins outputs to start
    OUTS=$1000                       ' makes all pins except ADC chip select low to start
    
    DO
       FOR ADch =0 TO 9 ' specify one of 10 input channels
         LOW A2dChipSel ' select chip
           SHIFTOUT sdo,sclk,MSBFIRST,[ADch<<8\12] ' mode, left justify ADch
           SHIFTIN sdi,sclk,MSBPRE,[result\12] ' get result, 12 bits
         HIGH A2dChipSel ' deselect chip
         a2dresult0(ADch) = (14464 ** result + result+5)/10 ' round off to Fahrenheit.
         DEBUG DEC ADch,": ",DEC a2dresult0(ADch),REP 32\5,CR ' display
       NEXT
    
    PAUSE 1000
    DEBUG CLS
    DEBUG CRSRXY,0,12,"Temp Channel 1: ", DEC A2Dresult0,REP 32\5          'Displays correct
    DEBUG CRSRXY,0,13,"Temp Channel 2: ", DEC A2Dresult1,REP 32\5          'causes an error on RUN
    
    DEBUG HOME
    LOOP
    

    Shouldn't that DEC A2Dresult1 code display just the channel 2 variable according to your last post "Note that a2dresult0(ADch) is what is called an implied array. It addresses a2dresult1 as the second element of the implied array, and so on."


    How do I lower the resolution so I don't use 10 WORD variables? A temp reading to the .5 degree would be adequate.

    What does that REP 32\5 code mean. I could not find that in the BASIC Stamp Syntax and Reference Manual


    falcon
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-01-09 17:44
    result is a word variable, but the a2dresult array elements can be bytes.
    a2dresult VAR Byte(10) ' with index 0 to 9

    With that explicit array syntax, you will always have to refer to the variable by its position in the array, for example, a2dresult(3) will be the 4th byte in the array. You do not have a separate variable called a2dresult3. There is another (undocumented) way to make arrays, called implicit arrays, where you can have the best of both worlds.

    Temperature values are reduced to lower resolution by the one line of math that works on the word-sized result variable. I had it in my previous post dividing by 10 to give resolution in units of 1°F. You can get 0.5°F with this math:
    [COLOR=#ff0000]a2dresult(ADch) = (14464 ** result + result+5)/5 ' round off to Fahrenheit*2. 
    DEBUG DEC ADch,": ",DEC a2dresult(ADch)/2,".",DEC1 a2dresult(ADch)*5,REP 32\5,CR ' display [/COLOR]
    
    You see the division by 5, instead of 10, which makes a byte such as 221 represent the temperature 110.5 °F, and the display code parses out the byte to display it as such.

    You can find the REP under the description of "modifiers" of the SEROUT command.
  • FalconFalcon Posts: 191
    edited 2012-01-09 18:37
    Got it. Works like a champ.

    Thanks a million Tracy. I'll work through that code line by line and try to get to a better level of understanding.

    I appreciate the patience.

    falcon
Sign In or Register to comment.