pequenos ajustes no sensor de temperatura e pinout
This commit is contained in:
parent
72bf996e7e
commit
6242d8b3dc
|
|
@ -7,6 +7,11 @@
|
||||||
|
|
||||||
#define PINO_INVALIDO 0xFF
|
#define PINO_INVALIDO 0xFF
|
||||||
|
|
||||||
|
enum class FormatoLeituraAnalogica : uint8_t {
|
||||||
|
Bruta,
|
||||||
|
Milivolts
|
||||||
|
};
|
||||||
|
|
||||||
class PinoModel {
|
class PinoModel {
|
||||||
public:
|
public:
|
||||||
int num;
|
int num;
|
||||||
|
|
@ -20,6 +25,35 @@ class PinoModel {
|
||||||
PinoModel(int numero = PINO_INVALIDO, TiposBarramentos barr = CONTROLADOR, TiposPinos tp = _INPUT, TiposLeituras lt = DIGITAL, int _idSensor = 0, int canalMux = -1) : num(numero), barramento(barr), tipo(tp), leitura(lt), idSensor(_idSensor), _CanalMUX(canalMux) {
|
PinoModel(int numero = PINO_INVALIDO, TiposBarramentos barr = CONTROLADOR, TiposPinos tp = _INPUT, TiposLeituras lt = DIGITAL, int _idSensor = 0, int canalMux = -1) : num(numero), barramento(barr), tipo(tp), leitura(lt), idSensor(_idSensor), _CanalMUX(canalMux) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConfigurarLeituraAnalogica(uint8_t resolucaoBits = 12, adc_attenuation_t atenuacao = ADC_11db) {
|
||||||
|
if (!Conectado || barramento != TiposBarramentos::CONTROLADOR || leitura != TiposLeituras::ANALOGICO) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolucaoBits < 9 || resolucaoBits > 12) {
|
||||||
|
MostrarLog(
|
||||||
|
"Resolucao ADC invalida no GPIO " +
|
||||||
|
String(num) +
|
||||||
|
": " +
|
||||||
|
String(resolucaoBits) +
|
||||||
|
" bits"
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
analogReadResolution(resolucaoBits);
|
||||||
|
analogSetPinAttenuation(num, atenuacao);
|
||||||
|
|
||||||
|
MostrarLog(
|
||||||
|
"ADC configurado | GPIO: " + String(num) +
|
||||||
|
" | Resolucao: " + String(resolucaoBits) +
|
||||||
|
" bits | Atenuacao: " + String(static_cast<int>(atenuacao))
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Definido() {
|
bool Definido() {
|
||||||
bool barramentoIniciado =
|
bool barramentoIniciado =
|
||||||
(barramento == TiposBarramentos::CONTROLADOR) ||
|
(barramento == TiposBarramentos::CONTROLADOR) ||
|
||||||
|
|
@ -90,38 +124,72 @@ class PinoModel {
|
||||||
Conectado = false;
|
Conectado = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get(int leituras = 1) {
|
int get(int quantidadeLeituras = 1, FormatoLeituraAnalogica formato = FormatoLeituraAnalogica::Bruta) {
|
||||||
if (Conectado) {
|
if (!Conectado || quantidadeLeituras <= 0) {
|
||||||
if (barramento == TiposBarramentos::CONTROLADOR) {
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool retornarMilivolts = formato == FormatoLeituraAnalogica::Milivolts;
|
||||||
|
|
||||||
|
switch (barramento) {
|
||||||
|
case TiposBarramentos::CONTROLADOR: {
|
||||||
if (leitura == TiposLeituras::DIGITAL) {
|
if (leitura == TiposLeituras::DIGITAL) {
|
||||||
return digitalRead(num);
|
if (retornarMilivolts) {
|
||||||
}
|
MostrarLog("Leitura em mV solicitada para pino digital: " + String(num));
|
||||||
else if (leitura == TiposLeituras::ANALOGICO) {
|
|
||||||
double l = 0;
|
|
||||||
for (int i = 0; i < leituras; i++) {
|
|
||||||
vTaskDelay(1);
|
|
||||||
int leitura = analogRead(num);
|
|
||||||
MostrarLog("Leitura Controlador: " + String(leitura));
|
|
||||||
l += leitura;
|
|
||||||
}
|
|
||||||
return l / leituras;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (barramento == TiposBarramentos::EXPANSOR_GPIO) {
|
|
||||||
if (I2CService::McpIniciado) {
|
|
||||||
if (!I2CService::SolicitarAcessoI2C(idSensor, _CanalMUX)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int leitura = I2CService::mcp.digitalRead(num);
|
return digitalRead(num);
|
||||||
I2CService::LiberarAcessoI2C(idSensor);
|
|
||||||
return leitura;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (leitura == TiposLeituras::ANALOGICO) {
|
||||||
|
uint64_t soma = 0;
|
||||||
|
for (int i = 0; i < quantidadeLeituras; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
}
|
||||||
|
const uint32_t valor = retornarMilivolts ? analogReadMilliVolts(num) : analogRead(num);
|
||||||
|
soma += valor;
|
||||||
|
}
|
||||||
|
const uint32_t media = static_cast<uint32_t>(soma / static_cast<uint64_t>(quantidadeLeituras));
|
||||||
|
MostrarLog(
|
||||||
|
"Leitura Controlador | GPIO: " + String(num) +
|
||||||
|
" | Valor: " + String(media) +
|
||||||
|
(retornarMilivolts ? " mV" : " raw") +
|
||||||
|
" | Amostras: " + String(quantidadeLeituras)
|
||||||
|
);
|
||||||
|
return media <= static_cast<uint32_t>(INT_MAX) ? static_cast<int>(media) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else if (barramento == TiposBarramentos::EXPANSOR_ADS) {
|
|
||||||
return I2CService::RealizarLeituraADS(num, leituras, idSensor, _CanalMUX);
|
case TiposBarramentos::EXPANSOR_GPIO: {
|
||||||
|
if (retornarMilivolts) {
|
||||||
|
MostrarLog("Leitura em mV nao suportada pelo expansor GPIO");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!I2CService::McpIniciado) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!I2CService::SolicitarAcessoI2C(idSensor, _CanalMUX)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
const int valor = I2CService::mcp.digitalRead(num);
|
||||||
|
I2CService::LiberarAcessoI2C(idSensor);
|
||||||
|
return valor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TiposBarramentos::EXPANSOR_ADS: {
|
||||||
|
if (retornarMilivolts) {
|
||||||
|
MostrarLog("Modo milivolts ainda nao definido para o ADS");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return I2CService::RealizarLeituraADS(num, quantidadeLeituras, idSensor, _CanalMUX);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(bool status, bool reqMutex = true) {
|
void set(bool status, bool reqMutex = true) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ class SensorTemperaturaNtc : public ComponenteCAN {
|
||||||
String ID;
|
String ID;
|
||||||
uint8_t ID_Num = 0;
|
uint8_t ID_Num = 0;
|
||||||
PinoModel _pino;
|
PinoModel _pino;
|
||||||
|
bool _ntcGnd = false;
|
||||||
|
|
||||||
int leitura = 0;
|
int leitura = 0;
|
||||||
double temperatura = -1;
|
double temperatura = -1;
|
||||||
|
|
@ -29,12 +30,14 @@ class SensorTemperaturaNtc : public ComponenteCAN {
|
||||||
int pino,
|
int pino,
|
||||||
TiposBarramentos tipoBarramento,
|
TiposBarramentos tipoBarramento,
|
||||||
int canalMux = -1,
|
int canalMux = -1,
|
||||||
float offsetTemperatura = 0.0f
|
float offsetTemperatura = 0.0f,
|
||||||
|
bool ntcGnd = false
|
||||||
) :
|
) :
|
||||||
ID(id),
|
ID(id),
|
||||||
ID_Num(idNum),
|
ID_Num(idNum),
|
||||||
_pino(PinoModel(pino, tipoBarramento, _INPUT, ANALOGICO, idNum, canalMux)),
|
_pino(PinoModel(pino, tipoBarramento, _INPUT, ANALOGICO, idNum, canalMux)),
|
||||||
OffsetTemperatura(offsetTemperatura)
|
OffsetTemperatura(offsetTemperatura),
|
||||||
|
_ntcGnd(ntcGnd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,6 +52,7 @@ class SensorTemperaturaNtc : public ComponenteCAN {
|
||||||
tensao = 0;
|
tensao = 0;
|
||||||
|
|
||||||
_pino.Conectar();
|
_pino.Conectar();
|
||||||
|
_pino.ConfigurarLeituraAnalogica(12, ADC_11db);
|
||||||
|
|
||||||
Iniciado = _pino.Definido();
|
Iniciado = _pino.Definido();
|
||||||
|
|
||||||
|
|
@ -123,14 +127,36 @@ class SensorTemperaturaNtc : public ComponenteCAN {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AferirTemperatura() {
|
void AferirTemperatura() {
|
||||||
leitura = _pino.get(1);
|
constexpr int QuantidadeAmostras = 16;
|
||||||
// leitura = filtro.updateEstimate(leitura);
|
|
||||||
|
|
||||||
temperatura = CalcularTemperatura((float)leitura, OffsetTemperatura);
|
leitura = _pino.get(QuantidadeAmostras);
|
||||||
|
const int tensaoMv = _pino.get(QuantidadeAmostras, FormatoLeituraAnalogica::Milivolts);
|
||||||
|
|
||||||
MostrarLog("Leitura: " + String(leitura) +
|
if (leitura < 0 || tensaoMv < 0) {
|
||||||
", Tensao: " + String(tensao) +
|
leitura = -1;
|
||||||
", Temperatura: " + String(temperatura));
|
tensao = NAN;
|
||||||
|
temperatura = NAN;
|
||||||
|
|
||||||
|
MostrarLog("Falha na leitura do sensor NTC");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tensao = tensaoMv / 1000.0f;
|
||||||
|
|
||||||
|
// Detecta curto, pino flutuante, circuito aberto ou saturação.
|
||||||
|
if (leitura <= 20 || leitura >= 4080) {
|
||||||
|
temperatura = NAN;
|
||||||
|
MostrarLog("Leitura NTC fora da faixa | Raw: " + String(leitura) + " | Tensao: " + String(tensao, 3) + " V");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
temperatura = CalcularTemperaturaPorTensao(static_cast<float>(tensaoMv), _ntcGnd, OffsetTemperatura);
|
||||||
|
|
||||||
|
MostrarLog(
|
||||||
|
"Leitura: " + String(leitura) +
|
||||||
|
" | Tensao: " + String(tensao, 3) + " V" +
|
||||||
|
" | Temperatura: " + String(temperatura, 2) + " C"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcularTemperatura(float leituraAdc, float offset = 0.0f) {
|
float CalcularTemperatura(float leituraAdc, float offset = 0.0f) {
|
||||||
|
|
@ -158,7 +184,87 @@ class SensorTemperaturaNtc : public ComponenteCAN {
|
||||||
|
|
||||||
return roundf(Tc * 100.0f) / 100.0f;
|
return roundf(Tc * 100.0f) / 100.0f;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
float CalcularTemperaturaPorTensao(float tensaoAdcMv, bool ntcGnd, float offset = 0.0f) {
|
||||||
|
constexpr float Vs = 5.0f;
|
||||||
|
|
||||||
|
constexpr float Rfixo = 10000.0f; // Resistor interno do motor
|
||||||
|
|
||||||
|
// Valores reais da placa:
|
||||||
|
constexpr float Rserie = 4700.0f; // Retorno até o GPIO
|
||||||
|
constexpr float Rgnd = 6800.0f; // GPIO até o GND
|
||||||
|
constexpr float Rcarga = Rserie + Rgnd;
|
||||||
|
|
||||||
|
constexpr float Beta = 3950.0f;
|
||||||
|
constexpr float T0 = 298.15f; // 25 °C em kelvin
|
||||||
|
constexpr float Rntc25 = 10000.0f;
|
||||||
|
|
||||||
|
const float vAdc = tensaoAdcMv / 1000.0f;
|
||||||
|
|
||||||
|
if (!isfinite(vAdc) || vAdc <= 0.01f || vAdc >= 3.05f)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
// Tensão no retorno do motor, antes do resistor de 4,7 kΩ.
|
||||||
|
const float vRetorno = vAdc * (Rserie + Rgnd) / Rgnd;
|
||||||
|
|
||||||
|
if (!isfinite(vRetorno) || vRetorno <= 0.01f || vRetorno >= Vs - 0.01f) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
float resistenciaNtc = NAN;
|
||||||
|
|
||||||
|
if (ntcGnd) {
|
||||||
|
/*
|
||||||
|
5 V
|
||||||
|
|
|
||||||
|
Rfixo
|
||||||
|
|
|
||||||
|
retorno
|
||||||
|
|
|
||||||
|
NTC
|
||||||
|
|
|
||||||
|
GND
|
||||||
|
A carga externa Rcarga fica em paralelo com o NTC.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const float rEquivalente = Rfixo * vRetorno / (Vs - vRetorno);
|
||||||
|
const float inversoRntc = (1.0f / rEquivalente) - (1.0f / Rcarga);
|
||||||
|
if (!isfinite(inversoRntc) || inversoRntc <= 0.0f)
|
||||||
|
return NAN;
|
||||||
|
resistenciaNtc = 1.0f / inversoRntc;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
5 V
|
||||||
|
|
|
||||||
|
NTC
|
||||||
|
|
|
||||||
|
retorno
|
||||||
|
|
|
||||||
|
Rfixo
|
||||||
|
|
|
||||||
|
GND
|
||||||
|
A carga externa Rcarga fica em paralelo com Rfixo.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const float rInferior = (Rfixo * Rcarga) / (Rfixo + Rcarga);
|
||||||
|
resistenciaNtc = rInferior * (Vs - vRetorno) / vRetorno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isfinite(resistenciaNtc) || resistenciaNtc <= 0.0f)
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
const float temperaturaK = 1.0f / ((1.0f / T0) + logf(resistenciaNtc / Rntc25) / Beta);
|
||||||
|
const float temperaturaC = temperaturaK - 273.15f + offset;
|
||||||
|
|
||||||
|
if (!isfinite(temperaturaC) || temperaturaC < -40.0f || temperaturaC > 150.0f) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return roundf(temperaturaC * 100.0f) / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,10 @@ Rele_v2* ObterRelePorId(uint8_t idNum) {
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region TEMPERATURA NTC
|
#pragma region TEMPERATURA NTC
|
||||||
SensorTemperaturaNtc sNTC_MotorET("TMVET", 1, 6, TiposBarramentos::CONTROLADOR, -1, 0.0f);
|
SensorTemperaturaNtc sNTC_MotorET("TMVET", 1, 6, TiposBarramentos::CONTROLADOR, -1, 0.0f, false);
|
||||||
SensorTemperaturaNtc sNTC_MotorDT("TMVDT", 3, 7, TiposBarramentos::CONTROLADOR, -1, 0.0f);
|
SensorTemperaturaNtc sNTC_MotorDT("TMVDT", 3, 7, TiposBarramentos::CONTROLADOR, -1, 0.0f, true);
|
||||||
SensorTemperaturaNtc sNTC_MotorEF("TMVEF", 2, 8, TiposBarramentos::CONTROLADOR, -1, 0.0f);
|
SensorTemperaturaNtc sNTC_MotorEF("TMVEF", 2, 8, TiposBarramentos::CONTROLADOR, -1, 0.0f, false);
|
||||||
SensorTemperaturaNtc sNTC_MotorDF("TMVDF", 4, 9, TiposBarramentos::CONTROLADOR, -1, 0.0f);
|
SensorTemperaturaNtc sNTC_MotorDF("TMVDF", 4, 9, TiposBarramentos::CONTROLADOR, -1, 0.0f, true);
|
||||||
|
|
||||||
SensorTemperaturaNtc* ObterTempNtcPorId(uint8_t idNum) {
|
SensorTemperaturaNtc* ObterTempNtcPorId(uint8_t idNum) {
|
||||||
switch (idNum) {
|
switch (idNum) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue