project idea questions

golfnut

Member
Embarking on ambitious project, to me it is unclear if it can be done with a picaxe.
I want to make a 'pretty-accurate' Temperature probe/device based on the Analog Devices ADT7410. I need to read I2c register data in from it, and do some math conversion and Display temp on 7segment display in C.

I want to keep all of the temp data - so no rounding or truncation errors. I dont want to loose any resolution/accuracy -ie to use all of the typical accuracy of +/-0.1C from the chip.

The data from temp i.c. is in a two byte word, and 13bits of this are the binary temp.
25C is..... 0 0001 1001 0000 I need to make this Decimal and then divide by 16 for degrees Celcius.

Is there a picaxe that will be happy to pull this data and do the math functions well, so I get no loss in resolution in the temp chip data?

I dont know how to do the rest of it either, but this seems fundamental to me.
Golfnut
 

hippy

Ex-Staff (retired)
The ADT7410 can read the temperature to 16 bits giving a notional resolution of 0.0078125'C. It should be possible to convert that without loss of accuracy of the result read using almost any PICAXE though those with I2C commands will be better suited and have enough program memory to perform the conversion and display.

Given "no rounding or truncation errors" you will have to convert the 16-bit value to a display with ten digits. The easiest way to do that is probably using BCD, a memory location holding each digit.
 

Dippy

Moderator
I've only had a very quick look, time for my bath.

Looks do-able. Note the Data Sheet i looked at shows accuarcy of 0.5oC over -40 to +105oC. (Accuracy/precision... different animals.)

The I2C looks OK , though the numerica manipulation will be fairly long winded.

"I dont know how to do the rest of it either, but this seems fundamental to me."
- Forgive me, I know it's Christmas, but it looks like somone will have to do all of the Data Shet reading and code-writing for you.
Might it be better if you started off with something you can get to grips with and then step up to this one?
Westy? Eclectic? You've got plenty of time... ;)
 

hippy

Ex-Staff (retired)
Code:
Do
  Gosub DisplayTempInW0
  w0 = w0+1
  Pause 1000
Loop

