//Modelo arduino para leitura e aquisição de dados aplicado ao monitoramento ambiental
//Disciplina: GEOJ0125 - MÉTODOS E TÉCNICAS DE MONITORAMENTO AMBIENTAL - 2023-01
//Curso: Doutarado em Geografia
//Adaptação: Prof. Hildeu Ferreira da Assunção
//inclusão de bibliotecas
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>
#include <RTClib.h>
//definição dos pinos ativos
#define Led 4 //LED_BUILTIN
#define Pin_P 2
#define BUS 5
#define SDA A4 //RTC SDA A4
#define SCL A5 //RTC SCL A5
#define CS_PIN 10
//#define CS 10 MOSI 11 MISO 12 SCK 13 //--> sd
//definição de controles
#define LEITURA 5 //intervalo entre leituras dos sensores (5 minutos)
#define REGISTRO 60 //intervalo entre registros no datalogger (1h = 60 min)
//declara funções (opcional)
//declaração das variaveis
volatile float cte = 0.4;
volatile unsigned long trigger;
volatile float chuva = 0;
volatile int contador = 0;
int cnt = 0;
int last_reading_time, reading_time;
int alt;
float Ti;
float UR;
bool ledState = LOW;
String filelog = "Datalog.csv";
String fieldHeader = "Data\tHora\tAlt(m)\tChuva(mm)\tTemp(°C)\tUR(%)";
char timestamp[21];
String readingData = "";
//declaração dos objetos ativos
File dataFile; //objeto para registro dos dados
RTC_DS1307 rtc; //objeto para marcação do tempo
OneWire oneWire(BUS);
DallasTemperature sensor(&oneWire);
DeviceAddress insideThermometer;
//funções prioritárias (interrupt)
void pulso() {
if (millis() - trigger > 150) {
trigger = millis();
contador++;
chuva += cte;
}
}
//função de configurações e ativação de dispositivos e sensores
void setup() {
Serial.begin(9600);
pinMode(Led, OUTPUT);
pinMode(Pin_P, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(Pin_P), pulso, FALLING);
digitalWrite(Led, LOW);
sensor.begin();
if (!SD.begin(CS_PIN)) {
Serial.println("SD card ausente!");
}
if (!rtc.begin()) {
Serial.println("RTC ausente!");
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//atualiza a data e horário pelo computador (somente uma vez)
Serial.println(fieldHeader); //saida do cabecalho para o monitor serial
fieldHeader.replace("\t", ","); //converte o cabecalho para ser grvado
recData(); //grava os campos (cabecalho) dos dados
}
//função de continuidade
void loop() {
while (!update_time()) {};
if ((reading_time != last_reading_time) && (reading_time % LEITURA == 0)) {
getReadings(); //função que faz a leitura nos sensores a de cada 5 min
cnt++;
if (reading_time % REGISTRO == 0) {//ocorre a cada 60 minutos
recData(); //função que faz a gravação a cada hora
//reinicia as variaveis
chuva = 0;
Ti = 0;
UR = 0;
cnt = 0;
}
last_reading_time = reading_time; //atualiza o horario da ultima leitura
}
if (contador > 0) {
//getReadings();
digitalWrite(Led, HIGH);
delay(150);
digitalWrite(Led, LOW);
contador = 0;
}
}
//Outras funções
//verifica o tempo (hora e data)
bool update_time() {
DateTime now = rtc.now();
sprintf(timestamp, "%04d-%02d-%02d\t%02d:%02d:%02d\t", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
reading_time = now.minute(); //atualiza o tempo a cada minuto
return true;
}
//função para data e hora de criacao do arquivo de registros
void fatDateTime(uint16_t* date, uint16_t* time) {
DateTime now = rtc.now(); //get the current date-time(t)
*date = FAT_DATE(now.year(), now.month(), now.day()); // return date using FAT_DATE macro to format fields
*time = FAT_TIME(now.hour(), now.minute(), now.second()); // return time using FAT_TIME macro to format fields
//Serial.println("Data: "+ String(yyyy)+String(mm) + String(dd));
}
//função para registro dos dados
void recData() {
SdFile::dateTimeCallback(fatDateTime); //SD.dateTimeCallback(fatDateTime);
File dataFile = SD.open(filelog, FILE_WRITE); //"Datalog.csv"
//se o arquivo existe, registre os dados
if (dataFile) {
if (dataFile.size() < fieldHeader.length()) { //
dataFile.println(fieldHeader); //cabecalho de saida dos campos de dados
//Serial.println(Data.length());
} else {
dataFile.println(readingData); // gravacao dos dados numericos
Serial.println("\t✓"); //
}
dataFile.close();
} else {
Serial.println(filelog + " ausente!"); // if the file isn't open, pop up an error:
}
}
//funcao para leitura e junção dos dados: data e hora, chuva, temperatura, etc
void getReadings() {
if (sensor.getAddress(insideThermometer, 0)) {
//printAddress(insideThermometer);
sensor.setResolution(insideThermometer, 9);
sensor.requestTemperatures();
//float tempC = sensor.getTempC(insideThermometer);
}
alt = 670; //
Ti = sensor.getTempCByIndex(0);//tempC;
UR = 73.9;
String fieldData = timestamp + String(alt) + "\t" + String(chuva) + "\t" + String(Ti) + "\t" + String(UR);
Serial.println(fieldData);
readingData = fieldData;
readingData.replace("\t", ",");
}
/*
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
//sprintf(addr, "")//28FF6402FDBD48D3
}
}*/