///       (o\---/o)           
//        ( , , )
// ___,--.(_(Y)_),--.____
//|   "--"       "--"    |
//| Don't Worry Be Happy |
//| HECTOR E. VILLARREAL |
//|         2023         |
//|______________________|
//       )   |   (
//      (___,'.___) 
//Lectura de temperatura de dos Dallas DS18B20 ver 1.01 29-12 23
//Copyright (C) 2023, Héctor Villarreal
//---------------------------------------------------------------------------------------------------
//Librerias
//--------------------------------------------------------------
#include <LiquidCrystal.h>
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 6                       //Se establece el pin 6  como bus OneWire
#define TEMPERATURE_PRECISION 12             // Maxima resolución 12 bits (entre 9 y 12 bits)

//Set LCD Arduino Nano
LiquidCrystal lcd(A5, A4, A3, A2, A1, A0);  // Corresponde a (RS, EN, D4, D5, D6, D7)
int pinLed= 5;                              //Pin para el led de error

OneWire oneWire(ONE_WIRE_BUS);        /* Setup a oneWire instance to communicate with any OneWire devices 
                                         (not just Maxim/Dallas temperature ICs)*/
DallasTemperature sensors(&oneWire);  //Se declara una variable u objeto para nuestro sensor
int numberOfDevices = 0; 
byte address[8];                 // variable que almacena la cantidad de dispositivos en el wire
DeviceAddress tempDeviceAddress;      // variable para address de despositivos encontrados
long value0 = 1960090501;             // Constante ID del dispositivo
volatile int tempC = 0;
int device = 0;                       // variable auxiliar
//------------------------------------------------------------------------------------------------------
//INICIALIZACION y CONFIGURACION del sistema
//------------------------------------------------------------------------------------------------------
void setup(void) {
  sensors.begin();
  Serial.begin(115200);     // inicializo el puerto serie
  pinMode(pinLed, OUTPUT);     //Pin del led modo salida
  digitalWrite(pinLed, HIGH);  //Me aseguro que esté apagado el led de error
//--------------------------------------------------------------
  #include "mensaje_inicio.h" //Mensaje de inicio en LCD
//--------------------------------------------------------------
 
  Serial.println("Dallas DS18B20 Control v.1.0");
  numberOfDevices = sensors.getDeviceCount();  // almacena la cantidad de dispositivos en el wire
  Serial.print("Locating devices...");   // Buscando ... dispositivos en el bus
  Serial.print("Found ");
  Serial.print(numberOfDevices, DEC);
  if ((numberOfDevices)== 0) {
      digitalWrite(pinLed, LOW);
      lcd.clear();
      lcd.setCursor(0, 0);                      // Selecciono la Primera linea
      lcd.print("Error:3 not read");            // escribimos en la primera linea ERROR 3
      delay(1000);
      lcd.setCursor(0, 2);
      String message = "Dallas no found!";      //mensaje error Dallas no encontrada
      for (byte i = 0; i < message.length(); i++) {
          lcd.print(message[i]);
          delay(100);
      }
    while ( true );                            //detiene el programa por error de dallas
  }
  Serial.println(" devices.");
  for (int i = 0; i < numberOfDevices; i++) { // Loop through each device, print out address
   // Search the wire for address
   device= i;
    if (sensors.getAddress(tempDeviceAddress, i)) {
      Serial.print("Found device ");
      Serial.print(i, DEC);
      Serial.print(" with address: ");
      printAddress(tempDeviceAddress);
      Serial.println();
      sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);  // set the resolution to TEMPERATURE_PRECISION bit 
      //(Each Dallas/Maxim device is capable of several different resolutions)//
      Serial.print("Resolution set to: ");
      Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
      Serial.println();
    } 
    else {
      Serial.print("Found ghost device at ");
      Serial.print(i, DEC);
      Serial.print(" but could not detect address. Check power and cabling");
      digitalWrite(pinLed, LOW); //led error, dirección no encontrada
      lcd.clear();
      lcd.setCursor(0, 0); // Selecciono la Primera linea
      lcd.print("Error:4 not read"); // escribimos en la primera linea error 4
      delay(1000);
      lcd.setCursor(0, 2);
      String message = "Address no found!";      //mensaje error dirección no encontrada
      for (byte i = 0; i < message.length(); i++) {
            lcd.print(message[i]);
            delay(100);
       }
    }
  }
  lcd.clear();
  lcd.setCursor(0, 0); // Selecciono la Primera linea
  lcd.print("Found devices: ");
  lcd.print (sensors.getDeviceCount());
  lcd.setCursor(0, 1);
  lcd.print("Dallas DS18B20");
 }
