ajustes INA228

This commit is contained in:
Diego Freitas 2025-04-24 08:49:04 -03:00
parent a039e3c6a6
commit 3bad145819
17 changed files with 282 additions and 263 deletions

Binary file not shown.

View File

@ -71,6 +71,7 @@ namespace AgroBase.Forms
AtualizarDadosSensorCorrente("AB5V", lblB5V); AtualizarDadosSensorCorrente("AB5V", lblB5V);
AtualizarDadosSensorCorrente("AB7V2", lblB7V2); AtualizarDadosSensorCorrente("AB7V2", lblB7V2);
AtualizarDadosSensorCorrente("AB12V", lblB12V); AtualizarDadosSensorCorrente("AB12V", lblB12V);
AtualizarDadosSensorCorrente("AB36V", lblTensao);
} }
lblMagnetometro.ForeColor = (Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.DefaultIfEmpty()?.FirstOrDefault()?.Iniciado ?? false) ? Color.Green : Color.Red; lblMagnetometro.ForeColor = (Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.DefaultIfEmpty()?.FirstOrDefault()?.Iniciado ?? false) ? Color.Green : Color.Red;
@ -90,10 +91,7 @@ namespace AgroBase.Forms
var sensor = Variaveis.OperacaoEmAndamento.DispSen.Dados.DadosLeitura.SensoresCorrente.FirstOrDefault(x => x.ID == id); var sensor = Variaveis.OperacaoEmAndamento.DispSen.Dados.DadosLeitura.SensoresCorrente.FirstOrDefault(x => x.ID == id);
if (sensor != null) if (sensor != null)
{ {
double d0 = (double)sensor.Current; lbl.Text = $"{id.Replace("AB", "Barramento ")}: {sensor.BusVoltage.ToString("0.00")} V, {(sensor.Current ?? -1).ToString("0.00")} mA, {sensor.Power.ToString("0.00")} W, {sensor.Temperature.ToString("0.00")} ºC, {sensor.Energy.ToString("0.00")} Wh";
double d1 = sensor.BusVoltage;
lbl.Text = id.Replace("AB", "Barramento ") + ": " + d1.ToString("0.00") + " V " + d0.ToString("0.00") + " mA";
lbl.ForeColor = sensor.Iniciado ? Color.Green : Color.Red; lbl.ForeColor = sensor.Iniciado ? Color.Green : Color.Red;
} }
} }

View File

