ATtiny13 – temperature logger using LM35 and Software UART

This project is about a simple temperature logging system using ATtiny13 and the Software UART. The system reads the temperature every second and shows it on the serial console (baudrate 19200, settings 8N1). The temperature is shown in °Celsius. LM35 has been used as the temperature sensor. Complete example code is on GitHub.

LM35 Temperature Sensor

LM35 is three terminal linear temperature sensor. It can measure temperature from- 55°C to +150°C. The voltage output of the LM35 increases 10mV per degree Celsius rise in temperature. LM35 can be operated from a 5V supply and the stand by current is less than 60μA. The pin out of  LM35 is shown in the figure below.

Parts

Circuit Diagram

Firmware

This code is written in C and can be compiled using the avr-gcc. More details on how compile this project is here. Complete example code is on GitHub.

/**
 * Copyright (c) 2017, Łukasz Marcin Podkalicki <lpodkalicki@gmail.com>
 * ATtiny13/029
 * Read temperature (0°C to 100°C) using analog sensor LM35
 * and log the data to Software UART (baudrate 19200, 8N1) once per second.
 *
 * Settings:
 *  FUSE_L=0x6A
 *  FUSE_H=0xFF
 *  F_CPU=1200000
 */

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "uart.h"

#define	LM35_DATA_PIN	PB4

static void LM35_init(void);
static int LM35_read(void);
static int analog_read(uint8_t pin);
static void uart_puttemp(int temp);

int
main(void)
{
	int temp;

	/* setup */
	LM35_init();

	/* loop */
	while (1) {
		temp = LM35_read();
		uart_puttemp(temp);
		_delay_ms(1000);
	}
}

void
LM35_init(void)
{

	DDRB &= ~_BV(LM35_DATA_PIN); // set data pin as INPUT
}

int
LM35_read(void)
{
	int temp;

	temp = analog_read(LM35_DATA_PIN); // read analog value from sensor
	temp = ((((uint32_t)temp * 1000UL) >> 10) * 5); // convert value using euqation temp = Vin * 1000 / 1024 * Vref [milivolts]

	return temp;
}

int
analog_read(uint8_t pin)
{
	uint8_t low, high;

	switch(pin) {
	case PB2: ADMUX = _BV(MUX0); break; // ADC1
        case PB4: ADMUX = _BV(MUX1); break; // ADC2
        case PB3: ADMUX = _BV(MUX0)|_BV(MUX1); break; // ADC3
        case PB5: // ADC0
	default: ADMUX = 0; break;
	}

	ADMUX &= ~_BV(REFS0); // explicit set VCC as reference voltage (5V)
	ADCSRA |= _BV(ADEN);  // Enable ADC
	ADCSRA |= _BV(ADSC);  // Run single conversion
	while(bit_is_set(ADCSRA, ADSC)); // Wait conversion is done

	// Read values
	low = ADCL;
        high = ADCH;

        // combine two bytes
        return (high << 8) | low;
}

void
uart_puttemp(int temp)
{
	int value = temp / 10;
	uart_puts("temp=");
	uart_putu(value);
	uart_putc('.');
	uart_putu(temp - (value * 10));
	uart_putc('\n');
}

3 thoughts on “ATtiny13 – temperature logger using LM35 and Software UART

  1. Thank you!

    I managed to have it working yet it is not accurate enough. Probably the outputs will get better with a minute or two delay in measurement.

    In the diagram, I think you meant for the TX pin PB3 to go to the RXD pin of the FTDI so I got confused at the beginning.

    Thanks again and please keep up with the great projects of ATtiny13a

  2. Greetings !
    Thank you so much for the nice work !
    I tried to compile the program using the command (I changed the value of the MCU to “MCU=attiny13a” in the uart.h file as well):

    $sudo avr-gcc -Wall -g -Os -mmcu=attiny13a -DF_CPU=1200000 -I. -DUART_BAUDRATE=19200 main.c -o main.bin

    I end up with this error:

    …/blog-master/avr/attiny13/029_log_temperature_lm35_to_software_uart/main.c:91: undefined reference to `uart_puts’
    …/blog-master/avr/attiny13/029_log_temperature_lm35_to_software_uart/main.c:92: undefined reference to `uart_putu’
    …/blog-master/avr/attiny13/029_log_temperature_lm35_to_software_uart/main.c:93: undefined reference to `uart_putc’
    …/blog-master/avr/attiny13/029_log_temperature_lm35_to_software_uart/main.c:94: undefined reference to `uart_putu’
    …/blog-master/avr/attiny13/029_log_temperature_lm35_to_software_uart/main.c:95: undefined reference to `uart_putc’
    collect2: error: ld returned 1 exit status

    Please help

    Thank you !

    • Hi! You need to compile uart.c and link it with main.o. Also, you don’t need to compile it with “sudo”.

      $avr-gcc -Wall -g -Os -mmcu=attiny13a -DF_CPU=1200000 -I. -DUART_BAUDRATE=19200 main.c uart.c -o main.bin

      See the Makefile (…/blog-master/avr/attiny13/029_log_temperature_lm35_to_software_uart/Makefile).

Leave a Comment