19 fevereiro 2013

LM35 - Sensor de Temperatura

O LM35 é um sensor de temperatura fabricado pela National Semiconductor. Varia a tensão de saída (pino Vout) de acordo com a temperatura medida na superfície do sensor. No Arduino, usamos uma das entradas analógicas para ler esta tensão do LM35 e calcular a temperatura.

sensor de temperatura LM35
 
No circuito abaixo, podemos ver a ligação do LM35, assim como os 3 leds na protoboard, que acendem de acordo com a variação da temperatura. Todo esse material você encontra no Kit Arduino Iniciante , disponível na loja FILIPEFLOP :

Circuito LM35 Arduino
Ao executar o programa, o LM35 vai enviar informações pela entrada analógica do Arduino, que por sua vez vai tratar essas informações, converter a tensão do sensor para graus celsius e fahrenheit, armazenar os valores máximo e mínimo, e enviar essas informações pela serial, além de acender os leds.

Após compilar e transferir o programa para o Arduino, abra o Monitor Serial da IDE do Arduino e você verá uma tela parecida com esta :

LM35 - Serial monitor

Existem outros sensores de temperatura mais modernos, como o DS18B20, que é um sensor digital, possui bibliotecas próprias, possibilidade de ligar mais de um sensor na mesma porta do Arduino, e várias outras vantagens. Vou testar este sensor posteriormente e farei um post específico.

E já que falamos em datasheet no post anterior, abaixo os links para os datasheets dos sensores citados :

Datasheet LM35 : 

Datasheet DS18B20 :


Abaixo, o programa relativo ao circuito apresentado nesse post :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//Programa : Sensor de temperatura LM35
//Arduino & Cia

int pin = 0; // Pino analogico para ligacao do LM35

// Variaveis que armazenam a temperatura em Celsius e Fahrenheit
int tempc = 0,tempf=0; 
int samples[8]; // Array para precisão na medição

// Variáveis que guardam a temperatura máxima e mínima
int maxtemp = -100,mintemp = 100; 
int i;

void setup()
{
  Serial.begin(9600);     // Inicializa comunicação serial
  pinMode(13, OUTPUT);    // Define pino 13 como saída (led verde)
  pinMode(12, OUTPUT);    // Define pino 12 como saída (led vermelho)
  pinMode(11, OUTPUT);    // Define pino 11 como saída (led amarelo)
}