DisplayTempInW0:
  SerTxd( #bit15, #bit14, #bit13, #bit12," ")
  SerTxd( #bit11, #bit10, #bit9,  #bit8, " ")
  SerTxd( #bit7,  #bit6,  #bit5,  #bit4, " ")
  SerTxd( #bit3,  #bit2,  #bit1,  #bit0, 9  )
  If bit15 = 1 Then
    SerTxd( "-" )
    w0 = -w0
  End If  
  w1 = w0 / 128
  w2 = 0
  w3 = 0
  If bit0 = 1 Then : w2 = w2 + 0078 : w3 = w3 + 125 : End If
  If bit1 = 1 Then : w2 = w2 + 0156 : w3 = w3 + 250 : End If
  If bit2 = 1 Then : w2 = w2 + 0312 : w3 = w3 + 500 : End If
  If bit3 = 1 Then : w2 = w2 + 0625                 : End If
  If bit4 = 1 Then : w2 = w2 + 1250                 : End If
  If bit5 = 1 Then : w2 = w2 + 2500                 : End If
  If bit6 = 1 Then : w2 = w2 + 5000                 : End If
  BinToAscii w2, b8, b9, b10, b11, b12
  SerTxd( #w1, ".", b9, b10, b11, b12 )
  BinToAscii w3,  b8, b9, b10, b11, b12
  SerTxd( b10, b11, b12, CR, LF )
  Return
 
Last edited:

manuka

Senior Member
Golfnut: I'm often wary with such high resolution temperature quests, as in many circumstances "false accuracy" may arise. Best you enlighten us about the application & how frequently readings need to be taken.

Aside from the usual calibration/resolution/accuracy/precision issues, such intended fine readings may be also biased by thermal lag etc. As this device has a temperature conversion time of 250 ms, subtle temp. changes may occur even while monitoring.

At the starter level try Maxim's (was Dallas Semi) DS18B20, which (thanks to their READTEMP & READTEMP12 commands) is extremely PICAXE friendly. However read time is ~750 ms. Stan
 
Last edited:

lbenson

Senior Member
Note that the DS18B20 digital thermometer also provides an operating temperature range of -55°C to +125°C and is accurate to ±0.5°C over the range of -10°C to +85°C, and also has 12-bit Celsius temperature measurements: http://www.maxim-ic.com/quick_view2.cfm?qv_pk=2812

This would be easier to use than the ADT7410. Perhaps someone more expert could explain how the ADT7410 would provide greater accuracy or resolution for practical purposes.
 

golfnut

Member
Temp measurement

Thanks for the replies gents. You are dealing with a relative noob here. Done some basics on 08M in the summer. (Ive never read from another device with registers - a little daunting)

In summary for my application, Its just a good tight thermometer on the cheap.
Range is approx -30C to +125C to 3Dec places. eg -7.481C or -8.628C display format,

where the fourth dec place (you dont see on the display) influences round up or down of the the 3rd place after the dec point.

I know you are all going shout at the same time - you dont need that many bits for 4 dec places. You only need blah bits for that...The problem for me is I dont know how many bits I need for 4 meaningful Dec places.

Aside, Id like to read and display temp every 0.25sec. Anyone think that a prob? I would guess no. (Im aware the thermal lag of the chip is about 40secs to steady state - not a problem)

I know that resolution does not mean accuracy. The analog part has Typ Acc is +/-0.1C, from 0c to 80c(3.3v rail) which is the reason for picking this one, its resolution is Beyond what I req.

golfnut
 

hippy

Ex-Staff (retired)
The problem for me is I dont know how many bits I need for 4 meaningful Dec places.
The number of bits will be up to the point before the sum of all possible subsequent bits has no affect on rounding up or down of more significant digits.

By my calculations -

01 = 0.5
02 = 0.25
03 = 0.125
04 = 0.0625
05 = 0.0312 5
06 = 0.0156 25
07 = 0.0078 125
08 = 0.0039 0625
09 = 0.0019 53125
10 = 0.0009 765625
11 = 0.0004 8828125
12 = 0.0002 44140625
13 = 0.0001 220703125
14 = 0.0000 6103515625
15 = 0.0000 30517578125
16 = 0.0000 152587890625
17 = 0.0000 0762939453125

So it looks to me like you'll need 17 bits ( maybe more ) after the binary decimal point for accuracy to four decimal places.

0.00000000000000110 = 0.0000 457763671875 => 0.0000
0.00000000000000111 = 0.0000 6866455078125 => 0.0001
 

LizzieB

Senior Member
I know that resolution does not mean accuracy. The analog part has Typ Acc is +/-0.1C, from 0c to 80c(3.3v rail) which is the reason for picking this one, its resolution is Beyond what I req.

golfnut
You can't rely on "Typical Accuracy", the only thing you can rely on is that for the particular device you are using the accuracy will be as specified, e.g. ±0.5°C from −40°C to +105°C @ VDD = 2.7 V to 3.6 V.
 

golfnut

Member
woof

Cheers Hippy for the effort here.

If I were to display 25.999 Celcius - which is enough resolution' for me.

With 13 bit ADC (which my chip has by default) and the subsequent 13 bits in the temp read register...I could display

25.9991220703125 Is this what you meant? Or have I lost it some more.
(13 = 0.0001 220703125 from your explanation)
I then would effectively mask a lot of this away so I only display 25.999C

Then I have bagged more or less all of the resolution capability of the chip.

So final question is. Surely 13bits is enough to display 3 good meaningful places after the dec point with minimal rounding or truncation errors? As above.
gn
ps Cost of the chips was free from ADI Sample site in USA http://www.analog.com/en/content/samples/fca.html
 
Last edited:

hippy

Ex-Staff (retired)
The real problem is the definition of "meaningful places", "accuracy" and "resolution".

If you want to accurately discriminate between a temperature of 25.998 and 25.999 you need to have 13 or so binary fractional bits to work with and that's excluding bits which represents the whole part of the temperature.

You can take what the chip returns and display to three decimal places but that's not the same as displaying the actual temperature accurate to three decimal places.

With just two fractional bits you can display any of the four temperatures -

25.00
25.25
25.50
25.75

That's to two decimal places but you are only showing temperature accurate to 0.25'C, not to 100th of a degree.
 

manuka

Senior Member
Hippy - pretty much my point too, although I'm more alerted to thermal & measurement uncertainty issues.

Outside professional research labs there are few DIY situations where temperatures quoted to 1/100th of a degree can be considered gospel- the very act of electrical monitoring introduces disparities brought on by thermal mass,reading delay and self heating for starters.The ambient atmospheric pressure may also be a factor. Even such a scientific standard as the triple point of water is only quoted as 273.16 K (0.01 °C). Metrology (the science of measurement) is very concerned with such issues as measurement traceability,most often obtained by calibration against standards.

Parallels with time of course abound- microsecond intervals can be readily detected, BUT elapsed time (such as for Olympic sprints when human reaction time may be an issue ) is typically limited to 1/100th of a second. Even with digital measurement, Bolt's August 2009 100m sprint record is quoted as 9.58 seconds.

FWIW about the only everyday measurement that you are justified in quoting to such extremes is the esteemed Weston standard cell, which has a voltage of 1.018636 V at 20°C -providing it's not abused.

Of course it's possible that Golfnut has $$$$$$$$$ facilities on tap (in which case he may soon be in receipt of Forum invoices ...), but I for one am still ignorant about just WHAT is being subject to such intensive thermal scrutiny. Stan.

Footnote: The unit mentioned by Eclectic back in post #10 is presently on sale (at a mere US$8200)!
 
Last edited:

westaust55

Moderator
C = Centigrade?
C = Celsius


"The Celsius scale wazs defined in 1954 at the 10th General Conference of Weights and Measures, temperature on the Celsius scale is the temperature on the Kelvin scale minus 273.15. This definition makes values on the Celsius and centigrade scale agree within less than 0.1 degree. For everyday purposes, the scales are identical.
One reason for doing away with the word “centigrade,” was that it might be confused with one-hundredth of a grade, a unit of plane angle."(http://www.sizes.com/units/temperature_centigrade.htm)
 

golfnut

Member
getting through

Hippy, nice clear teaching, you have found my level. If you bang anyones head with a global hammer for two days it will go thru the square hole, I look like krytens dodgy twin now.

Two fractional binary bits can give me decimal fractional resolution to 0.25C
(sounds really silly now spelling it out)

I too, now think that 25.999C is fanciful as the 3rd dec place is thousandths of a degree and an unnecassary bridge too far. Lets drop an order of mag so sticking with a display format of 23.48C
(or 103.38C or -17.37C etc) To increment or decrement the second dec place by 1 to 23.49 or 23.47 I would need to know if the 3rd dec place was in the range 0 to 4 to round down or 5 to 9 to round up.

from my chip 16 bits is what I have to play with. The biggest whole I will measure will be 125 so, a chunk of bits would get used up to give the whole part, the remaining bits left would be available for the fractional part. Sticking with a display format of xxx.xx Celcius

from Hippys post 16bits = 0.0000 152587890625

measuring 100's 104.001 52587890625 C display 104.00C rounding down by 0.001
10's off 78.000 152587890625 C display 78.00C again with good confidence
units 6.000 0152587890625 C display 6.00C with great confidence


Have I strayed too far from the truth here, are you all shouting "schoolboy error" already?
Is this what my 16bit chip could do or is it time to take up morris dancing or something equally humiliating..
Golfnut
 

hippy

Ex-Staff (retired)
With the ADT7410 giving 7 fractional bits in 16-bit mode that returns temperature to 1/128th of a degree so showing that to two decimal places would seem reasonable. The following code will do that, including rounding up or down -

Code:
Do
  Gosub DisplayTempInW0
  w0 = w0+1
  Pause 1000
Loop

DisplayTempInW0:
  SerTxd( #bit15, #bit14, #bit13, #bit12," ")
  SerTxd( #bit11, #bit10, #bit9,  #bit8, " ")
  SerTxd( #bit7,  #bit6,  #bit5,  #bit4, " ")
  SerTxd( #bit3,  #bit2,  #bit1,  #bit0, 9  )
  If bit15 = 1 Then
    SerTxd( "-" )
    w0 = -w0
  End If  
  w1 = w0 / 128
  w2 = 0
  w2 = bit0 * 0078 + w2
  w2 = bit1 * 0156 + w2
  w2 = bit2 * 0312 + w2
  w2 = bit3 * 0625 + w2
  w2 = bit4 * 1250 + w2
  w2 = bit5 * 2500 + w2
  w2 = bit6 * 5000 + w2
  w3 = w2 // 100
  If w3 >= 50 Then
    w2 = w2 + 100
  End If
  BinToAscii w2, b8, b9, b10, b11, b12
  SerTxd( #w1, ".", b9, b10, CR, LF )
  Return
Results are -

0000 0000 0000 0000 0.00
0000 0000 0000 0001 0.01
0000 0000 0000 0010 0.02
0000 0000 0000 0011 0.02
0000 0000 0000 0100 0.03
0000 0000 0000 0101 0.04
0000 0000 0000 0110 0.05
0000 0000 0000 0111 0.05
0000 0000 0000 1000 0.06
0000 0000 0000 1001 0.07
0000 0000 0000 1010 0.08
0000 0000 0000 1011 0.09
0000 0000 0000 1100 0.09
0000 0000 0000 1101 0.10
etc
 

golfnut

Member
digital thermometer update

trying to get 033 lcd going well on 20X2, had some good success using code donated from Hippy.

That code sent results over sertxd, I modifed it to send data to my LCD and I have made a long day of it. Not that succesful if Im honest.

I fixed values for b0 and b1 using let command so that W0 had realistic 16bit binary to chew on.
I got 25.5C on the simulated lcd for a while on pc screen.

Altered what I thought ie the sertxd to serout etc just couldnt repeat what the simulated lcd gave. ie sometimes .50C and no whole number sometimes just martian cypher you know..

Code:
          	 BinToAscii  w2, b8, b9, b10, b11, b12
			 
			serout b.3, N2400, (254, 128)
			pause 30
			serout b.3, N2400, (w1, b9, b10,  ".")  my dodgy stuff
			  
		 'SerTxd( #w1, ".", b9, b10, CR, LF )   hippy orig, works over serial



Any input for getting numbers from binary words onto the lcd, whether to use the # or not, or does one put the word to lcd as two bytes etc..
I am trying to see things like 24.16C etc
 

hippy

Ex-Staff (retired)
Not entirely sure I'm following but why not just send what's in the SERTXD as SEROUT excluding the CR, LF ?

SerOut B.3, N2400, ( #w1, ".", b9, b10 )
 

golfnut

Member
Hi, I did try that at some point,




Code:
'init: pause 500   'give devices some settling time from power up
                  'Configure Temp sensor to 16bit at 1 sample per second....
'	i2cslave %10010000, i2cslow, i2cbyte
'	hi2cout  %00000011,(%10100000)  
   

main:
	pause 1100  'guarantees a complete sample ready as 
	            'the temp IC samples are ready every second
	Do
			'read I2C Temp Bytes MSB
	'	i2cslave %10010000, i2cslow, i2cbyte
	'	hi2cin   %00000000,(b1) 
         
         		'read I2C Temp Bytes LSB
	'	i2cslave %10010000, i2cslow, i2cbyte
	'	hi2cin   %00000001,(b0) 

  	let b1=%00001100            'added to get 16bit no into w0 to simulate having
  	let b0=%01100000            ' my temp sensor supplying data

		Gosub DisplayTempInW0
	      w0 = w0+1
		Pause 1000
	Loop
		
	
	
DisplayTempInW0:
		 
			  If bit15 = 1 Then
			    SerTxd( "-" )
			    w0 = -w0
			  End If  
			  w1 = w0 / 128
			  w2 = 0
			  w2 = bit0 * 0078 + w2
			  w2 = bit1 * 0156 + w2
			  w2 = bit2 * 0312 + w2
			  w2 = bit3 * 0625 + w2
			  w2 = bit4 * 1250 + w2
			  w2 = bit5 * 2500 + w2
			  w2 = bit6 * 5000 + w2
			  w3 = w2 // 100
			  
			  If w3 >= 50 Then
			    w2  = w2 +100
			  End If
			  
			 
			 BinToAscii  w2, b8, b9, b10, b11, b12
			 
			serout B.3, N2400, (254, 128)
			pause 30
			SerOut B.3, N2400, ( #w1, ".", b9, b10 ) 
			  
			  Return
This code gives 23||V on my lcd (cant do the real graphic) after poss 1sec info moves to right one symbol width.
As a trial without the # infront of w1 I get .75 on lcd and it doesnt move about.

I did the hello world thing it seems solid, it displays text in "qoutes" etc.
Running the x2 at default speed 8 is it?

Is one of my errors the way ive put dummy binary data in?
GN
 

golfnut

Member
can get half going..

The fractional value displays correctly - only if I delete the #w1 from the serout (func)
Code:
            	serout B.3,N2400,(254,1)     ' Clear screen
            	pause 50
	serout B.3,N2400,(254,128)  ' write on first line at LHS
	pause 50
	Serout b.3, N2400,(".",b9,b10,"C")
Display reads .99C
If I add back whole part of the temp value as #w1 Im in a world of pain, display goes across the screen.
Thought it may be a uP speed thing, tried it with N2400_4 to slow it up, but just the same, something odd about having #w0 in a serout on the 20X2
Doing a debug of w1 it is 25 as set higher up in my code.

Cup of cha, I think. She will have me doing real' jobs at this rate,,,. :.)
 

eclectic

Moderator
See M2, p. 173

Data are variables/constants (0-255) which provide the data to be output.
Optional #’s are for outputting ASCII decimal numbers, rather than raw

So, W1 would need displaying as

Serout n ..... (#b3,#b2)


Ec
 

golfnut

Member
Hi, Ec

I did what you suggest, I had tried similar but admittedltly without the #...


The problem is....

If I try to display reg b2 and it has 2 or more dec digits eg 23

b2 in the debug panel is 23 which is correct (whole part of my 23.00C value)
The LCD only displays the first digit, 2 then rubbish

If I mod b2 content to single digit eg %00000111 no problem,
then in the serout (fn) use #b2 .... then LCD displays 7 etc

Anyone know syntax for displaying a register value 10 or more to lcd

I would guess Im going to have to split 23 from b2 reg and put the 2 in reg-x
and the 3 in reg-y and serout reg x and y

??? GN
 

golfnut

Member
ah, display good, can go to bed now.

what was required was.. apart from knowing what your doing..

The b2 and b3 registers forming word w1 - I did a

bintoascii w1, b13,b14,b15,b16,b17

so each reg gets a dec power eg lsb dec display dig is in reg b17 (tens)
hundreds are in reg b16 etc. Solves the problem I had where say 23 wouldnt display.
This way the 2 comes from b16 and 3 from b17

(I know my old boss would say, RTFM ... read the manual.)

then to display

Serout b.3, N2400_8,(b15,b16,b17,".",b9,b10,"C")

Format on LCD is 000.00C or -055.23C or 023.48C

Next job is graft the sensor on and get it talking to uP.
GN
 

golfnut

Member
some success thermometer

Digital thermometer using an ADI7410, a 20X2 and 33 lcd
Giving some reasonable results, comparing to within 0.1C to a german IR medical in ear thermometer.

One problem I noticed.
I take an ave of a register, the MSB of this reg should not be in the avg calculation.
I want to leave bit7 alone and not average that - is that easy , I cant find a command that looks suitable.

currently I do this....

bo register holds a new value each 240ms, so I loop every 250ms and pull the value and do an average of 40 samples as below but bit7 of b0 I want to not include in the avg, just let it stay what it is, all the way thru code to display data.

my code averages the whole 8 bits of b0 and not bit6 thru bit0 I require

do
'read I2C Temp Bytes MSB
i2cslave %10010000, i2cslow, i2cbyte
hi2cin %00000000,(b1)
'read I2C Temp Bytes LSB
i2cslave %10010000, i2cslow, i2cbyte
hi2cin %00000001,(b0)

w24=w24+b0
inc b55
loop while b55 < 40

w25=w24/40
b0=b50

etc etc
GN
 

Attachments

Top