TLC2543 scaling
Falcon
Posts: 191
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.
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
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
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
Declare the variables as Words, not Bytes. There are ways around that if you do want to stick with bytes and less resolution.
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
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.
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.
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.
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
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: 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.
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