#include <Wire.h>
#include <RTClib.h>
#include <SD.h>
#include <SPI.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>
#include <avr/wdt.h> // Inclua a biblioteca para o watchdog timer
// Definições para o display OLED
#define I2C_ADDRESS 0x3C
SSD1306AsciiAvrI2c oled;
// Definições para o RTC DS3231
RTC_DS3231 rtc;
// Definições para o SD Card
const int chipSelect = 10; // Pino do Arduino para o chip select do cartão SD
File arquivoCSV; // Objeto para o arquivo CSV no cartão SD
unsigned long tamanhoArquivoCSV = 0; // Variável para armazenar o tamanho do arquivo CSV
// Definições para os sensores de umidade
const int numSensores = 8; // Número de sensores de umidade
const int pinosSensores[numSensores] = {A0, A1, A2, A3, 5, A7, 2, 3}; // Pinos analógicos conectados aos sensores
const char* nomesSensores[numSensores] = {
"SWC120", "SWC140", "SWC160", "SWC180",
"SWC220", "SWC240", "SWC260", "SWC280"
}; // Nomes dos sensores para identificação
bool sensoresConectados[numSensores] = {false}; // Array para rastrear o status de conexão dos sensores
// Pinos e variáveis para o botão de delete e reset
const int pinoBotaoReset = 9;
const int pinoBotaoSwitch = 6; // Defina o pino digital para o botão switch
const int pinoBotaoDelete = 4;
unsigned long tempoPressionadoDelete = 0;
bool buttonPressedDelete = false;
const unsigned long tempoBarraProgresso = 4000; // Tempo para preencher a barra de progresso (4 segundos)
// Variáveis para rastrear o tempo
unsigned long ultimoVerificaConexao = 0; // Tempo da última verificação de conexão dos sensores
const unsigned long intervaloVerificaConexao = 1000; // Intervalo de verificação de 5 segundos
const unsigned long intervaloAtualizacaoUmidade = 1000; // Intervalo de atualização da umidade dos sensores a cada 10 min
unsigned long ultimoAtualizacaoUmidade = 0; // Último tempo de atualização da umidade
unsigned long ultimoMonitoramentoArquivo = 0; // Último tempo de monitoramento do tamanho do arquivo CSV
const unsigned long intervaloMonitoramentoArquivo = 1000; // Intervalo de monitoramento do tamanho do arquivo a cada 20 segundos
// Variáveis para rastrear o tempo das verificações
unsigned long ultimoVerificaRTC = 0; // Último tempo de verificação do RTC
const unsigned long intervaloVerificaRTC = 1800000; // Intervalo de verificação do RTC a cada 30 minutos
unsigned long ultimoVerificaSD = 0; // Último tempo de verificação do cartão SD
const unsigned long intervaloVerificaSD = 2000; // Intervalo de verificação do estado do cartão SD a cada 1 segundo
bool cartaoSDPresente = false; // Variável para rastrear o estado do cartão SD
void setup() {
// Inicialização do display OLED
Wire.begin();
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.setFont(System5x7);
// Inicialização do RTC
if (!rtc.begin()) {
exibirErro("Erro: RTC nao encontrado!");
while (true); // Travar o código em caso de erro
}
// Verificar se o cartão SD está presente
if (!SD.begin(chipSelect)) {
exibirErro("Erro: Cartao SD nao encontrado!");
while (true); // Travar o código em caso de erro
}
cartaoSDPresente = true;
// Abrir ou criar o arquivo CSV inicial
abrirOuCriarArquivoCSV();
// Configuração dos pinos dos botões
pinMode(pinoBotaoReset, INPUT_PULLUP); // Configurar o pino como entrada com pull-up interno
pinMode(pinoBotaoDelete, INPUT_PULLUP); // Configurar o pino como entrada com pull-up interno
pinMode(pinoBotaoSwitch, INPUT_PULLUP); // Configurar o pino como entrada com pull-up interno
// Inicialização do Monitor Serial
Serial.begin(9600); // Inicializa a comunicação serial
//Inicialização do sistema
oled.clear();
oled.println("Iniciando Sensor...");
oled.displayRows(); // Atualiza o display OLED
delay(2000);
// Outras inicializações e mensagens no OLED
oled.clear();
oled.println("Modulos OK");
oled.displayRows(); // Atualiza o display OLED
delay(2000);
}
void loop() {
unsigned long tempoAtual = millis();
// Verificações periódicas
if (tempoAtual - ultimoVerificaConexao >= intervaloVerificaConexao) {
ultimoVerificaConexao = tempoAtual;
verificarConexaoSensores();
}
if (cartaoSDPresente && tempoAtual - ultimoAtualizacaoUmidade >= intervaloAtualizacaoUmidade) {
ultimoAtualizacaoUmidade = tempoAtual;
atualizarUmidadeSensores();
}
// Verificar o estado do SD Card
verificarEstadoSD();
// Monitorar o tamanho do arquivo CSV a cada 20 segundos
if (tempoAtual - ultimoMonitoramentoArquivo >= intervaloMonitoramentoArquivo) {
ultimoMonitoramentoArquivo = tempoAtual;
monitorarTamanhoArquivoCSV();
}
// Verificar o estado do botão de delete
if (digitalRead(pinoBotaoDelete) == LOW) { // Botão pressionado
if (!buttonPressedDelete) {
tempoPressionadoDelete = millis();
buttonPressedDelete = true;
} else {
unsigned long tempoPressionado = millis() - tempoPressionadoDelete;
if (tempoPressionado >= tempoBarraProgresso) {
deletarArquivo();
// Esperar até que o botão seja liberado para evitar repetição
while (digitalRead(pinoBotaoDelete) == LOW) {
delay(10); // Pequeno atraso para evitar debouncing
}
buttonPressedDelete = false;
} else {
mostrarBarraProgresso(tempoPressionado, tempoBarraProgresso);
}
}
} else {
buttonPressedDelete = false;
}
// Verificar o estado do botão de reset
if (digitalRead(pinoBotaoReset) == LOW) { // Botão pressionado
resetarArduino(); // Chama a função de reset
// Aguardar até que o botão seja liberado para evitar reinicializações repetidas
while (digitalRead(pinoBotaoReset) == LOW) {
delay(50); // Pequeno atraso para evitar debouncing
}
}
// Verificar o estado do botão switch e controlar o display OLED
verificarEstadoSwitch();
// Atualizar a visualização dos sensores conectados
atualizarDisplaySensores();
// Imprimir dados no Monitor Serial
imprimirDadosMonitorSerial();
}
void mostrarBarraProgresso(unsigned long tempoInicial, unsigned long duracao) {
unsigned long tempoAtual = millis();
float progresso = float(tempoAtual - tempoInicial) / duracao; // Calcula o progresso em porcentagem
oled.clear();
oled.setCursor(0, 0);
oled.println("Deletando arquivo...");
int barraComprimento = 16; // Comprimento da barra em caracteres
int barraPreenchida = int(barraComprimento * progresso);
// Desenha a barra de progresso
oled.print("[");
for (int i = 0; i < barraComprimento; i++) {
if (i < barraPreenchida) {
oled.print("#"); // Caractere para parte preenchida da barra
} else {
oled.print("-"); // Caractere para parte não preenchida da barra
}
}
oled.print("]");
oled.displayRows(); // Atualiza o display OLED
// Adicionar um atraso para uma atualização mais lenta
delay(100); // Atraso em milissegundos
}
void verificarEstadoSwitch() {
if (digitalRead(pinoBotaoSwitch) == LOW) {
oled.ssd1306WriteCmd(SSD1306_DISPLAYOFF); // Desliga o display OLED
} else {
oled.ssd1306WriteCmd(SSD1306_DISPLAYON); // Liga o display OLED
}
}
void deletarArquivo() {
unsigned long tempoInicio = millis();
unsigned long duracao = tempoBarraProgresso; // Tempo para a barra de progresso
oled.clear();
oled.println("Aguarde...");
oled.displayRows(); // Atualiza o display OLED
// Loop até que o tempo decorrido atinja a duração
while (millis() - tempoInicio < duracao) {
mostrarBarraProgresso(tempoInicio, duracao);
}
// Após completar o tempo de 4 segundos, tentar deletar o arquivo
if (SD.exists("dados.csv")) {
if (SD.remove("dados.csv")) {
oled.clear();
oled.println("Arquivo deletado com sucesso");
} else {
oled.clear();
oled.println("Erro ao deletar arquivo");
}
} else {
oled.clear();
oled.println("Arquivo nao encontrado");
}
oled.displayRows(); // Atualiza o display OLED
}
// Função para resetar o Arduino
void resetarArduino() {
oled.clear();
oled.println("Reiniciando...");
oled.displayRows(); // Atualiza o display OLED
delay(1000); // Atraso para mostrar a mensagem
// Configura o watchdog timer para reiniciar o Arduino
wdt_enable(WDTO_15MS); // Configura o watchdog timer para um curto período de 15ms
while (true) {
// O watchdog timer irá reiniciar o Arduino quando atingir o período definido
}
}
// Verifica a conexão de cada sensor de umidade
void verificarConexaoSensores() {
for (int i = 0; i < numSensores; i++) {
bool conectado = verificaConexaoPino(pinosSensores[i]);
sensoresConectados[i] = conectado;
}
}
// Verifica a conexão de um sensor em um pino específico
bool verificaConexaoPino(int pino) {
pinMode(pino, INPUT);
return digitalRead(pino) == HIGH;
}
// Atualiza a umidade de todos os sensores conectados
void atualizarUmidadeSensores() {
for (int i = 0; i < numSensores; i++) {
if (sensoresConectados[i]) {
int umidade = analogRead(pinosSensores[i]);
umidade = map(umidade, 1023, 300, 0, 100);
// Abrir o arquivo CSV para escrita
if (arquivoCSV) {
// Inserir cabeçalhos na primeira linha
if (arquivoCSV.size() == 0) {
arquivoCSV.println("Sensor, Umidade (%), Data, Hora");
arquivoCSV.flush();
}
// Obter data e hora atuais do RTC
DateTime agora = rtc.now();
String data = String(agora.day()) + "/" + String(agora.month()) + "/" + String(agora.year());
String hora = String(agora.hour()) + ":" + String(agora.minute()) + ":" + String(agora.second());
// Escrever os dados no arquivo CSV
arquivoCSV.print(nomesSensores[i]);
arquivoCSV.print(", ");
arquivoCSV.print(umidade);
arquivoCSV.print(", ");
arquivoCSV.print(data);
arquivoCSV.print(", ");
arquivoCSV.println(hora);
arquivoCSV.flush(); // Forçar escrita imediata no arquivo
// Atualizar o tamanho do arquivo
tamanhoArquivoCSV = arquivoCSV.size();
}
}
}
}
// Verificar o estado do cartão SD
void verificarEstadoSD() {
if (!SD.begin(chipSelect)) {
if (cartaoSDPresente) {
cartaoSDPresente = false;
oled.clear();
oled.println("Erro: Cartao SD removido!");
oled.displayRows(); // Atualiza o display OLED
}
} else {
if (!cartaoSDPresente) {
cartaoSDPresente = true;
abrirOuCriarArquivoCSV();
}
}
}
// Monitorar o tamanho do arquivo CSV
void monitorarTamanhoArquivoCSV() {
oled.clear();
oled.println("CSV:");
float tamanhoKB = tamanhoArquivoCSV / 1024.0; // Converter bytes para kilobytes
oled.print(tamanhoKB, 1); // Exibir com uma casa decimal
oled.println(" KB");
oled.displayRows(); // Atualiza o display OLED
delay(2000); // Delay para visualização no OLED
}
// Função para atualizar o display com os dados dos sensores conectados
void atualizarDisplaySensores() {
oled.clear();
if (digitalRead(pinoBotaoSwitch) == HIGH) {
oled.setCursor(0, 0);
for (int i = 0; i < numSensores; i++) {
if (sensoresConectados[i]) {
oled.print(nomesSensores[i]);
oled.print(": ");
int umidade = analogRead(pinosSensores[i]);
umidade = constrain(map(umidade, 1023, 300, 0, 100), 0, 100);
oled.print(umidade);
oled.println("%");
} else {
oled.print(nomesSensores[i]);
oled.println(": --");
}
}
oled.displayRows(); // Atualiza o display OLED
delay(2000); // Delay para visualização no OLED
}
}
// Função para exibir mensagens de erro no OLED
void exibirErro(const char* mensagem) {
oled.clear();
oled.println(mensagem);
oled.displayRows(); // Atualiza o display OLED
delay(2000);
}
// Função para abrir ou criar o arquivo CSV no cartão SD
void abrirOuCriarArquivoCSV() {
arquivoCSV = SD.open("dados.csv", FILE_WRITE);
if (!arquivoCSV) {
exibirErro("Erro: Falha ao abrir/criar arquivo CSV!");
while (true); // Travar o código em caso de erro
}
}
// Função para imprimir dados no Monitor Serial
void imprimirDadosMonitorSerial() {
Serial.println("Dados dos Sensores:");
for (int i = 0; i < numSensores; i++) {
if (sensoresConectados[i]) {
int umidade = analogRead(pinosSensores[i]);
umidade = constrain(map(umidade, 1023, 330, 0, 100), 0, 100);
Serial.print(nomesSensores[i]);
Serial.print(": ");
Serial.print(umidade);
Serial.println("%");
} else {
Serial.print(nomesSensores[i]);
Serial.println(": --");
}
}
Serial.print("Tamanho do arquivo CSV: ");
float tamanhoKB = tamanhoArquivoCSV / 1024.0; // Converter bytes para kilobytes
Serial.print(tamanhoKB, 1); // Exibir com uma casa decimal
Serial.println(" KB");
Serial.println();
}
Loading
ds18b20
ds18b20