@ -365,6 +365,38 @@ namespace AgroBase.Models.Modules
} }
}, },
new SensorModel() new SensorModel()
{
ID = "AB36V",
Descricao = "Corrente no Barramento 36V",
ID_Num = 15,
Componente = S_Code.sCOR,
Aferir = true,
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.I2C,
},
UnidadeMedida = "A",
Parametros = new List<SensorParametroModel>()
{
new SensorParametroModel()
{
Descricao = "Endereço I2C",
Valor = "0x40",
QtdBytes = 1,
Escalar = false,
Enviar = true
},
new SensorParametroModel()
{
Descricao = "Corrente Máx",
Valor = (100).ToString(),
QtdBytes = 2,
Escalar = true,
Enviar = true
},
}
},
new SensorModel()
{ {
ID = "GY91", ID = "GY91",
Descricao = "Inclinometro", Descricao = "Inclinometro",
@ -1432,6 +1464,8 @@ namespace AgroBase.Models.Modules
} }
} }
public double Power { get; set; } public double Power { get; set; }
public double Energy { get; set; }
public double Temperature { get; set; }
public double ValorMaximo { get; set; } public double ValorMaximo { get; set; }
public double ValorMinimo { get; set; } public double ValorMinimo { get; set; }
@ -1912,6 +1946,12 @@ namespace AgroBase.Models.Modules
_sensor.Power = Parametros.Count > 2 ? Parametros[2] : -1; _sensor.Power = Parametros.Count > 2 ? Parametros[2] : -1;
break; break;
} }
case CanMessagePosicaoDados.Dados2:
{
_sensor.Energy = Parametros.Count > 0 ? Parametros[0] : -1;
_sensor.Temperature = Parametros.Count > 1 ? Parametros[1] : -1;
break;
}
} }
_sensor.Momento = DateTime.Now; _sensor.Momento = DateTime.Now;
} }
@ -2115,7 +2155,7 @@ namespace AgroBase.Models.Modules
S_Code componente = DetectarComponenteDoID_Num(ID_Num); S_Code componente = DetectarComponenteDoID_Num(ID_Num);
//Console.WriteLine($"[SEN] Componente={componente.ToString()}, ID_Num={ID_Num}, Posicao={posicao.ToString()}, Data={FuncoesGlobais.ConverterComandoBytesParaTexto(data)}"); Console.WriteLine($"[SEN] Componente={componente.ToString()}, ID_Num={ID_Num}, Posicao={posicao.ToString()}, Data={FuncoesGlobais.ConverterComandoBytesParaTexto(data)}");
switch (posicao) switch (posicao)
{ {
@ -2153,7 +2193,7 @@ namespace AgroBase.Models.Modules
case S_Code.sCOR: case S_Code.sCOR:
{ {
double busVoltage = ConverterByteParaDouble(data, 2); double busVoltage = ConverterByteParaDouble(data, 2);
double current = ConverterByteParaDouble(data, 4); double current = ConverterByteParaDouble(data, 4) * 10;
double power = ConverterByteParaDouble(data, 6); double power = ConverterByteParaDouble(data, 6);
DefinirOuCriar(ID_Num, posicao, componente, new List<dynamic>() { busVoltage, current, power }); DefinirOuCriar(ID_Num, posicao, componente, new List<dynamic>() { busVoltage, current, power });
break; break;
@ -2199,6 +2239,13 @@ namespace AgroBase.Models.Modules
{ {
switch (componente) switch (componente)
{ {
case S_Code.sCOR:
{
double energia = ConverterByteParaDouble(data, 2);
double temperatura = ConverterByteParaDouble(data, 4);
DefinirOuCriar(ID_Num, posicao, componente, new List<dynamic>() { energia, temperatura });
break;
}
case S_Code.sIMU: case S_Code.sIMU:
{ {
double temperatura = ConverterByteParaDouble(data, 2); double temperatura = ConverterByteParaDouble(data, 2);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -25,7 +25,7 @@
<meta name="viewport" content="width=device-width, <meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style> <style>
#map_7f2f505618d18ff23c11f62484118a2c { #map_627e1913ffb6ce0524d1e3cdac7f538e {
position: relative; position: relative;
width: 100.0%; width: 100.0%;
height: 100.0%; height: 100.0%;
@ -39,14 +39,14 @@
<body> <body>
<div class="folium-map" id="map_7f2f505618d18ff23c11f62484118a2c" ></div> <div class="folium-map" id="map_627e1913ffb6ce0524d1e3cdac7f538e" ></div>
</body> </body>
<script> <script>
var map_7f2f505618d18ff23c11f62484118a2c = L.map( var map_627e1913ffb6ce0524d1e3cdac7f538e = L.map(
"map_7f2f505618d18ff23c11f62484118a2c", "map_627e1913ffb6ce0524d1e3cdac7f538e",
{ {
center: [0.0, 0.0], center: [0.0, 0.0],
crs: L.CRS.EPSG3857, crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_4c72109091f8651b6e2b819865fbc3d5 = L.tileLayer( var tile_layer_ae5289bcde884732f0a974c70cdf1be8 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png", "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false} {"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
); );
tile_layer_4c72109091f8651b6e2b819865fbc3d5.addTo(map_7f2f505618d18ff23c11f62484118a2c); tile_layer_ae5289bcde884732f0a974c70cdf1be8.addTo(map_627e1913ffb6ce0524d1e3cdac7f538e);
</script> </script>
@ -87,7 +87,7 @@
} }
trajeto_json_add({"features": []}); trajeto_json_add({"features": []});
trajeto_json.addTo(map_7f2f505618d18ff23c11f62484118a2c); trajeto_json.addTo(map_627e1913ffb6ce0524d1e3cdac7f538e);
function adicionarGeometria(novaGeometria) { function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria); trajeto_json.addData(novaGeometria);
@ -145,7 +145,7 @@
var marcadorDinamico = L.marker([0, 0], { var marcadorDinamico = L.marker([0, 0], {
icon: customIcon icon: customIcon
}).addTo(map_7f2f505618d18ff23c11f62484118a2c); }).addTo(map_627e1913ffb6ce0524d1e3cdac7f538e);
// Conectar ao broker MQTT // Conectar ao broker MQTT
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
@ -183,7 +183,7 @@
marcadorDinamico.setRotationAngle(angulo); marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]); adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_7f2f505618d18ff23c11f62484118a2c.setView(novaPosicao, map_7f2f505618d18ff23c11f62484118a2c.getZoom()); map_627e1913ffb6ce0524d1e3cdac7f538e.setView(novaPosicao, map_627e1913ffb6ce0524d1e3cdac7f538e.getZoom());
}); });
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) { function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

File diff suppressed because one or more lines are too long

View File

@ -228,9 +228,9 @@ void ProcessarCfg(std::vector<uint8_t> data) {
PrintTela("I2C inicializado nos pinos SDA=" + String(pinoSDA) + " e SCL=" + String(pinoSCL)); PrintTela("I2C inicializado nos pinos SDA=" + String(pinoSDA) + " e SCL=" + String(pinoSCL));
} }
vTaskDelay(pdMS_TO_TICKS(100)); vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
_chkRx = canService.MontarFrameChk(D_Code, Conectado, VERSION); _chkRx = canService.MontarFrameChk(D_Code, Conectado, VERSION);
LimparListasComponentes(); LimparListasComponentes();
Conectado = Conectar;
PrintTela("Configuracao do modulo concluida"); PrintTela("Configuracao do modulo concluida");
break; break;
} }

View File

@ -0,0 +1,193 @@
#ifndef SensorCorrenteINA228Model
#define SensorCorrenteINA228Model
#include "SerialService.h"
#include "Pinout.h"
#include "Utils.h"
#include <Wire.h>
#include <vector>
class SensorCorrenteINA228 {
public:
SensorCorrenteINA228(String _modID, String _id) {
Mod_ID = _modID;
_ID = _id;
}
String Mod_ID = "";
String _ID;
int ID_Num;
byte _Endereco;
float _A_Shunt = 10.0;
bool Iniciado = false;
float busVoltage = 0;
float current = 0;
float power = 0;
float energy = 0;
float temperature = 0;
void Inicializar() {
if (Iniciado) {
PrintTela(_ID + " ja inicializado");
return;
}
Wire.beginTransmission(_Endereco);
byte error = Wire.endTransmission();
if (error == 0) {
Iniciado = true;
EscreverRegistradorINA(0x00, 0x8000); // Bit 15 = 1 → RESET
delay(2);
if (_A_Shunt == 10.0) {
currentLSB = 0.0001; // Mantém como já aprovado nos testes
} else if (_A_Shunt == 50.0) {
currentLSB = 0.00005; // 50 / 0.00005 = 1.000.000 → perto do limite
} else if (_A_Shunt == 100.0) {
currentLSB = 0.0001; // 100 / 0.0001 = 1.000.000 → ótimo
}
} else {
Iniciado = false;
PrintTela(_ID + " nao iniciado, endereco " + _Endereco + " nao encontrado!");
}
}
void Desligar() {
if (!Iniciado) {
PrintTela(_ID + " nao esta inicializado");
return;
}
Iniciado = false;
PrintTela(_ID + " Desligado");
}
void RequisitarDados() {
if (!Iniciado) return;
AferirCorrente();
}
std::vector<uint8_t> MontarMensagemCAN(CanMessagePosicaoDados posicao) {
std::vector<uint8_t> data;
data.push_back(ID_Num);
data.push_back(static_cast<uint8_t>(posicao));
switch (posicao) {
case CanMessagePosicaoDados::Status: {
data.push_back(Iniciado ? 1 : 0);
break;
}
case CanMessagePosicaoDados::Dados1: {
uint16_t volts = busVoltage * 100;
uint16_t amps = current * 100;
uint16_t watts = power * 10;
data.push_back(volts >> 8); data.push_back(volts & 0xFF);
data.push_back(amps >> 8); data.push_back(amps & 0xFF);
data.push_back(watts >> 8); data.push_back(watts & 0xFF);
break;
}
case CanMessagePosicaoDados::Dados2: {
uint16_t wh = energy * 10;
uint16_t temp = temperature * 100;
data.push_back(wh >> 8); data.push_back(wh & 0xFF);
data.push_back(temp >> 8); data.push_back(temp & 0xFF);
break;
}
}
return data;
}
static std::vector<uint8_t> ConfigurarSensor(std::vector<SensorCorrenteINA228*>& lista, std::vector<uint8_t>& data, const String& Mod_ID) {
std::vector<uint8_t> status;
if (data.size() < 3) return status;
uint8_t idNum = data[1];
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[2];
auto it = std::find_if(lista.begin(), lista.end(), [idNum](SensorCorrenteINA228* s) { return s->ID_Num == idNum; });
bool jaExiste = it != lista.end();
SensorCorrenteINA228* sensor;
switch (posicao) {
case CanMessagePosicaoDados::Config1: {
if (data.size() < 8) return status;
bool conectar = data[4] == 1;
uint8_t endereco = data[5];
uint16_t aMaxInt = ((uint16_t)data[6] << 8) | data[7];
float aMax = aMaxInt / 100.0;
if (conectar) {
if (!jaExiste) {
sensor = new SensorCorrenteINA228(Mod_ID, "sCOR_" + String(idNum));
} else {
sensor = *it;
}
if (!sensor->Iniciado) {
sensor->ID_Num = idNum;
sensor->_Endereco = endereco;
sensor->_A_Shunt = aMax;
sensor->Inicializar();
if (!jaExiste) {
lista.push_back(sensor);
PrintTela("Sensor INA228 adicionado via CAN: sCOR_" + String(idNum));
}
}
status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status);
} else {
if (jaExiste) {
sensor = *it;
sensor->Desligar();
status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status);
delete sensor;
lista.erase(it);
PrintTela("Sensor INA228 removido via CAN: sCOR_" + String(idNum));
}
}
break;
}
}
return status;
}
private:
float shuntLSB = 1.0e-6;
float currentLSB = 0.000003;
float VbusLSB = 1.23e-5;
uint32_t LerRegistradorINA(uint8_t reg, uint8_t bytes) {
Wire.beginTransmission(_Endereco);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(_Endereco, bytes);
uint32_t valor = 0;
for (uint8_t i = 0; i < bytes; i++) {
valor = (valor << 8) | Wire.read();
}
return valor;
}
void EscreverRegistradorINA(uint8_t reg, uint16_t valor) {
Wire.beginTransmission(_Endereco);
Wire.write(reg);
Wire.write((valor >> 8) & 0xFF); // MSB
Wire.write(valor & 0xFF); // LSB
Wire.endTransmission();
}
void AferirCorrente() {
if (!Iniciado) return;
uint32_t rawBus = LerRegistradorINA(0x05, 3);
uint32_t rawCurrent = LerRegistradorINA(0x07, 3);
uint32_t rawPower = LerRegistradorINA(0x08, 3);
uint64_t rawEnergy = ((uint64_t)LerRegistradorINA(0x0A, 3) << 16) | LerRegistradorINA(0x0B, 2);
uint16_t rawTemp = LerRegistradorINA(0x0F, 2);
//busVoltage = rawBus * 3.125e-6;
busVoltage = rawBus * VbusLSB;
power = rawPower * currentLSB * 3.125;
current = rawCurrent * currentLSB;
energy = rawEnergy * currentLSB * 3.125 * 16 / 3600.0;
temperature = ((int16_t)rawTemp) * 0.0078125;
}
};
#endif

