Componentes Eletronicos

Leitura do Sensor de Temperatura Interna do Arduino

Eletrogate 8 de agosto de 2023

Introdução

Algumas placas Arduino possuem um sensor que permite medir a temperatura interna do chip.

Esse sensor é um diodo que produz uma tensão dependente da temperatura. Esta tensão é medida com o ADC e tem uma relação linear com a temperatura.

Além do ATmega328P, outros chips AVR’s também possuem essa funcionalidade, como o ATmega32U4 (Arduino Leonardo), ATmega328 (Arduino Nano), ATmega168P e ATmega168A.


Materiais Necessários para o Projeto de Leitura do Sensor de Temperatura Interna do Arduino


Sua Utilidade e Limitações

A leitura do sensor de temperatura interna pode ser útil em diversos projetos. Além disso, a leitura do sensor de temperatura interna pode ser usada como uma ferramenta de diagnóstico. Se a temperatura interna do Arduino estiver constantemente elevada, isso pode indicar algum problema, como um curto-circuito, superaquecimento ou mau funcionamento de algum componente. Nesses casos, a leitura do sensor pode auxiliar na detecção e resolução desses problemas. No entanto, devemos destacar as limitações desse sensor, pois ele não pode ser utilizado na medição da temperatura ambiente, visto que sua precisão e a faixa de medição são limitadas em comparação com sensores externos dedicados.


Precisão

É importante ressaltar que a precisão do sensor é baixa e pode ser afetada por variações na tensão de alimentação do Arduino, o que pode resultar em ruídos e desvios na leitura da temperatura. De acordo com o datasheet, a temperatura pode variar em até ±10 graus Celsius. No entanto, é possível alcançar uma precisão de aproximadamente 4 °C ou ±2 °C, se o ganho e o deslocamento forem devidamente ajustados.


O Programa

Antes de realizarmos a leitura do sensor, é preciso configurar os registradores do ADC. Isso pode ser realizado com as seguintes etapas:

1. Defina a referência de tensão interna de 1.1V para o ADC:

ADMUX |= (1 << REFS1) | (1 << REFS0);

É importante notar que, quando a referência é a tensão interna, não se deve aplicar uma tensão superior a 1.1 V nos pinos configurados como entrada analógica. Isso ocorre porque a tensão interna de referência é limitada a esse valor, garantindo a correta leitura da temperatura.

2. Configure o prescaler do ADC:

ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);

Essa linha define o prescaler do ADC como 128, o que determina a taxa de conversão do ADC.

3. Selecione o canal ADC para o sensor de temperatura:

ADMUX = (ADMUX & 0xF0) | 0x08;

Nessa linha é definido o canal ADC como o canal 8, que é o canal para o sensor de temperatura interno.

4. Inicie a conversão ADC:

ADCSRA |= (1 << ADSC);

Aqui é iniciado a conversão do ADC e começa a amostrar o valor do sensor de temperatura.

5. Aguarde a conversão ser concluída:

while (ADCSRA & (1 << ADSC));

Esse loop aguarda até que a conversão ADC seja concluída. Quando a conversão é concluída, o bit ADSC é limpo automaticamente.

Após concluir essas etapas, o valor do sensor de temperatura pode ser obtido lendo-se o registrador ADC.

uint16_t temperatura = ADC;

O valor da temperatura será armazenado na variável “temperatura” para ser utilizado posteriormente no programa.

Agora, com as configurações do ADC definidas, nós podemos criar uma função para fazer a configuração e leitura do sensor.


Leitura do Sensor de Temperatura Interna

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

//Altere aqui para calibrar o sensor
static const float offset = 335.2; 
static const float ganho = 1.06154; 

//AUMENTE o valor do offset para DIMINUIR a temperatura
//DIMINUA o valor do offset para AUMENTAR a temperatura
//o valor de referencia do offset é 335.2 e para o ganho é 1.06154 

// Função para inicializar o ADC
void ADC_init() {
    ADMUX |= (1 << REFS1) | (1 << REFS0);   // Utiliza a referência interna de tensão de 1.1V
    ADCSRA |= (1 << ADEN);                  // Habilita o ADC
    ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);  // Define o prescaler do ADC como 128
}

// Função para ler o sensor de temperatura interno
uint16_t ler_temperatura() {
    // Seleciona o canal ADC 8 para o sensor de temperatura
    ADMUX = (ADMUX & 0xF0) | 0x08;

    ADCSRA |= (1 << ADSC);                  // Inicia a conversão ADC
    while (ADCSRA & (1 << ADSC));            // Aguarda a conclusão da conversão

    return ADC;
}

