Temperature Logger

From Wiki

Jump to: navigation, search


Implementing a serial temperature logger using an AVR and your workstation.

Once you have your one wire interface hooking your DS1820 or DS1822 to your AVR, you can easily send the data back over the serial port to your PC, and produce nice graphs like this one:

temp-graph.png

Here's the AVR source code to augment the udelay and one wire source code.

void serial_write(uint8_t byte) {
    sbi(UCR, TXEN);
    loop_until_bit_is_set(USR,UDRE);
    outp(byte, UDR);
    cbi(UCR, TXEN);
}

void serial_setup(void) {
    // make sure they're 8-bit characters
    cbi(UCR, CHR9);

    // set baud rate to 9600 bps
    outp(38, UBRR);
}

int main(void) {
    wdt_disable();

    outb (0xFF,DDRB); /* PORTB is all outbut */
    outb (0x00,DDRD); /* PORTD is all input */
    outb (~0x00, PORTB);

    uint8_t scratchpad[9];
    uint8_t i;

    for (i = 0; i < 9; i++) scratchpad[i] = 0;
    serial_setup();

    while (1) {
        uint16_t celcius;
        uint16_t fahrenheit;

        convert_temp();
        celcius = read_temp();
        fahrenheit = ((celcius * 9) / 5) + (32 << 4);
        outb(~((fahrenheit>>4)&0xFF), PORTB);
        // write the data to the serial port in nibbles
        serial_write(0); // start byte always 0
        for (i = 0; i < 4; i++) {
            serial_write((celcius & 0xF) + 'A'); // +'A' means we never transmit 0x00
            celcius >>= 4;
        }
        serial_write('\n');
        serial_write('\r');
    }
}

Please note how I write the data as 4 nibbles in ASCII. This was inefficient, but easy to debug in a regular terminal program, so I left it that way. Then, I created a simple parsing program on my PC. You can find that source code httphere. It will sample the temperature over a 30 second range, and spit out a line that looks like this:

1054189758: 83.0223
1054189789: 82.7881
1054189820: 82.8761
1054189851: 82.8537
1054189882: 82.8708
1054189913: 82.8908
1054189944: 82.7723
1054189975: 82.7578
1054190006: 82.8087
1054190037: 82.6964

Then, I run that into gnuplot, with a script that looks like this:

gnuplot << EOF
set terminal png small color
set size 1.5,1
set xtics rotate 3600
set ytics 2
set xdata time
set timefmt "%s"
set format x "%m/%d %l%p"
plot "/tmp/datalog" u ($1-25200):2 w l
EOF

Which should produce a graph that looks like the one above! Yay!

Here it is in action, reading 1010000 (80) degrees Fahrenheit. Its hot!

img_0849.sized.jpg

Here's another logged image from a board that had 2 sensors on it, one inside and one outside. There was also a window box fan running on a timer, blowing outside air into the house. Can you see when the fan turns on and off?

graph.png

Personal tools