View File

@ -9,7 +9,7 @@
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\Utils.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\Utils.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\Pinout.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\Pinout.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorTemperaturaModel.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorTemperaturaModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorCorrenteModel.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorCorrenteINA228Model.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorIMUModel.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorIMUModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SinaleiroModel.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SinaleiroModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ReleModel.h" #include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ReleModel.h"
@ -41,7 +41,7 @@ PinoModel _pinoSCL = PinoModel(2, CONTROLADOR, _INPUT);
std::vector<SensorTemperatura*> listaSensoresTemperatura; std::vector<SensorTemperatura*> listaSensoresTemperatura;
std::vector<SensorCorrente*> listaSensoresCorrente; std::vector<SensorCorrenteINA228*> listaSensoresCorrente;
std::vector<Sinaleiro*> listaSinaleiros; std::vector<Sinaleiro*> listaSinaleiros;
std::vector<Rele*> listaReles; std::vector<Rele*> listaReles;
std::vector<ServoFreio*> listaServoFreios; std::vector<ServoFreio*> listaServoFreios;
@ -118,6 +118,7 @@ void enviarDadosSensores() {
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status)); EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
} }
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1)); EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados2));
} }
} }
@ -232,9 +233,9 @@ void ProcessarCfg(std::vector<uint8_t> data) {
PrintTela("I2C inicializado nos pinos SDA=" + String(pinoSDA) + " e SCL=" + String(pinoSCL)); PrintTela("I2C inicializado nos pinos SDA=" + String(pinoSDA) + " e SCL=" + String(pinoSCL));
} }
vTaskDelay(pdMS_TO_TICKS(100)); vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
_chkRx = canService.MontarFrameChk(D_Code, Conectado, VERSION); _chkRx = canService.MontarFrameChk(D_Code, Conectado, VERSION);
LimparListasComponentes(); LimparListasComponentes();
Conectado = Conectar;
PrintTela("Configuracao do modulo concluida"); PrintTela("Configuracao do modulo concluida");
break; break;
} }
@ -246,7 +247,7 @@ void ProcessarCfg(std::vector<uint8_t> data) {
break; break;
} }
case sCOR: { case sCOR: {
_chkRx = SensorCorrente::ConfigurarSensor(listaSensoresCorrente, data, Mod_ID); _chkRx = SensorCorrenteINA228::ConfigurarSensor(listaSensoresCorrente, data, Mod_ID);
break; break;
} }
case sLED: { case sLED: {