// Função para inicializar a UART
void UART_init(uint16_t taxa_baud) {
    uint16_t valor_ubrr = F_CPU / (16UL * taxa_baud) - 1;

    // Define a taxa de baud rate
    UBRR0H = (uint8_t)(valor_ubrr >> 8);
    UBRR0L = (uint8_t)valor_ubrr;

    // Habilita a transmissor
    UCSR0B |= (1 << TXEN0);

    // Define o formato do frame: 8 bits de dados, 1 bit de parada, sem paridade
    UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);
}

// Função para transmitir um caractere via UART
void UART_transmitir(uint8_t dado) {
    while (!(UCSR0A & (1 << UDRE0)));    // Aguarda o buffer de transmissão vazio
    UDR0 = dado;                         // Coloca os dados no buffer e enviar
}

// Função para transmitir uma string via UART
void UART_transmitir_string(const char* str) {
    for (int i = 0; str[i] != '\0'; i++) {
        UART_transmitir(str[i]);
    }
}

// Função para converter um valor float para uma string
void float_to_string(float valor, char* str) {
    int32_t inteira = (int32_t)valor;
    int32_t decimal = (int32_t)(valor * 100) % 100;

    if (valor < 0) {
        str[0] = '-';
        inteira = -inteira;
        decimal = -decimal;
    } else {
        str[0] = ' ';
    }

    str[1] = '0' + inteira / 10;
    str[2] = '0' + inteira % 10;
    str[3] = '.';

    str[4] = '0' + decimal / 10;
    str[5] = '0' + decimal % 10;
    str[6] = '\0';
}

int main(void) {
    ADC_init();                          // Inicializa o ADC
    UART_init(9600);                     // Inicializa o UART com taxa de baud rate 9600

    while (1) {
        uint16_t adc = ler_temperatura();

        // Conversão do valor ADC para temperatura em graus Celsius
        float celsius = (adc - offset) / ganho;

        char temperatura_str[7];
        float_to_string(celsius, temperatura_str);

        _delay_ms(1000);                   // Atraso de 1 segundo
        
        // Transmitir string de temperatura via UART
        UART_transmitir_string("Temperatura: ");
        UART_transmitir_string(temperatura_str);
        UART_transmitir('\n');

    }

    return 0;
}


Calibragem do Código

Os sensores dos chips AVR’s podem ser calibrados com a equação abaixo.

Onde TADC é o valor medido pelo sensor sem nenhuma calibração.

O Toffset é um valor de compensação ou desvio. Ele representa um ajuste para corrigir os erros de leitura do sensor.

E o K é um fator de escala ou ganho aplicado à leitura do sensor.

No código, foram usados, como referência, os valores fornecidos em um post,no site AvdWeb.

Onde Toffset = 335.2 e o K = 1.06154.

Siga os passos abaixo para calibrar o código:

1. Conexão do hardware:

Conecte a placa do microcontrolador ao seu computador usando o cabo de conexão serial apropriado.

2. Configuração inicial do programa:

Abra o Arduino IDE no seu computador.
Crie um novo projeto e cole o código da leitura do sensor de temperatura interna.
Faça o upload do código para o Arduino.

3. Monitoramento das leituras:

Abra o monitor serial no menu “Ferramentas”.
Verifique se a velocidade de transmissão (baud rate) está configurada em 9600.
Aguarde as leituras serem exibidas no monitor serial.

4. Comparação com uma referência externa:

Utilize um termômetro externo confiável para medir a temperatura ambiente.

5. Ajuste no código:

Compare a leitura do sensor interno exibida no monitor serial com a leitura da referência externa. Se houver uma diferença significativa entre as leituras, será necessário ajustar o valor da variável “offset” no código.
Caso o valor exibido no monitor esteja abaixo da temperatura referência, diminua o valor do offset.
Ou, se estiver acima da temperatura referencia, basta aumentar o offset.
Carregue o código novamente após fazer as alterações e verifique os novos valores.
Repita esse passo até que as leituras do sensor estejam dentro de uma faixa aceitável de erro (± 2 °C) em relação à referência externa.

Deve-se considerar que a temperatura interna pode aumentar alguns graus após aproximadamente 10 minutos.


Conclusão

Em resumo, a leitura do sensor de temperatura interna do Arduino Uno oferece uma funcionalidade importante para monitorar a temperatura do microcontrolador e identificar problemas internos. Embora apresente algumas limitações, compreender suas características e aplicações nos possibilita aproveitar de forma mais eficiente o Arduino em nossos projetos eletrônicos.


Sobre o Autor


Igor

Técnico em Eletrônica e estudante de Engenharia de Controle e Automação, sempre explorando novas tecnologias e desenvolvendo projetos que otimizam tarefas cotidianas.


Eletrogate

8 de agosto de 2023

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!