/*
 * Thermometerlm35.pde - read temperature using an LM35 sensor 
 * and display it on a PCD8544 LCD.
 * Copyright (c) 2010 Carlos Rodrigues <cefrodrigues@gmail.com>
 *
 * https://code.google.com/p/pcd8544/source/browse/trunk/examples/Thermometer/Thermometer.ino
 * 
 * Se concede permiso, de forma gratuita, a cualquier persona que obtenga una copia 
 * de este software y archivos de documentación asociados (el "Software"), para tratar 
 * el Software sin restricción, incluyendo sin limitación, los derechos para usar, 
 * copiar , modificar, fusionar, publicar, distribuir, sublicenciar y / o vender 
 * copias del Software, y para permitir a las personas a las que el Software 
 * suministra a hacerlo, con sujeción a las siguientes condiciones:
 *
 * El aviso de copyright anterior y este aviso de permiso se incluirán en 
 * todas las copias o partes sustanciales del Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Modified by V. García for hispavila.com
 * Funciona espectacular 02/07/13
 */

#include "PCD8544.h"

int analogPin = 0;
float temperature = 0.0;
int grados, decimas, gradR, deciR;
int lm35read, tmedia;
int val,cnt;

static const byte sensorPin = 0;
static const byte ledPin = 13;

// The dimensions of the LCD (in pixels)...
static const byte LCD_WIDTH = 96;
static const byte LCD_HEIGHT = 48;

// The number of lines for the temperature chart...
static const byte CHART_HEIGHT = 5;

// A custom "degrees" symbol...
static const byte DEGREES_CHAR = 1;
static const byte degrees_glyph[] = { 0x00, 0x07, 0x05, 0x07, 0x00 };

// A bitmap graphic (10x2) of a thermometer...
static const byte THERMO_WIDTH = 10;
static const byte THERMO_HEIGHT = 2;
static const byte thermometer[] = { 0x00, 0x00, 0x48, 0xfe, 0x01, 0xfe, 0x00, 0x02, 0x05, 0x02,
                                    0x00, 0x00, 0x62, 0xff, 0xfe, 0xff, 0x60, 0x00, 0x00, 0x00};

static PCD8544 lcd;


void setup() {
  Serial.begin(9600);  
  
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
    lcd.clear();  
  // Register the custom symbol...
  lcd.createChar(DEGREES_CHAR, degrees_glyph);
  
  pinMode(ledPin, OUTPUT);

// La referencia 1.1 V interno proporciona una mejor
// Resolución del LM35, y también es más estable
// Cuando se alimenta de una batería o USB ...
  analogReference(INTERNAL);
    lcd.clear(); 
}


void loop() {
      // inicializamos el valor de tmedia
    tmedia=0;
    
    // medimos la temperatura 10 veces y la almacenamos en tmedia
    for ( cnt=0; cnt<20; cnt++)  {
      lm35read = analogRead(sensorPin);      
      tmedia=tmedia+lm35read;
    }
    
    // calculamos la media de las medidas
    tmedia=tmedia/cnt; 
    
    // convertimos tmedia en un valor en grados, pero
    // dadas las caracteristicas del sensor la precision es de 
    // 0.5 grados y los decimales son .4 o .9
     temperature = (1.1 * tmedia * 100.0)/1024.0;
       
    // mapeamos el valor tmedia para que nos de
    // la temperatura en decimas de grado
    val = map(tmedia,0,1023,0,4990);
    
    // ahora los grados los obtenemos dividiendo por 10
    grados=val/10;
    
    // y las decimas de grado son el resto de la division
    // por 10
    decimas=val%10;
    
    // Redondeamos los decimales a 0 o a 5
    if (decimas< 3)  {
         gradR=grados;
         deciR=0;
       }
    if ((decimas > 2)&(decimas<7)) {
         gradR=grados;
         deciR=5;
       }
     else {
         gradR=grados+1;
         deciR=0;
       } 
       
    Serial.print("Lectura en bruto ");
    Serial.print(lm35read);   
    Serial.print("  temp. sin redondear  ");
    Serial.print(temperature);    
    Serial.print(" temp. redondeada ");
    Serial.print(grados);
    Serial.print(".");
    Serial.print(deciR);     Serial.print(" ");
    Serial.println(val/10);    

  // Inicio más allá del borde de la pantalla ...
  static byte xChart = LCD_WIDTH;
  
  digitalWrite(ledPin, HIGH);

  // Read the temperature (in celsius)... NO USADO
  //Imprimir la temperatura (utilizando el símbolo personalizado "grados") ...  
 
  lcd.setCursor(6, 0);
  lcd.print("Temperatura ");
  lcd.setCursor(0, 1);  
  lcd.print("Ambiente  LM35");  
  lcd.setCursor(24, 3);
  lcd.print(temperature, 2);
  lcd.print(" \001C ");  
  lcd.setCursor(24, 4); 

  lcd.print(((temperature*9)/5)+32, 2);  
  lcd.print(" \001F      ");

  lcd.setCursor(0, 5); 
  lcd.print("hispavila.com ");  
 
  // Draw the thermometer bitmap at the bottom left corner...
  lcd.setCursor(3, 1+(LCD_HEIGHT/8 - THERMO_HEIGHT)/2);
  lcd.drawBitmap(thermometer, THERMO_WIDTH, THERMO_HEIGHT);

  // Ajustar la posición actual del gráfico ...
  if (xChart >= LCD_WIDTH) {
    xChart = THERMO_WIDTH + 2;
   
  }

  //Actualización de la tabla de temperaturas ...  
  lcd.setCursor(xChart, 2);

  xChart++;

  digitalWrite(ledPin, LOW);  
  delay(500);
}


/* EOF - Thermometerlm35.pde  */