void loop()
{
  for(i = 0;i<=7;i++){ // Loop que faz a leitura da temperatura 8 vezes
    samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
    //A cada leitura, incrementa o valor da variavel tempc
    tempc = tempc + samples[i]; 
  delay(100);
}

// Divide a variavel tempc por 8, para obter precisão na medição
tempc = tempc/8.0; 
//Converte a temperatura em Fahrenheit e armazena na variável tempf
tempf = (tempc * 9)/ 5 + 32; 
//Armazena a temperatura máxima na variável maxtemp
if(tempc > maxtemp) {maxtemp = tempc;} 
//Armazena a temperatura máxima na vari[avel mintemp
if(tempc < mintemp) {mintemp = tempc;} 

//Se a temperatura estiver abaixo de 25, acende o led verde
if(tempc < 25) 
  {
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
  }

//Se a temperatura estiver acima de 28, acende o led vermelho
if(tempc > 28) 
  {
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    digitalWrite(11, LOW);
  }

//Se a temperatura estiver acima de 25 e abaixo de 28, acende o led amarelo
if((tempc > 25) && (tempc < 28)) 
  {
    digitalWrite(11, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
  }

// As linhas abaixo enviam para o monitor serial a temperatura em 
// Celsius e Fahrenheit,
// e também as temperaturas máxima e mínima registradas

Serial.print(tempc,DEC);
Serial.print(" Cels., ");
Serial.print(tempf,DEC);
Serial.print(" Fahr. -> ");
Serial.print(" Min : ");
Serial.print(mintemp,DEC);
Serial.print("  Max: ");
Serial.println(maxtemp,DEC);

tempc = 0;
delay(1000); // Aguarda 1 segundo e reinicia o processo
}

Até a próxima !


43 comentários:

  1. pq vc usa resistor na saida GND do sensor para arduino.. nao poderia ligar direto?

    e qual resistor usar?

    ResponderExcluir
    Respostas
    1. Boa tarde ! Eu liguei direto, e a medição estava variando demais, coisa de 5 graus, depois voltava ao normal. Coloquei um resistor de 10 K.

      Excluir
  2. Bom dia!!
    Tenho um módulo para o arduino com o LM35, mas o valor que eu estou lendo nao esta correto, leio sempre um valor muito acima, ao invés de ter na saída um valor de 28°C, por exemplo, tenho 128°C, por um acaso esse pode ser um problema do meu módulo, pois ja testei mais de um módulo e esta dando o mesmo problema, utilizei varios codigos para teste e sempre caio na mesma questão.
    Obrigado

    ResponderExcluir
    Respostas
    1. Bom dia. Pode me informar qual tipo de módulo está usando ? Se puder, mande um link. Já peguei módulos (não esse de temperatura, especificamente) com a pinagem invertida. O programa que você está usando é o mesmo do post ? Qualquer coisa, me mande uma mensagem privada usando o formulário de contato, com o código anexado. Abraço !

      Excluir
    2. Estou utilizando este módulo
      http://dx.com/pt/p/arduino-diy-lm35d-analog-temperature-humidity-sensor-module-black-140022...
      O primeiro programa que utilizei foi o do post, e funcionou da forma como expliquei acima.
      Obrigado, abraço!

      Excluir
    3. Entendi. Esse módulo não tem muitos componentes, é bem simples de usar. Você já tentou aumentar o número de samples (medições), para ver se ele melhora a precisão ? é esta linha :

      int samples[8]; // Array para precisão na medição

      Aumente o valor de 8 para 20, por exemplo, e veja se altera alguma coisa.

      Excluir
    4. Mudei e nao alterou, o sensor esta fornecendo quase 5 volts na saída, medi com multimetro, deve ser algum problema no sensor.

      Excluir
    5. Olá amigo, está marcando zero graus, e quando retiro o resistor a temperatura sobre pra 400 graus, o que pode ser???

      Excluir
  3. samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0; . O que representa o 5.0? e o o que representa o valor 1000? esse calculo serve para o t DS18B20(meu caso)?

    ResponderExcluir
    Respostas
    1. 5.0 é a voltagem de referência (5 volts), o 100.0 é utilizado para converter o valor do analogRead, que vem em milivolts. Para o DS18B20, eu recomendo a leitura do meu outro post :

      http://www.arduinoecia.com.br/2013/04/sensor-de-temperatura-ds18b20_11.html

      Abraços !

      Excluir
  4. e o 1024 é a variacao da tensao? 0 a 1023?

    ResponderExcluir
    Respostas
    1. 0 a 1023 é a faixa de valores lidos da porta analógica. Esse valor é gerado proporcionalmente ao valor de entrada. Por exemplo. Conecte um potenciômetro de qualquer valor à uma porta analógica. O potenciômetro na sua resistência mais baixa será interpretado pelo Arduino como valor 0, e sua resistência mais alta, como valor 1023.

      Abraço !

      Excluir
  5. samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0; . como seria o calculo se fosse o DS18B20? grato antecipadamente!

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Para o DS18B20, recomendo a leitura do artigo abaixo :

      http://www.arduinoecia.com.br/2013/04/sensor-de-temperatura-ds18b20_11.html

      Abraço !

      Excluir
  6. Parabéns pelo post , muito bom.
    Qual o calculo feito pra colocar o resistor de 10 k ?

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Sinceramente, não fiz nenhum cálculo complicado, foi tentativa e erro mesmo. O sensor estava apresentando erros estranhos na saída (marcava a temperatura correta, de repente "pulava" para 50, 60 graus), peguei a dica de um colega para ligar um resistor de 15 K no pino de dados do sensor. Coloquei um de 10K, e estabilizou, não tive mais problemas.

      Abraço e obrigado pela visita !

      Excluir
  7. Como faço para colocar um contador que quando a temperatura nesse mesmo programa passe de 25º + ele vai contando até acionar pela 3º fez a temperatura máxima o sistema desligue ou dê um reset.... pois dentro do loop não dá...

    ResponderExcluir
    Respostas
    1. Boa noite Jepherson,

      Creio que você consiga colocar dentro do loop sim. ficaria mais ou menos assim :

      if(tempc > 25)
      {
      digitalWrite(12, HIGH);
      digitalWrite(13, LOW);
      digitalWrite(11, LOW);
      contador = contado++; //Incrementa o contador
      if (contador == 3)
      {
      //Desliga portas
      }
      }

      Abraço !

      Excluir
  8. Boa noite amigão, parabens pelo posta, gostei do seu canal aqui, bem explicativo, mas tenho uma duvida, qual a temperatura maxima que o LM35 suporta? estou pensando em fazer o controle de uma laminadora no trampo que trabalha na temperatura de 99 a 104 aproximadamente, Muitissimo Obrigado desde já, abraços amigo =)

    ResponderExcluir
    Respostas
    1. Boa noite,

      O LM35 tem várias versões. o LM35 e LM35A, por exemplo, aceita de -55 a +150, o LM35C e o LM35CA, de -40 a +110, e o LM35D (um dos mais fáceis de encontrar), vai de 0 a 100.

      Você pode usar o LM35 sim, só fique atento à esses detalhes.

      Se precisar de mais informações sobre o LM35, pode consultar o datasheet nesse link :
      http://www.ti.com/lit/ds/symlink/lm35.pdf

      Abraços e obrigado por acompanhar o Arduino e Cia !

      Excluir
  9. boa tarde. Fiz tudo igualzinho e os leds não acendem. A temperatura ta marcando OK, mas os leds não !! Pode ajudar ?

    ResponderExcluir
    Respostas
    1. Boa tarde Ricardo,

      Por favor dê uma olhada no Serial Monitor, e veja se a temperatura está sendo mostrada corretamente. Se estiver, provavelmente é algum problema na ligação dos componentes.

      Abraço !

      Excluir
  10. Olá pessoal..... Eu, juntamente com mais alguns alunos e o professor de física da nossa escola de período integral estamos mexendo com arduino. Somos todos iniciantes mas estamos indo bem rsrsrs. Porém preciso de um código que está me deixando louco. Meu objetivo é fazer uma chocadeira, onde, dependendo da temperatura acende as luzes ou apaga. ( < 37 acende - > 38 apaga). os componentes que tenho são o sensor LM35 e um rele para acender as luzes. gostaria tambem que a temperatura aparecesse na LCD ( 16 x 2 ).

    Obrigado pessoal e parabéns pelos ótimos trabalhos.
    Helder

    ResponderExcluir
    Respostas
    1. Bom dia Helder !

      Obrigado por acompanhar o Arduino e Cia.

      Você pode juntar as informações desse post, em que eu mostro a temperatura em um display LCD 16x2 :

      http://www.arduinoecia.com.br/2013/03/display-lcd-16x2-e-sensor-de.html

      e esse outro, que mostro como acender uma lâmpada utilizando módulo relé :

      http://www.arduinoecia.com.br/2013/02/ligando-uma-lampada-com-rele.html

      Isso deve te ajudar por enquanto. Se precisar de mais informações ou dicas, entre em contato. :-)

      Abraço !

      Excluir
    2. Boa Tarde arduino e cia. Os posts ajudaram bastante... resolveu a maioria de meus problemas... Porem ainda não estou conseguindo fazer a parte da lampada. mudei algumas coisas que eram desnecessárias para mim mas funcionou tudo perfeitamente....
      Segue o código:

      #include

      // Pino analogico para ligacao do LM35
      int pin = 0;
      int sinalparaorele = 7;

      // Variaveis que armazenam a temperatura em Celsius e Fahrenheit
      int tempc = 0,tempf=0;

      // Array para precisão na medição
      int samples[8];
      int i;

      //Define os pinos que serão ligados ao LCD
      LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


      void setup()
      {
      Serial.begin(9600); // Inicializa comunicação serial
      pinMode(sinalparaorele, OUTPUT); //Define o pino como saida
      }

      void loop()
      {
      // Loop que faz a leitura da temperatura 8 vezes
      for(i = 0;i<=7;i++)
      {
      samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
      //A cada leitura, incrementa o valor da variavel tempc
      tempc = tempc + samples[i];
      delay(100);
      }

      // Divide a variavel tempc por 8, para obter precisão na medição
      tempc = tempc/8.0;

      //Converte a temperatura em Fahrenheit e armazena na variável tempf
      tempf = (tempc * 9)/ 5 + 32;



      //As linhas abaixo escrevem o valor da temperatura na saída serial
      Serial.print(tempc,DEC);
      Serial.print(" Celsius, ");
      Serial.print(tempf,DEC);
      Serial.println(" fahrenheit ");

      delay(100);
      lcd.begin(16, 2); //Inicia o LCD com dimensões 16x2(Colunas x Linhas)
      lcd.setCursor(0, 0); //Posiciona o cursor na primeira coluna(0) e na primeira linha(0) do LCD
      lcd.print("TemperaturaC =!"); //Escreve no LCD temperaturac ="
      lcd.print(tempc);
      lcd.setCursor(0, 1); //Posiciona o cursor na primeira coluna(0) e na segunda linha(1) do LCD
      lcd.print("TemperaturaF ="); //Escreve no LCD "temperaturaf ="
      lcd.print(tempf);

      tempc=0;

      if(tempc < 37)
      {
      digitalWrite(sinalparaorele, HIGH); //Aciona o rele
      }
      else
      {
      digitalWrite(sinalparaorele, LOW); //Desliga o rele
      }
      }

      Bem.... a temperatura e o lcd rodam perfeitamente apesar que algumas vezes da algum problema por mal contato.... porém a lampada com o rele não esta funcionando.

      Abraços e obrigado pela ajuda. =)

      Excluir
  11. Ola, liguei o LM35 direto no arduino e tambem usando o esquema seu, mas em ambos a leitura do analogRead(0) eh sempre 835, mesmo colocando o sensor ao lado da saida de ar quente do notebook ou encostando em uma superficie gelada a leitura nunca muda. Quando retiro o cabo de sinal da porta 0 a leitura muda pra 1023. Estou fazendo algo errado?

    Grato.

    ResponderExcluir
    Respostas
    1. Boa tarde Luciano,

      Tente incluir a linha pinMode(pin, INPUT) no setup, por favor. Talvez faça diferença no seu caso.

      Abraço !

      Excluir
    2. Coloquei pinMode(A0, INPUT) no setup e continua no mesmo.
      Outra coisa q fiz foi inverter o GND e o Vout, entao o analogRead comecou a retornar valores diferentes conforme a mudanca de temperatura, mas a temperatura em vez de aumentar com o calor, ela diminui.

      Excluir
    3. Boa noite Luciano,

      Entendi. Eu só não recomendo inverter a alimentação, pois queimei um LM35 assim....

      A ligação não tem muito segredo, logo não vejo outra opção senão testar com outro sensor, para ver se o problema persiste.

      Abraço !

      Excluir
  12. Olá, existe a possibilidade de você fazer um exemplo com o DS18B20, acionando relé ao invés de led?
    Infelizmente a página http://www.arduinoecia.com.br/2013/04/sensor-de-temperatura-ds18b20_11.html não existe mais.
    Fiz este código abaixo, infelizmente o relé fica direto ligado.
    #include
    #include
    // Utilizar resistror de 10K
    int DS18S20_Pin = 2; //DS18S20 Sinal digital na porta 2
    int relePin = 7;

    float temperature;
    float maxtemp = 30;
    float folga = 0.5;


    //Temperatura chip i/o
    OneWire ds(DS18S20_Pin); // on ligada porta digital pin 2


    void setup(void) {
    Serial.begin(9600);
    pinMode(relePin,OUTPUT);

    }

    void loop(void) {

    float temperature = getTemp();


    if (temperature > maxtemp + folga)
    {
    digitalWrite(relePin,LOW);
    }
    if (temperature < maxtemp - folga)
    {
    digitalWrite(relePin,HIGH);
    }
    Serial.println(temperature);
    delay(1000);
    }






    float getTemp(){
    //returns the temperature from one DS18S20 in DEG Celsius

    byte data[12];
    byte addr[8];

    if ( !ds.search(addr)) {
    //no more sensors on chain, reset search
    ds.reset_search();
    return -1000;
    }

    if ( OneWire::crc8( addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return -1000;
    }

    if ( addr[0] != 0x10 && addr[0] != 0x28) {
    Serial.print("Device is not recognized");
    return -1000;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44,1); // start conversion, with parasite power on at the end

    byte present = ds.reset();
    ds.select(addr);
    ds.write(0xBE); // Read Scratchpad


    for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
    }

    ds.reset_search();

    byte MSB = data[1];
    byte LSB = data[0];

    float tempRead = ((MSB << 8) | LSB); //using two's compliment
    float TemperatureSum = tempRead / 16;

    return TemperatureSum;

    }

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Vou tentar, é que no momento estou sem DS18B20 e sem relé, mas deve chegar em breve.

      Quanto à página, eu consegui acessar normalmente por aqui.

      Abraço!

      Excluir
  13. Como posso fazer para que o programa análise durante 1 minuto toda a temperatura do sensor é caso haja uma variação de mais 6 graus em 1 minuto ele faça tal
    Comando que eu definir ? Agradeço ae puderam me ajudar.

    ResponderExcluir
  14. Olá.

    Copie seu sketch e montagem do circuíto, mas acrescentei o pino 8 e 9 para uma sheld com 02 relês. Porém, a "temperatura" fica oscilando três graus. Fazendo com que o relês e led's fiquem instáveis.
    Quando retiro a sheld dos relês, volta tudo ao normal.
    Medi a tenção no protoboard, e constatei que quando a shield dos relê é acionada, a tenção caí.
    Como posso solucionar isso.



    }

    void loop()
    {
    for(i = 0;i<=7;i++){ // Loop que faz a leitura da temperatura 8 vezes
    samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
    //A cada leitura, incrementa o valor da variavel tempc
    tempc = tempc + samples[i];
    delay(100);
    }

    // Divide a variavel tempc por 8, para obter precisão na medição
    tempc = tempc/8.0;
    //Converte a temperatura em Fahrenheit e armazena na variável tempf
    tempf = (tempc * 9)/ 5 + 32;
    //Armazena a temperatura máxima na variável maxtemp
    if(tempc > maxtemp) {maxtemp = tempc;}
    //Armazena a temperatura máxima na vari[avel mintemp
    if(tempc < mintemp) {mintemp = tempc;}

    //Se a temperatura estiver abaixo de 15, acende o led verde + relê 02
    if(tempc < 15)
    {
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(8, HIGH);
    digitalWrite(9, LOW);
    }

    //Se a temperatura estiver acima de 28, acende o led vermelho + relê 01
    if(tempc > 28)
    {
    digitalWrite(12, HIGH);
    digitalWrite(13, LOW);
    digitalWrite(11, LOW);
    digitalWrite(9, HIGH);
    digitalWrite(8, LOW);
    }

    //Se a temperatura estiver acima de 15 e abaixo de 28, acende o led amarelo
    if((tempc > 15) && (tempc < 28))
    {
    digitalWrite(11, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    }

    // As linhas abaixo enviam para o monitor serial a temperatura em
    // Celsius e Fahrenheit,
    // e também as temperaturas máxima e mínima registradas

    Serial.print(tempc,DEC);
    Serial.print(" Cels., ");
    Serial.print(tempf,DEC);
    Serial.print(" Fahr. -> ");
    Serial.print(" Min : ");
    Serial.print(mintemp,DEC);
    Serial.print(" Max: ");
    Serial.println(maxtemp,DEC);

    tempc = 0;
    delay(1000); // Aguarda 1 segundo e reinicia o processo
    }

    ResponderExcluir
    Respostas
    1. Bom dia Matheus,

      Uma opção é você utilizar alimentação externa para os relés. Pelo jeito, está sobrecarregando o Arduino.

      Abraço!

      Excluir
  15. ola
    como posso fazer esse programa com um sensor NTC, eu inclui a biblioteca do thermistor , mas a temperatura nao mostra em graus celsius, conforme abaixo:
    209 Cels., 408 Fahr. -> Min : 100 Max: 209
    209 Cels., 408 Fahr. -> Min : 100 Max: 209

    o que preciso alterar ?

    grato

    ResponderExcluir
  16. Boa tarde.
    Como seria o programa se fosse com 2 LM35?
    Poderiam me ajudar?

    ResponderExcluir
  17. Boa tarde.
    Seu termistor é de 5K ou 10K?

    ResponderExcluir
  18. Tendo em vista uma programação parecida, pode-se colocar o sensor em qualquer entrada analógica do Arduino sem que a mesma seja mencionada na programação?

    ResponderExcluir
    Respostas
    1. Oi Mariana,

      Você precisa definir no programa em qual porta analógica o sensor será conectado.

      Abraço!

      Excluir
  19. Olá! estou com problemas em relação a temperatura lida pelo sensor, não sei por que, mas ela fica numa faixa de 150 a 500°C, já tentei programas diferentes e tudo mais, porém nada mudou, alguém poderia me ajudar?? Desde já eu agradeço!!

    ResponderExcluir
  20. Não deu certo.

    Com o resistor de 10K fica assim:

    0 Cels., 32 Fahr. -> Min : 0 Max: 499
    0 Cels., 32 Fahr. -> Min : 0 Max: 499
    0 Cels., 32 Fahr. -> Min : 0 Max: 499
    0 Cels., 32 Fahr. -> Min : 0 Max: 499
    0 Cels., 32 Fahr. -> Min : 0 Max: 499
    0 Cels., 32 Fahr. -> Min : 0 Max: 499

    Sem o resistor aparecem medidas "aleatórias":

    356 Cels., 672 Fahr. -> Min : 0 Max: 495
    0 Cels., 32 Fahr. -> Min : 0 Max: 495
    57 Cels., 134 Fahr. -> Min : 0 Max: 495
    499 Cels., 930 Fahr. -> Min : 0 Max: 499
    67 Cels., 152 Fahr. -> Min : 0 Max: 499
    1 Cels., 33 Fahr. -> Min : 0 Max: 499
    343 Cels., 649 Fahr. -> Min : 0 Max: 499
    401 Cels., 753 Fahr. -> Min : 0 Max: 499
    0 Cels., 32 Fahr. -> Min : 0 Max: 499

    ResponderExcluir
  21. Arduino e Cia, obrigada por compartilhar! Usei este código e no meu caso funcionou perfeitamente :)

    ResponderExcluir
    Respostas
    1. Oi Celia,

      Obrigado pelo retorno. Aguardo sua visita sempre que possível. :)

      Abraço!

      Excluir