#include <Arduino.h>
#include <Wire.h>
#include <MPU6050_tockn.h>
// AVISO ======> INSTRUÇÕES DO CÓDIGO ABAIXO
/* Para a simulação dos inputs de entrada dos giros do anemômetro, adotei um botão.
Esse botão contará os giros que o anemômetro realizará, e ao atender as condições de
Velocidade média acima do limite de velocidade por 10 contagens,
Uma verificação da direção do vento será relizada.
Tendo em vista que o anêmometro deve ser iniciado em direção ao mar, o eixo Z do
Sensor MPU 6050 será calibrado para essa direção.
Caso o sensor ultrapasse um giro de 90° ou -90°, e a segunda condicional for suprida
O rele será ativado soando o buzzer. */
//SUGESTÃO => Alterar o limite e o tamanho da fila fifo facilitará na hora de testar o código clicando no botão manualmente
#define SAMPLE_INTERVAL 360000 // Intervalo de amostragem de 6 minutos (em milissegundos)
#define ALERT_THRESHOLD 10 // Número de medições consecutivas acima do limite
#define WIND_SPEED_LIMIT 7.0 // Limite de velocidade do vento em m/s (ajuste conforme necessário)
// Variáveis para cálculo da velocidade do vento
volatile int windSpeedPulses = 0;
unsigned long lastWindSpeedCheck = 0;
unsigned long lastSampleTime = 0;
const float raio = 0.25; //Raio em metros da pá
// Fila circular para armazenar as medições de velocidade do vento
const int fifoSize = 300;
float windSpeedFifo[fifoSize];
int fifoIndex = 0;
int alertCount = 0;
//Pinos para leitura de velocidade
const int buttonPin = 32; // Pino onde o botão está conectado
volatile int clickCount = 0; // Contador de cliques
unsigned long startTime = 0; // Tempo de início
unsigned long debounceDelay = 50; // Tempo de debounce em milissegundos
volatile unsigned long lastDebounceTime = 0; // Tempo do último clique
//Pino Relé
const int PIN_RELAY = 33;
//Pinos para leitura de direção
MPU6050 mpu6050(Wire);
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP); // Configura o pino do botão como entrada com resistor de pull-up
attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPressed, FALLING); // Interrupção no evento de borda de descida
//Comunicação com módulo de direção
Wire.begin();
mpu6050.begin();
mpu6050.calcGyroOffsets(true);
pinMode(PIN_RELAY, OUTPUT);
digitalWrite(PIN_RELAY, LOW);
}
void loop() {
startTime = millis(); // Marca o tempo de início
clickCount = 0; // Reseta o contador de cliques
while (millis() - startTime < 2000) {
// Aguarda 2 segundos
}
float windSpeed = ((clickCount / 3) * 2 * 3.14 * raio); // Exemplo de conversão
// Armazenar a leitura atual na fila circular
windSpeedFifo[fifoIndex] = windSpeed;
fifoIndex = (fifoIndex + 1) % fifoSize;
// Calcular a média das medições na fila
float windSpeedSum = 0.0;
for (int i = 0; i < fifoSize; i++) {
windSpeedSum += windSpeedFifo[i];
}
float windSpeedAverage = windSpeedSum / fifoSize;
//Serial.print("Clicks in the last 2 seconds: ");
//Serial.println(clickCount);
Serial.print("Velocidade Instantânea: ");
Serial.print(windSpeed);
Serial.print(" m/s, Velocidade Média: ");
Serial.print(windSpeedAverage);
Serial.println(" m/s");
//iniciando leitura de giroscópio
mpu6050.update();
float windDirection = mpu6050.getAngleZ();
Serial.print("Graus : ");
Serial.println(windDirection);
// Verificar se a média está acima do limite
if (windSpeedAverage > WIND_SPEED_LIMIT) {
alertCount++;
if (alertCount >= ALERT_THRESHOLD) {
if(windDirection > 90 || windDirection < -90)
// Disparar alerta
Serial.println("ALERTA O vento está acima do limite de velocidade! e está soprando contra a praia!");
digitalWrite(PIN_RELAY, HIGH);
}
}
else {
digitalWrite(PIN_RELAY, LOW);
}
// Espera 1 segundo antes de iniciar a próxima contagem
}
void buttonPressed() {
unsigned long currentTime = millis();
if ((currentTime - lastDebounceTime) > debounceDelay) {
clickCount++; // Incrementa o contador de cliques
lastDebounceTime = currentTime; // Atualiza o tempo do último clique
}
}