//-----------------------------------------------------------------------------------------------
//Programa a ejecutar LOOP
//-----------------------------------------------------------------------------------------------
void loop(void)  {
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  sensors.requestTemperatures(); // Send the command to get temperatures
 
  for (int i = 0; i < numberOfDevices; i++) {       // Loop through each device, print out temperature data
    if (sensors.getAddress(tempDeviceAddress, i)) { // Search the wire for address
  // It responds almost immediately. Let's print out the data
      printTemperature(tempDeviceAddress);          // Use a simple function to print out the data
    }
    else  { 
      error1();
    }
  }
  delay(1000);
}
//-----------------------------------------------------------------------------------------------
//Anexo - FUNCIONES a usar
//-----------------------------------------------------------------------------------------------
//Función para presentar la dirección del dispositivo
//--------------------------------------------------------------
void printAddress(DeviceAddress deviceAddress) {   // function to print a device address
  for (uint8_t i = 0; i < 8; i++) {
      if (deviceAddress[i] < 16) Serial.print("0");
      Serial.print(deviceAddress[i], HEX);
  }
}
//-----------------------------------------------------------------------------------------------
//Función para presentar error 1
//--------------------------------------------------------------
void error1() {   // function to print error1
  Serial.println(" Error:1 ghost device! Check your power requirements and cabling ");
  digitalWrite(pinLed, LOW);
  lcd.clear();
  lcd.setCursor(0, 0);            // Selecciono la Primera linea
  lcd.print("Error:1 not read"); // escribimos en la primera linea Error 1
  delay(1000);
  lcd.setCursor(0, 2);
  String message = "Check cabling!";
  for (byte i = 0; i < message.length(); i++) {
    lcd.print(message[i]);
    delay(100);
  } 
}
//--------------------------------------------------------------
//Función para presentar la Temperatura del dispositivo
//--------------------------------------------------------------
void printTemperature(DeviceAddress deviceAddress) {   // function to print the temperature for a device
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == DEVICE_DISCONNECTED_C){
      Serial.println("Error:2 Could not read temperature data");
      digitalWrite(pinLed, LOW);
      lcd.clear();
      lcd.setCursor(0, 0); // Selecciono la Primera linea
      lcd.print("Error:2 not read"); // escribimos en la primera linea
      delay(1000);
      lcd.setCursor(0, 2);
      String message = "Out of range!"; //mensaje error fuera de rango
      for (byte i = 0; i < message.length(); i++) {
            lcd.print(message[i]);
            delay(100);
       }
     return;
  }
  digitalWrite(pinLed, HIGH);  // no error led apagado
//--------------------------------------------------------------
 int num= device++;
// Envía DATOS al puerto serie
 Serial.print("Sonda");
 Serial.print(num, DEC);
 Serial.print("= ");
 Serial.print("Temp. ");
 Serial.print(tempC);
 Serial.println (" °C");
//--------------------------------------------------------------
// Envía DATOS al lcd
 lcd.clear();
 lcd.setCursor(0, 0); // Selecciono la Primera linea
 lcd.print("Contr.Temp v 1.0"); // escribimos en la primera linea
 lcd.setCursor(0, 1);
 lcd.print("T");
 lcd.print(num, DEC);
 lcd.print("= ");
 lcd.print(tempC);
 lcd.setCursor(11, 1);
 lcd.print((char)223);
 lcd.print("C");
 if (device >numberOfDevices) device = 1;
 delay(2000);
}

//--------------------------------------------------------------
Temp 1
Temp 2
Temp 3
Temp 4