agrobot_base/Firmware/Modulos/SensorFluxoModel_v2.h

173 lines
4.0 KiB
C++

#include "SerialService.h"
#include "Pinout.h"
#include "IComponenteCAN.h"
#ifndef SensorFluxoModel_v2_h
#define SensorFluxoModel_v2_h
class SensorFluxo_v2 : public ComponenteCAN {
public:
SensorFluxo_v2(
const String& id,
uint8_t idNum,
int pino,
TiposBarramentos barramento = CONTROLADOR
)
: _ID(id),
ID_Num(idNum),
_pino(pino, barramento, _INPUT_PULLUP, DIGITAL) {
}
String _ID;
uint8_t ID_Num = 0;
PinoModel _pino;
bool Iniciado = false;
unsigned long tempoAnterior = 0;
unsigned int _Pulsos = 0;
unsigned long _PeriodoTotal = 0;
bool ultimaLeitura = false;
unsigned int _PulsosLeitura = 0;
unsigned long _PeriodoTotalLeitura = 0;
float _Vazao = 0.0f;
void Inicializar() {
if (Iniciado) {
MostrarLog("Sensor ja inicializado");
return;
}
_pino.Conectar();
Iniciado = _pino.Definido();
if (Iniciado) {
ResetarEstado();
MostrarLog("Sensor iniciado");
} else {
MostrarLog("Sensor nao iniciado");
}
}
void Desligar() {
if (!Iniciado) {
MostrarLog("Sensor nao esta inicializado");
return;
}
_pino.Desconectar();
ResetarEstado();
_PulsosLeitura = 0;
_PeriodoTotalLeitura = 0;
_Vazao = 0.0f;
Iniciado = false;
MostrarLog("Sensor desligado");
}
void Loop() {
if (!Iniciado) return;
bool leituraAtual = (_pino.get() == 1);
if (leituraAtual != ultimaLeitura) {
//MostrarLog("Mudou: ultima=" + String(ultimaLeitura) + " atual=" + String(leituraAtual));
if (leituraAtual && !ultimaLeitura) {
unsigned long tempoAtual = millis();
unsigned long intervalo = tempoAtual - tempoAnterior;
tempoAnterior = tempoAtual;
_Pulsos++;
_PeriodoTotal += intervalo;
//MostrarLog("SUBIDA! Pulsos=" + String(_Pulsos) + " Periodo=" + String(_PeriodoTotal) + " Intervalo=" + String(intervalo));
}
ultimaLeitura = leituraAtual;
}
}
void RequisitarDados() {
AtualizarLeitura();
}
std::vector<uint8_t> MontarMensagemCAN(CanMessagePosicaoDados posicao) {
std::vector<uint8_t> data;
data.push_back(static_cast<uint8_t>(posicao));
data.push_back(ID_Num);
switch (posicao) {
case CanMessagePosicaoDados::Status: {
data.push_back(Iniciado ? 1 : 0);
break;
}
case CanMessagePosicaoDados::Dados1: {
uint16_t vazaoEscalada = (uint16_t)(_Vazao * 100.0f);
data.push_back((uint8_t)_PulsosLeitura);
data.push_back((uint8_t)(_PeriodoTotalLeitura >> 8));
data.push_back((uint8_t)(_PeriodoTotalLeitura & 0xFF));
data.push_back((uint8_t)(vazaoEscalada >> 8));
data.push_back((uint8_t)(vazaoEscalada & 0xFF));
break;
}
default:
break;
}
return data;
}
private:
bool DebugMode = false;
void AtualizarLeitura() {
if (!Iniciado) return;
_PulsosLeitura = _Pulsos;
_PeriodoTotalLeitura = _PeriodoTotal;
_Vazao = CalcularVazao(_Pulsos, _PeriodoTotal);
ReiniciarAmostragem();
}
void ResetarEstado() {
_Pulsos = 0;
_PeriodoTotal = 0;
tempoAnterior = millis();
ultimaLeitura = (_pino.get() == 1);
}
void ReiniciarAmostragem() {
_Pulsos = 0;
_PeriodoTotal = 0;
tempoAnterior = millis();
}
float CalcularVazao(uint16_t pulsos, unsigned long periodoMs) {
if (periodoMs == 0) return 0.0f;
float frequenciaHz = ((float)pulsos) * 1000.0f / (float)periodoMs;
float q_L_min = (frequenciaHz + 3.0f) / 8.1f;
if (q_L_min < 0.0f) q_L_min = 0.0f;
if (q_L_min > 10.0f) q_L_min = 10.0f;
float q_mL_s = q_L_min * (1000.0f / 60.0f);
return q_mL_s;
}
void MostrarLog(String mensagem) {
if (DebugMode) {
PrintTela("[FLX " + _ID + "] " + mensagem);
}
}
};
#endif