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.
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.
É 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.
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.
#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; }
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.
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.
|
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!