Chocadeira com Arduino

Abaixo um projeto interessante para a confecção de uma chocadeira controlada por meio do arduino. O conteúdo e a fonte de busca estão citadas ao centro da postagem.

/*
   Nome do Projeto:  Chocadeira
   Nome do Aquivo:   Choca_DS18b20_V02.ino
   Dependencias:     OneWire.h          Biblioteca de 1Wire
                     LiquidCrystal.h    Biblioteca de LCD
   MCU:              ATmega
   Board:            Arduino Uno/Mega/Mini
   Compilador        N/A
   IDE:              Arduino IDE 1.0.6
   Hardware:         Arduino UNO/MEGA/Mini
   Escrito por:      Rui Viana
   Data:             27/06/2015
   Uso:              Didático
   Desenhos          Chocadeira.jpg
   Copyright @       N/A
   
   Este programa é software livre;
   E é distribuído na esperança que possa ser útil, mas SEM QUALQUER GARANTIA; mesmo sem a garantia implícita de COMERCIALIZAÇÃO ou ADEQUAÇÃO A UM DETERMINADO FIM.
   A parte do tratamento de 1Wire deste código foi copiada do exemplo da biblioteca OneWire.h.
   
   REVISIONS: (latest entry first)  
   2015-06-26   -   Choca_DS18b20_V02.ino - First release
   2015-06-28   -   Choca_DS18b20_V02.ino - Adicao de LDC   
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Descricão:  
   
   Este código utiliza a biblioteca OneWire.h para ler sensores de temperatura.
   E a biblioteca LiquidCrystal.h para mostrar a temperatura no diplsy LCD
   Converte o valor lido para oC, e mostra em um diplay LCD.
   Compara o valor da leitura com o valor programado, e define se liga ou desliga o rele que alimenta as resistencias de aquecimento.
   Tem dois botoes, um para aumentar e outro para diminuir a programação da temperatura 
*/
//************  Variaveis e constantes  ************ 
  #include <OneWire.h>                          // Biblioteca de 1Wire
  #include <LiquidCrystal.h>                    // Inclui a biblioteca do LCD
  OneWire  ds(5);                               // Seleciona a porta do 1WirwBus on pin 10
  LiquidCrystal lcd( 7,  8,  9, 10, 11, 12);    // Pinos do LCD
  const int Rele = 13;                          // Pino de Saída
  const int Up = 2;                             // Pino do switch  de Up   
  const int Dn = 3;                             // Pino do switch  de Dn     
  float TempProg = 27;                          // Variavel com temperatura programada  
  long debouncing_time = 15;                    // Debouncing Time in Milliseconds
  volatile unsigned long last_micros;           // Variavel para deboucing
//***********************  Setup *******************  
  void setup()
  {
    lcd.begin(16, 2);                            // Inicia o LCD com dimensões 16x2(Colunas x Linhas)
    pinMode(Rele, OUTPUT);                       // Port como saída
    digitalWrite(Rele, LOW);                     // Desliga Rele   
    pinMode(Up, INPUT_PULLUP);                   // Port do switch Up como entrada e Pull-Up  
    pinMode(Dn, INPUT_PULLUP);                   // Port do switch Dn como entrada e Pull-Up         
    delay(1000);                                 // Aguarda 1 seg antes de acessar as informações do sensor
    attachInterrupt(1, PressUp, RISING);         // Interrupt de botão ao ficar HIGH o pino 3
    attachInterrupt(0, PressDn, RISING);         // Interrupt de botão ao ficar HIGH o pino 2

    lcd.clear();                                 // Limpa do buffer do LCD
    lcd.setCursor(3, 0);                         // Seleciona posição 0 da linha 0
    lcd.print("Chocadeira");                     // Imprime texto
    lcd.setCursor(11, 1);                        // Seleciona posição 0 da linha 0
    lcd.print(TempProg);                         // Imprime variavel
  }
//***************  Rotina PressUp ***************** 
  void PressUp()                                 // Rotina chamada pela interrupcao do botão de aumento
  {
    if((long)(micros() - last_micros) >= debouncing_time * 1000)   // Tempo de debouncing
    {
      TempProg = TempProg + 0.1;                  // Incrementa temperatura em 0,01 oC
      lcd.setCursor(11, 1);                       // Seleciona posição 0 da linha 0
      lcd.print(TempProg);                        // Imprime variavel
      last_micros = micros();                     // Tempo de debouncing 
    }
  }
