#define pinSPOT A0 // Pino do potenciômetro slide - Simulador de RPM
#define limMax 301 // Tamanho máximo da fila - FIFO
#define pinBUZ 6 // Pino do buzzer - Alarme
#define pinRELE 7 // Pino do Rele - Ativação
#define pinCOSTA A1 // pino do potenciômetro - Direção do Vento
// Variáveis para o algoritmo do limite de armazenamento (300 medições) - FIFO
int fila[limMax]; // Array para armazenar os valores
int inicio = 0; // Índice do início da fila
int fim = 0; // Índice do fim da fila
int contador = 1; // Contador de valores armazenados
// Variáveis para cálculo da média - Velocidade do vento
float mediaVelVento = 0;
float velVentoAnterior = 0;
// Variáveis para cálculo do limite de valores acima da média
const int ativacoes = 10; // Limite de valores acima da média consecutivos
int contadorLimite = 0;
// Variáveis para cálculo da velocidade com base no RPM
const float pi = 3.14159265; // Número pi
int raio = 180; // Raio do anemômetro caseiro
// Para ativar o millis da análise de dados
unsigned long tempoAnterior = 0;
// Para ativar o millis do intervalo do buzzer
unsigned long intervaloAtivacao = 180000; // 3 minutos
unsigned long duracaoAtivacao = 20000; // 20 segundos
// Direções do vento
int direcaoVento = 0;
void setup() {
Serial.begin(9600);
pinMode(pinSPOT, INPUT);
pinMode(pinBUZ, OUTPUT);
pinMode(pinRELE, OUTPUT);
digitalWrite(pinRELE, LOW);
digitalWrite(pinBUZ, HIGH);
}
void loop() {
// Ativando a função millis (Temporizador interno do Arduino para funcionamento geral)
unsigned long tempoAtual = millis();
if(tempoAtual - tempoAnterior >= 360000){ // A cada 6 minutos uma análise vai ser concluída
tempoAnterior = tempoAtual;
// Modifica valores do potenciômetro de slide para RPM máxima
int valorSPOT = analogRead(pinSPOT);
int RPM = map(valorSPOT, 0, 1023, 0, 200);
// Direção do vento no potenciômetro
int valorDI = analogRead(pinCOSTA);
int direcaoVento = map(valorDI, 0, 1023, 0, 360);
if (direcaoVento < 90) {
Serial.println("Vento para Leste");
} else if (direcaoVento >= 90 && direcaoVento < 180){
Serial.println("Vento para Norte");
} else if (direcaoVento >= 180 && direcaoVento < 270){
Serial.println("Vento para Oeste");
} else{
Serial.println("Vento para Sul");
}
// Cálculos da Velocidade do vento e da média
float velVento = (((4 * pi * raio * RPM)/60)/1000) * 3.6;
float mediaVelVento = (velVento + velVentoAnterior) / 2;
velVentoAnterior = velVento;
// Condição para ativar o buzzer
/* Inicia timer interno para contagem da velocidade do
vento acima da média seguido. Além disso, só vai iniciar se a direção
do vento surgir da costa (no caso foram adotados o vento para Oeste e Leste) */
if ((velVento > mediaVelVento) && (direcaoVento < 90 || (direcaoVento >= 180 && direcaoVento < 270))) {
contadorLimite++;
} else {
contadorLimite = 0;
}
// Chama a função para ativar buzzer caso as condições forem atendidas
verificaAlarme();
// Impressões
Serial.println("Análise " + String(contador) + String(":"));
Serial.print("RPM: " + String(RPM));
Serial.print(" | Velocidade do vento: " + String(velVento + String(" km/h")));
Serial.println(" | Média: " + String(mediaVelVento + String(" km/h")));
Serial.println("");
// Ativando o algoritmo de armazenamento FIFO
fila[fim] = velVento; // Adiciona o novo valor à fila
fim = (fim + 1) % limMax; // Incrementa o fim da fila
contador++;
}
if (contador >= limMax) { // Verifica se a fila está cheia
inicio = (inicio + 1) % limMax; // Remove o valor mais antigo da fila
contador--; // Contador não aumenta
}
} // fim do loop
// Fução para ativar o buzzer conectado ao rele
void ativarBuzzer() {
static unsigned long tempoAnterior = 0; //Reescreve o tempoAnterior do millis
static bool buzzerAtivo = false; // Indica se buzzer está ligado ou desligado
unsigned long tempoAtual = millis();
// Indica se o buzzer está ligado ou se já passou pelo intervalo, caso sim, aciona o rele
if (!buzzerAtivo || (tempoAtual - tempoAnterior >= intervaloAtivacao)) {
tone(pinBUZ, 1000, duracaoAtivacao);
digitalWrite(pinRELE, HIGH); // Ativa o relé junto com o buzzer
buzzerAtivo = true;
tempoAnterior = tempoAtual;
} else if (tempoAtual - tempoAnterior >= duracaoAtivacao) {
noTone(pinBUZ);
digitalWrite(pinRELE, LOW); // Desativa o relé após a duração
buzzerAtivo = false;
}
}
void verificaAlarme() {
/*Analisa se a condição do alarme foi atingida pelo contador limite (valores acima da média),
por atingir a quantidade de dados máxima (300 registros) ou ambas. */
if (contadorLimite >= ativacoes || contador >= 299){
ativarBuzzer(); // Aciona a função do buzzer
} else {
// Mantém o relé e o buzzer desativado se a condição não for atendida
digitalWrite(pinRELE, LOW);
noTone(pinBUZ);
}
}