agrobot_base/Firmware/Modulos/SensorFluxoModel.h

144 lines
3.7 KiB
C++

#include "SerialService.h"
#include "Pinout.h"
#ifndef SensorFluxoModel
#define SensorFluxoModel
class SensorFluxo {
public:
SensorFluxo(String _modID, String _id) {
Mod_ID = _modID;
_ID = _id;
}
// Definições
String Mod_ID = "";
String _ID;
S_Code _componente = sFLX;
PinoModel _pino;
int _TaxaAmostragem = 2000;
int _delayAmostragem;
int _prioridade;
float _calibragem;
bool Iniciado = false;
bool Checando = false;
// Consumo
volatile int ultimaLeitura = 0;
volatile unsigned int tempoAnterior = 0;
volatile int _Pulsos = 0;
volatile long _PeriodoTotal = 0;
volatile float _Fluxo = 0;
void Inicializar() {
if (Iniciado) {
//EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(Mod_ID, MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
_pino.Conectar();
ultimaLeitura = _pino.get();
tempoAnterior = 0;
_Pulsos = 0;
_PeriodoTotal = 0;
_Fluxo = 0;
if (SFTaskHandle == NULL) {
xTaskCreatePinnedToCore(&SensorFluxo::SFTaskWrapper, "SFTask", 10000, this, _prioridade, &SFTaskHandle, tskNO_AFFINITY);
}
//EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(Mod_ID, MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
//EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(Mod_ID, MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(SFTaskHandle);
SFTaskHandle = NULL;
delay(50); // Aguarda um tempo para garantir o desligamento da tarefa
// Redefinir as configurações para os valores iniciais
_pino.Desconectar();
//EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(Mod_ID, MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
private:
TaskHandle_t SFTaskHandle = NULL;
static void SFTaskWrapper(void *pvParameters) {
SensorFluxo *sensor = static_cast<SensorFluxo*>(pvParameters);
sensor->SFTask();
}
void SFTask() {
unsigned long firstMilis = millis();
volatile int pulsosA = 0;
volatile float periodo = 0;
while (1)
{
if (!Iniciado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(pdMS_TO_TICKS(1000));
continue;
}
bool Leitura = _pino.get() == 1;
if (Leitura != ultimaLeitura) {
ultimaLeitura = Leitura;
_Pulsos++;
// Calcular o período em microssegundos
unsigned long tempoAtual = micros();
unsigned long periodoUs = _Pulsos == 1 ? 0 : (tempoAtual - tempoAnterior);
periodo = periodoUs / 1000.0; // Converte de us para ms (2300 us para 2,3 ms)
_PeriodoTotal += periodo;
//CalcularFluxo(periodo);
tempoAnterior = tempoAtual;
}
long intMillis = (millis() - firstMilis);
int Tempo = _TaxaAmostragem + _delayAmostragem;
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= Tempo) {
if (_Pulsos == pulsosA) {
_PeriodoTotal = 0;
_Pulsos = 0;
}
//EnviarDadosSerial(Mod_ID, MontarProtocoloSensor(sFLX, _ID, MontarDadosProtocoloFluxo(pulsos, periodoTotal)));
pulsosA = _Pulsos;
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(pdMS_TO_TICKS(1));
}
}
};
#endif