//***************  Rotina PressDn ***************** 
  void PressDn()                                 // Rotina chamada pela interrupcao do botão de reducao 
  {
    if((long)(micros() - last_micros) >= debouncing_time * 1000)   // Tempo de debouncing 
    {
      TempProg = TempProg - 0.1;                  // Decrementa temperatura em 0,01 oC
      lcd.setCursor(11, 1);                       // Seleciona posição 0 da linha 0
      lcd.print(TempProg);                        // Imprime variavel      
      last_micros = micros();                     // Tempo de debouncing 
    }
  }
//***********************  Loop ******************** 
  void loop()
  {  
    byte i;                                    // Variavel de uso geral
    byte present = 0;                          // Variavel para present bit do 1Wire
    byte type_s;                               // Variavel para selecionar o tipo de Sensor
    byte data[12];                             // Matriz para guardar os dados lidos do sensor
    byte addr[8];                              // Matriz para guardar endereço lidos do sensor
    float celsius;                             // Variavel para guardar o valor das temperutras  
    if ( !ds.search(addr))                     // Search for the next device.
    {
      ds.reset_search();                       // Begin a new search.
      delay(250);
      return;
    }
    if (OneWire::crc8(addr, 7) != addr[7])     // Verifica o CRC
    {
      return;
    }
    switch (addr[0])                           // Le o byte 0 da ROM
    {
      case 0x10:                               // Se for 0x10
        type_s = 1;                            // Set tipo = 1
        break;
      case 0x28:                               // Se for 0x28
        type_s = 0;                            // Set tipo = 0
        break;
      default:
        return;
    }
    ds.reset();                                // Reset the 1-wire bus.
    ds.select(addr);                           // Select a device based on its address.
    ds.write(0x44,1);                          // start conversion, with parasite power on at the end
    delay(1000);                               // maybe 750ms is enough, maybe not
    present = ds.reset();                      // Reset the 1-wire bus. e agurada o Present Pulse
    ds.select(addr);                           // Select a device based on its address.    
    ds.write(0xBE);                            // Read Scratchpad
   
    for ( i = 0; i < 9; i++)                   // le os 8 bytes de dados
    {           
      data[i] = ds.read();                     // Read a byte
    }
    unsigned int raw = (data[1] << 8) | data[0]; // Função raw  Shift Data[1] 8 bits
                                               //   e faz or com data[0]
    if (type_s) 
    {
      raw = raw << 3;                          // 9 bit resolution default
      if (data[7] == 0x10) 
      {
        raw = (raw & 0xFFF0) + 12 - data[6];   // count remain gives full 12 bit resolution
      }
    }
    else 
    {
      byte cfg = (data[4] & 0x60);
      if (cfg == 0x00) raw = raw << 3;        // 9 bit resolution, 93.75 ms
      else if (cfg == 0x20) raw = raw << 2;   // 10 bit res, 187.5 ms
      else if (cfg == 0x40) raw = raw << 1;   // 11 bit res, 375 ms
      // default is 12 bit resolution, 750 ms conversion time
    }
    celsius = (float)raw / 16.0;
    if (celsius >= TempProg)
     digitalWrite(Rele, LOW);                // Desliga Rele como entrada e Pull-Up  
    else
      digitalWrite(Rele, HIGH);                // Liga Rele  como entrada e Pull-Up   
    lcd.setCursor(0, 1);                     // Seleciona posição 0 da linha 0                        
    lcd.print(celsius);                      // Imprime texto
    lcd.setCursor(6, 1);                     // Seleciona posição 0 da linha 0                        
    if (digitalRead(Rele) == 1)
      lcd.print("Lig ");                       // Imprime texto
    else
      lcd.print("Desl");                       // Imprime texto
    //Não diminuir o valor abaixo. O ideal é a leitura a cada 2 segundos
    delay(2000);
  }

Fontes de busca:
http://pastebin.com/y2gUEgRk
http://labdegaragem.com/forum/topics/chocadeira?id=6223006%3ATopic%3A453089&page=1#comments
https://pastebin.com/u/RuiViana