// DATALOGGER ATTiny85 TECSO
/* Medición y archivamiento de datos relativos a la temperatura
de un sistema junto a la fecha y hora de medición.*/
// Uso de un DHT22 con MISO en PB5
// Uso de un RTC DS1307 configurado en I2C
#include <TinyDebug.h>
#include <TinyWireM.h>
#include <dht.h>
#include <TinyRTClib.h>
// DHT
#define DHT22_PIN PB5
dht DHT;
// RTC
char diaSemana[7][4] = {"DOM", "LUN", "MAR", "MIE", "JUE", "VIE", "SAB"};
char mesAnual[13][4] = {"NAN", "ENE", "FEB", "MAR", "ABR", "MAY", "JUN", "JUL", "AGO", "SEP", "OCT", "NOV", "DIC"};
RTC_DS1307 rtc;
// LED
#define LEDY_PIN PB4
#define LEDR_PIN PB3
// VARIABLES GLOBALES
// Millis
unsigned long millisOutput = 0;
unsigned long millisAudit = 0;
unsigned long millisLEDY = 0;
unsigned long millisLEDR = 0;
unsigned long millisCurrent = 0;
// Control
int firstTry = HIGH;
// Magnitudes
float Tem_Cels = 21;
DateTime now = DateTime(0, 0, 0, 0, 0, 0);
// Banderas
int ledR = LOW;
void setup() {
// Debug monitor
Debug.begin();
Debug.println("INICIO DE ATtiny.\n");
// DDR setup
pinMode(DHT22_PIN, INPUT);
pinMode(LEDY_PIN, OUTPUT);
pinMode(LEDR_PIN, OUTPUT);
// Encendido de periféricos
TinyWireM.begin();
rtc.begin();
// Variables de control
firstTry = HIGH;
if (! rtc.isrunning()) {
Debug.println("\nEl RTC no está en funcionamiento.");
delay(1000);
return;
}
}
void loop() {
millisCurrent = millis();
if(millisCurrent > millisLEDR){
ledR = !ledR;
digitalWrite(LEDR_PIN, ledR);
millisLEDR = millisCurrent + 512;
}
// VERIFICAR FUNCIONAMIENTO (Control interno)
if(millisCurrent > millisAudit){
if (! rtc.isrunning()) {
Debug.print("\nEl RTC no está en funcionamiento.");
delay(1000);
return;
}
if(isnan(Tem_Cels)){
Debug.println("\n Error al medir en el DHT.");
delay(1000);
return;
}
millisAudit = millisCurrent + 1024;
}
// SECUENCIA DE PRIMER VUELTA
/* Durante el funcionamiento habitual del sistema, elijo
utilizar siempre el dato de la vuelta anterior. De esta
forma, no necesito usar la función delay y puedo usar todos
los periféricos simultáneamente, teniendo un control más
manual del tiempo que dejo pasar entre la petición de una
señal y el uso de su respuesta. Por ejemplo, así el sistema
permite una diferencia en el tiempo de respuesta para
situaciones de control que para situaciones de archivo
(que tiene una exigencia varios órdenes de magnitud inferior).
Por eso, en la primer vuelta necesito pedir los datos de forma
diferente, ya que no hay una vuelta anterior. */
if(firstTry){
DHT.read22(DHT22_PIN);
millisOutput = millisCurrent + 512;
firstTry = LOW;
}
// USO DEL DHT
/* Primero usa el dato que le pidió al DHT hace 512 ms
Luego, le pide al DHT renovar el dato.
Esto lo hago porque el DHT tarda aproximadamente 256 ms
en tener el dato correcto, por lo que es necesario dejar
pasar tiempo desde el inicio de la anterior lectura. */
// USO DEL RTC (SECUENCIA DE ARCHIVAMIENTO)
/* Como el RTC no tiene una función de control importante
de momento, no me parece necesario tener su dato actualizado
lo antes posible. Es preferible ahorrar memoria y llamarlo
solo en la secuencia de archivamiento.*/
if(millisCurrent > millisOutput){
Tem_Cels = DHT.temperature;
DHT.read22(DHT22_PIN);
DateTime now = rtc.now();
Debug.print("\nT = ");
Debug.print(Tem_Cels);
Debug.print(" | ");
Debug.print(diaSemana[now.dayOfWeek()]);
Debug.print(", ");
Debug.print(now.day());
Debug.print(" de ");
Debug.print(mesAnual[now.month()]);
Debug.print(" del ");
Debug.print(now.year());
Debug.print(". ");
Debug.print(now.hour());
Debug.print(':');
Debug.print(now.minute());
Debug.print(':');
Debug.print(now.second());
Debug.println();
millisOutput = millisCurrent + 4096;
digitalWrite(LEDY_PIN, HIGH);
millisLEDY = millisCurrent + 512;
}
if(millisCurrent > millisLEDY) digitalWrite(LEDY_PIN, LOW);
}