agrobot_base/Firmware/Modulos/SensorTemperaturaNtcModel.h

150 lines
3.5 KiB
C
Raw Permalink Normal View History

#include "SerialService.h"
#include "Pinout.h"
#include "Utils.h"
#include "IComponenteCAN.h"
#include <SimpleKalmanFilter.h>
#ifndef SensorTemperaturaNtcModel
#define SensorTemperaturaNtcModel
class SensorTemperaturaNtc : public ComponenteCAN {
public:
String ID;
uint8_t ID_Num = 0;
PinoModel _pino;
int leitura = 0;
double temperatura = -1;
double tensao = 0;
bool Iniciado = false;
float OffsetTemperatura = 0.0f;
SensorTemperaturaNtc() {}
SensorTemperaturaNtc(
const String& id,
uint8_t idNum,
int pino,
TiposBarramentos tipoBarramento,
int canalMux = -1,
float offsetTemperatura = 0.0f
) :
ID(id),
ID_Num(idNum),
_pino(PinoModel(pino, tipoBarramento, _INPUT, ANALOGICO, idNum, canalMux)),
OffsetTemperatura(offsetTemperatura)
{
}
void Inicializar() {
if (Iniciado) {
MostrarLog("Sensor ja inicializado");
return;
}
leitura = 0;
temperatura = -1;
tensao = 0;
_pino.Conectar();
Iniciado = _pino.Definido();
MostrarLog(Iniciado ? "Sensor iniciado" : "Sensor nao iniciado");
}
void Desligar() {
if (!Iniciado) {
MostrarLog("Sensor nao esta inicializado");
return;
}
_pino.Desconectar();
Iniciado = false;
MostrarLog("Sensor desligado");
}
void RequisitarDados() {
if (!Iniciado) return;
AferirTemperatura();
}
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: {
int16_t leituraInt = static_cast<int16_t>(round(temperatura * 100.0f));
data.push_back((uint8_t)(leitura >> 8));
data.push_back((uint8_t)(leitura & 0xFF));
data.push_back((uint8_t)(leituraInt >> 8));
data.push_back((uint8_t)(leituraInt & 0xFF));
break;
}
}
return data;
}
private:
2026-04-02 23:42:18 +00:00
bool DebugMode = false;
// SimpleKalmanFilter filtro = SimpleKalmanFilter(5, 15, 0.01);
void MostrarLog(String mensagem) {
if (DebugMode) {
PrintTela("[TMP " + ID + "] " + mensagem);
}
}
void AferirTemperatura() {
leitura = _pino.get(1);
// leitura = filtro.updateEstimate(leitura);
temperatura = CalcularTemperatura((float)leitura, OffsetTemperatura);
MostrarLog("Leitura: " + String(leitura) +
", Tensao: " + String(tensao) +
", Temperatura: " + String(temperatura));
}
float CalcularTemperatura(float leituraAdc, float offset = 0.0f) {
const float Vs = 5.0f;
const float Beta = 3950.0f;
const float To = 298.15f;
const float Ro = 10000.0f;
const float adcMax = 4095.0f;
static constexpr float divisor = 1.0f;
static constexpr float vOffset = (2.516f / 3.036f);
if (leituraAdc < 200.0f) return -1.0f;
float Vadc = leituraAdc / adcMax * Vs;
Vadc = Vadc * divisor * vOffset;
tensao = Vadc;
if (Vadc <= 0.001f) return -100.0f;
if (Vadc >= Vs) return NAN;
float Rt = Ro * (Vadc / (Vs - Vadc));
float T = 1.0f / (1.0f / To + log(Rt / Ro) / Beta);
float Tc = T - 273.15f + offset;
return roundf(Tc * 100.0f) / 100.0f;
}
};
#endif