// Exercício 6
// Rodrigo Francisco Pettinati Mikaro
/* Descrição do funcionamento:
Um reservatório de água cilíndroco mede 100cm de altura por 20cm de raio.
Um sensor ultrassônico está posicionado a 10cm do topo do cilindro; este
sensor será utilizado para controlar o funcionamento de uma bomba d´água,
utilizada para encher o tanque. Sempre que o volume armazenado chegar a
15% do máximo, a bomba deve ser acionada, e desligada somente quando o
volume chegar a 98% do máximo. Os volumes máximo e mínimo, o volume ins-
tantâneo medido e o estado da bomba (ligada ou desligada) são mostrados
no LCD.
*/
/* Nota:
Devido às limitações do simulador WOKWI, os LEDs vermelho e verde foram
utilizados para representarem, respectivamente, se a bomba está desligada
ou ligada.
Cálculo do volume suportado pelo reservatório:
sendo:
h = height = altura
r = radius = raio
Vs = (π · r²) · h
Vs = (3,14 · 20²) · 100
Vs = (3,14 · 400) · 100
Vs = (1256) · 100
Vs = 125600cm³
Cálculo do volume mínimo:
Vmin = Vs · 15%
Vmin = 125600 · 0,15
Vmin = 18840cm³
Cálculo do volume máximo:
Vmáx = Vs · 98%
Vmáx = 125600 · 0,98
Vmáx = 123088cm³
*/
/* Atenção!
Para garantir o funcionamento correto do programa, inicie definindo a distância do
sensor ultrassônico em 109cm.
*/
// Definição dos pinos do sensor ultrassônico:
#define PIN_TRIG 4
#define PIN_ECHO 5
// Inserção da Biblioteca do LCD e da comunicação I2C:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// Endereço do LCD I2C:
LiquidCrystal_I2C lcd(0x27,16,2);
// Variáveis utilizadas para calcular o volume instantâneo medido:
long volume = 0;
float height = 0;
float distance = 0;
// Valores máximo e mínimo de volume d´água em cm³ (calculados previamente):
float minVolume = 18841.00;
float maxVolume = 123088.00;
// Leds que indicam que a bomba está ligada e desligada, respectivamente:
#define LEDwaterPumpOn 7
#define LEDwaterPumpOff 8
// Variável booleana que indica o estado da bomba d´água (ligada ou desligada):
bool waterPumpOn = false;
void setup() {
// Inicialização do LCD:
lcd.init();
// Define pinos gatilho (trigger) e eco (echo) como saída e entrada, respectivamente:
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
}
void loop() {
// Liga o Backlight do display:
lcd.setBacklight(HIGH);
// Inicia uma nova medição:
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
// Leitura do resultado da duração e cálculo da distância:
int duration = pulseIn(PIN_ECHO, HIGH);
distance = duration / 58;
// Mapeia a distancia de 10cm a 110cm para uma altura de 100 a 0 cm:
if (distance >= 10 && distance <= 110) {
height = map(distance, 10, 110, 100, 0);
}
// Cálculo do volume do reservatório (fórmula explicada anteriormente):
volume = height * 3.14 * 20 * 20;
// Liga a bomba d´água quando o volume mínimo é atingido E a bomba está desligada:
if (volume <= minVolume && !waterPumpOn) {
digitalWrite(LEDwaterPumpOn, 1);
digitalWrite(LEDwaterPumpOff, 0);
waterPumpOn = true;
}
// Desliga a bomba d´água quando volume máximo é atingido e a bomba está ligada:
else if (volume >= maxVolume && waterPumpOn) {
digitalWrite(LEDwaterPumpOn, 0);
digitalWrite(LEDwaterPumpOff, 1);
waterPumpOn = false;
}
// Reset do LCD:
lcd.clear();
// 1ª Tela (volumes máximo e mínimo:)
lcd.setCursor(0,0);
lcd.print("Vmax: 123088mL");
lcd.setCursor(0,1);
lcd.print("Vmin: 18840mL");
// Tempo que o display exibe a tela 1:
delay(2000);
// Apaga a 1ª Tela:
lcd.clear();
// 2ª Tela (exibe volume atual e indica se a bomba está ou não ligada):
// 1ª Linha (exibe volume atual):
lcd.setCursor(0,0);
lcd.print("Vol atual: ");
lcd.print(volume/1000);
lcd.print("L");
// 2ª Linha (exibe estado da bomba):
lcd.setCursor(0,1);
lcd.print("Bomba: ");
// Quando a bomba está ligada:
if (waterPumpOn == true) {
lcd.print("ligada"); // exibe "ligada"
}
// Quando a bomba está desligada:
else if (waterPumpOn == false) {
lcd.print("desligada"); // exibe "desligada"
}
// Tempo que o display exibe a tela 2:
delay(2000);
// Caso a altura esteja menor que 10cm (distância maior que 110), o reservatório está com defeito:
// Avisa erro no display:
if (distance > 110) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Reservatorio com");
lcd.setCursor(4,1);
lcd.print("defeito!");
waterPumpOn = false;
digitalWrite(LEDwaterPumpOn, 0);
digitalWrite(LEDwaterPumpOff, 1);
delay(5000);
}
// Caso a altura esteja maior que 110cm (distância menor que 10), o reservatório está transbordando:
else if (distance < 10) {
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Reservatorio");
lcd.setCursor(2,1);
lcd.print("transbordou!");
waterPumpOn = false;
digitalWrite(LEDwaterPumpOn, 0);
digitalWrite(LEDwaterPumpOff, 1);
delay(5000);
}
}