Read Temperature with PICAXE and DB18B20

August 29, 2013

I wanted to read the temperature using a DB18B20 temperature sensor connected to a PICAXE 8M2+, and then transmit this temperature to a computer using a URF/ERF pair.

Circuit

The ERF was configured as explained in http://drumcoder.co.uk/blog/2013/aug/22/picaxe-urferf-hello-world-ubuntu/

There was an LED connected to the PICAXE on C.1

The DB18B20 has three pins:

DS18B20Pinout

The outer two are connected to +ve and ground, and the middle one is connected to +ve via a 4K7 resistor. The middle one is also connected to C.2 on my PICAXE.

Program

Here's the PICAXE program used, along with comments.

main:
    symbol TemperatureSign = bit0      ' This holds whether the temperature is positive or negative
    symbol Whole = b1                  ' This will hold the whole number of degrees
    symbol Fraction = b2               ' This holds the fractional part of the temperature, to two decimal places
    symbol TemperatureTimes100 = w3    ' This holds the temperature count in tenths of a degree
    symbol Temperature12 = w4          ' This holds the value read from the temperature sensor
    setfreq m8                         ' Set the frequency to 8Mhz for the ERF module
    high C.1                           ' Turn LED on C.1 on
    readtemp12 C.2, Temperature12      ' Read temperature into Temperature12 variable
    low C.1                            ' Turn LED on C.1 off
    TemperatureSign = Temperature12 / 256 / 128    ' Take the most significant bit from the 16 bit word - this is the sign +/-
    if TemperatureSign = 1 then 
        Temperature12 =  Temperature12 ^ $ffff + 1 ' Temperature is negative, convert number using two's complement
    endif
    TemperatureTimes100 = Temperature12 * 6      ' Temperature12 is the number of 0.0625 increments, so we can get the
                                                 ' temperature * 100 by multiplying by 6.25.  
                                                 'This bit multiplies by 6 and...
    Temperature12 = Temperature12 * 25 / 100     ' ...this bit multiplies by 0.25
    TemperatureTimes100 = TemperatureTimes100 + Temperature12    'add these two values together to get Temperature * 100
    Whole = TemperatureTimes100 / 100             ' Whole number of degrees is this value divided by 100
    Fraction = TemperatureTimes100 % 100          ' Fractional number of degrees is this value mod 100
    if TemperatureSign = 0 then
       if Fraction > 9 then
         serout C.4, N9600_8, ("TEMP:",#Whole,".",#Fraction,"_")    ' Output positive value to network
       else
         serout C.4, N9600_8, ("TEMP:",#Whole,".0",#Fraction,"_")   ' Output positive value with decimal place prefixed by 0
      endif
    else
       if Fraction > 9 then
         serout C.4, N9600_8, ("TEMP:-",#Whole,".",#Fraction,"_")    ' Output negative value to network
       else
         serout C.4, N9600_8, ("TEMP:-",#Whole,".0",#Fraction,"_")   ' Output negative value with decimal place prefixed by 0
       endif
    endif
    pause 1000
    goto main

The main difference in this program over previous ones is the use of symbols as aliases for bytes, words and bits.

There's some logic to determine what to output on the network. If TemperatureSign is zero, then we have a positive value. If it's one, then we have a negative temperature and need to prefix the value sent out with a minus sign. If Fraction is less than 9, then it's a single digit fractional value and so needs to be prefixed with zero. That is, we need to transmit 23.06 rather than 23.6. (I'm sure there's probably a more elegant way to do this bit!)

The temperature sensor can take upto 750ms to read the temperature, and this is shown by the time the LED on C.1 is on for.

Computer

On the computer with the URF module plugged in, I used the same Python program shown in http://drumcoder.co.uk/blog/2013/aug/24/reading-pixaxe-urf-erf-output-python/, which gave the following output:

TEMP=26.06
TEMP=26.12
TEMP=26.25
TEMP=26.31
TEMP=26.37
TEMP=26.43
TEMP=26.31
TEMP=26.12
TEMP=26.00
TEMP=25.87
TEMP=25.75
TEMP=25.62
TEMP=25.50

References