// 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
unsigned long DHTMillis = 0;
dht DHT;
// RTC
char diaSemana[7][4] = {"DOM", "LUN", "MAR", "MIE", "JUE", "VIE", "SAB"};
char mesAnual[12][4] = {"ENE", "FEB", "MAR", "ABR", "MAY", "JUN", "JUL", "AGO", "SEP", "OCT", "NOV", "DIC"};
RTC_DS1307 rtc;
// SD
#define CS_PIN PB4
// VARIABLES GLOBALES
// Condiciones de compilación
#define SDCARD_ONLY
// Millis
unsigned long debugMillis = 0;
unsigned long auditMillis = 0;
// Control
int firstTry = HIGH;
// Magnitudes
float Tem_Cels = 21;
DateTime now = DateTime(0, 0, 0, 0, 0, 0);
void setup() {
// Debug monitor
Debug.begin();
Debug.println("INICIO DE ATtiny.\n");
// DDR setup
pinMode(DHT22_PIN, INPUT);
// 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() {
unsigned long currentMillis = millis();
// VERIFICAR FUNCIONAMIENTO (Control interno)
if(currentMillis >= auditMillis){
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;
}
auditMillis = currentMillis + 10000;
}
// 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);
delay(512);
firstTry = LOW;
}
#ifdef SDCARD_ONLY
if(currentMillis >= debugMillis){
Debug.println("\nMODO SDCARD_ONLY");
debugMillis = currentMillis + 1000;
}
return;
#endif
// 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(currentMillis >= debugMillis && currentMillis >= DHTMillis){
Tem_Cels = DHT.temperature;
DHT.read22(DHT22_PIN);
DHTMillis = currentMillis + 512;
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();
debugMillis = currentMillis + 1000;
}
delay(50);
}