adicionado fluxo de balanceamento de carga mov

This commit is contained in:
Diego Freitas 2024-01-31 09:16:02 -03:00
parent 1dfab912a7
commit eb02e4e8a2
21 changed files with 1411 additions and 65 deletions

Binary file not shown.

View File

@ -30,7 +30,6 @@ namespace AgroBase.Forms.Movimentacao
private void InitializeComponent()
{
this.gpbSentido = new System.Windows.Forms.GroupBox();
this.btnSalvarSentido = new System.Windows.Forms.Button();
this.gpbDF = new System.Windows.Forms.GroupBox();
this.cmbDFFrente = new System.Windows.Forms.ComboBox();
this.cmbDFTras = new System.Windows.Forms.ComboBox();
@ -83,6 +82,11 @@ namespace AgroBase.Forms.Movimentacao
this.lblRampaMin = new System.Windows.Forms.Label();
this.nudRampaMax = new System.Windows.Forms.NumericUpDown();
this.nudRampaMin = new System.Windows.Forms.NumericUpDown();
this.lblMargemRPM = new System.Windows.Forms.Label();
this.nudMargemRPM = new System.Windows.Forms.NumericUpDown();
this.lblDelayBalanceamento = new System.Windows.Forms.Label();
this.nudDelayBalancemaneto = new System.Windows.Forms.NumericUpDown();
this.btnSalvarSentido = new System.Windows.Forms.Button();
this.gpbSentido.SuspendLayout();
this.gpbDF.SuspendLayout();
this.gpbEF.SuspendLayout();
@ -93,11 +97,12 @@ namespace AgroBase.Forms.Movimentacao
((System.ComponentModel.ISupportInitialize)(this.nudPPR)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudRampaMax)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudRampaMin)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudMargemRPM)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudDelayBalancemaneto)).BeginInit();
this.SuspendLayout();
//
// gpbSentido
//
this.gpbSentido.Controls.Add(this.btnSalvarSentido);
this.gpbSentido.Controls.Add(this.gpbDF);
this.gpbSentido.Controls.Add(this.gpbEF);
this.gpbSentido.Controls.Add(this.gpbDT);
@ -106,22 +111,11 @@ namespace AgroBase.Forms.Movimentacao
this.gpbSentido.Margin = new System.Windows.Forms.Padding(2);
this.gpbSentido.Name = "gpbSentido";
this.gpbSentido.Padding = new System.Windows.Forms.Padding(2);
this.gpbSentido.Size = new System.Drawing.Size(379, 345);
this.gpbSentido.Size = new System.Drawing.Size(379, 308);
this.gpbSentido.TabIndex = 40;
this.gpbSentido.TabStop = false;
this.gpbSentido.Text = "Sentido de giro";
//
// btnSalvarSentido
//
this.btnSalvarSentido.Location = new System.Drawing.Point(196, 310);
this.btnSalvarSentido.Margin = new System.Windows.Forms.Padding(2);
this.btnSalvarSentido.Name = "btnSalvarSentido";
this.btnSalvarSentido.Size = new System.Drawing.Size(168, 24);
this.btnSalvarSentido.TabIndex = 8;
this.btnSalvarSentido.Text = "Salvar";
this.btnSalvarSentido.UseVisualStyleBackColor = true;
this.btnSalvarSentido.Click += new System.EventHandler(this.btnSalvarSentido_Click);
//
// gpbDF
//
this.gpbDF.Controls.Add(this.cmbDFFrente);
@ -504,7 +498,10 @@ namespace AgroBase.Forms.Movimentacao
//
// groupBox1
//
this.groupBox1.Controls.Add(this.chbMalhaFechada);
this.groupBox1.Controls.Add(this.lblMargemRPM);
this.groupBox1.Controls.Add(this.nudMargemRPM);
this.groupBox1.Controls.Add(this.lblDelayBalanceamento);
this.groupBox1.Controls.Add(this.nudDelayBalancemaneto);
this.groupBox1.Controls.Add(this.gpbPID);
this.groupBox1.Controls.Add(this.btnSalvarPID);
this.groupBox1.Controls.Add(this.lblPPR);
@ -513,7 +510,7 @@ namespace AgroBase.Forms.Movimentacao
this.groupBox1.Controls.Add(this.lblRampaMin);
this.groupBox1.Controls.Add(this.nudRampaMax);
this.groupBox1.Controls.Add(this.nudRampaMin);
this.groupBox1.Location = new System.Drawing.Point(11, 361);
this.groupBox1.Location = new System.Drawing.Point(11, 323);
this.groupBox1.Margin = new System.Windows.Forms.Padding(2);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(2);
@ -527,7 +524,7 @@ namespace AgroBase.Forms.Movimentacao
this.chbMalhaFechada.AutoSize = true;
this.chbMalhaFechada.Checked = true;
this.chbMalhaFechada.CheckState = System.Windows.Forms.CheckState.Checked;
this.chbMalhaFechada.Location = new System.Drawing.Point(262, 40);
this.chbMalhaFechada.Location = new System.Drawing.Point(17, 17);
this.chbMalhaFechada.Margin = new System.Windows.Forms.Padding(2);
this.chbMalhaFechada.Name = "chbMalhaFechada";
this.chbMalhaFechada.Size = new System.Drawing.Size(100, 17);
@ -542,13 +539,15 @@ namespace AgroBase.Forms.Movimentacao
this.gpbPID.Controls.Add(this.txtKp);
this.gpbPID.Controls.Add(this.lblKi);
this.gpbPID.Controls.Add(this.txtKi);
this.gpbPID.Controls.Add(this.chbMalhaFechada);
this.gpbPID.Controls.Add(this.lblKd);
this.gpbPID.Controls.Add(this.txtKd);
this.gpbPID.Location = new System.Drawing.Point(4, 71);
this.gpbPID.Enabled = false;
this.gpbPID.Location = new System.Drawing.Point(4, 60);
this.gpbPID.Margin = new System.Windows.Forms.Padding(2);
this.gpbPID.Name = "gpbPID";
this.gpbPID.Padding = new System.Windows.Forms.Padding(2);
this.gpbPID.Size = new System.Drawing.Size(268, 61);
this.gpbPID.Size = new System.Drawing.Size(268, 76);
this.gpbPID.TabIndex = 37;
this.gpbPID.TabStop = false;
this.gpbPID.Text = "PID";
@ -556,7 +555,7 @@ namespace AgroBase.Forms.Movimentacao
// lblKp
//
this.lblKp.AutoSize = true;
this.lblKp.Location = new System.Drawing.Point(14, 29);
this.lblKp.Location = new System.Drawing.Point(14, 44);
this.lblKp.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblKp.Name = "lblKp";
this.lblKp.Size = new System.Drawing.Size(20, 13);
@ -565,7 +564,7 @@ namespace AgroBase.Forms.Movimentacao
//
// txtKp
//
this.txtKp.Location = new System.Drawing.Point(37, 27);
this.txtKp.Location = new System.Drawing.Point(37, 42);
this.txtKp.Margin = new System.Windows.Forms.Padding(2);
this.txtKp.Name = "txtKp";
this.txtKp.Size = new System.Drawing.Size(46, 20);
@ -576,7 +575,7 @@ namespace AgroBase.Forms.Movimentacao
// lblKi
//
this.lblKi.AutoSize = true;
this.lblKi.Location = new System.Drawing.Point(101, 29);
this.lblKi.Location = new System.Drawing.Point(101, 44);
this.lblKi.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblKi.Name = "lblKi";
this.lblKi.Size = new System.Drawing.Size(16, 13);
@ -585,7 +584,7 @@ namespace AgroBase.Forms.Movimentacao
//
// txtKi
//
this.txtKi.Location = new System.Drawing.Point(121, 27);
this.txtKi.Location = new System.Drawing.Point(121, 42);
this.txtKi.Margin = new System.Windows.Forms.Padding(2);
this.txtKi.Name = "txtKi";
this.txtKi.Size = new System.Drawing.Size(46, 20);
@ -596,7 +595,7 @@ namespace AgroBase.Forms.Movimentacao
// lblKd
//
this.lblKd.AutoSize = true;
this.lblKd.Location = new System.Drawing.Point(184, 29);
this.lblKd.Location = new System.Drawing.Point(184, 44);
this.lblKd.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblKd.Name = "lblKd";
this.lblKd.Size = new System.Drawing.Size(20, 13);
@ -605,7 +604,7 @@ namespace AgroBase.Forms.Movimentacao
//
// txtKd
//
this.txtKd.Location = new System.Drawing.Point(207, 27);
this.txtKd.Location = new System.Drawing.Point(207, 42);
this.txtKd.Margin = new System.Windows.Forms.Padding(2);
this.txtKd.Name = "txtKd";
this.txtKd.Size = new System.Drawing.Size(46, 20);
@ -615,28 +614,28 @@ namespace AgroBase.Forms.Movimentacao
//
// btnSalvarPID
//
this.btnSalvarPID.Location = new System.Drawing.Point(277, 93);
this.btnSalvarPID.Location = new System.Drawing.Point(276, 109);
this.btnSalvarPID.Margin = new System.Windows.Forms.Padding(2);
this.btnSalvarPID.Name = "btnSalvarPID";
this.btnSalvarPID.Size = new System.Drawing.Size(98, 27);
this.btnSalvarPID.TabIndex = 28;
this.btnSalvarPID.Text = "Salvar";
this.btnSalvarPID.Text = "Editar";
this.btnSalvarPID.UseVisualStyleBackColor = true;
this.btnSalvarPID.Click += new System.EventHandler(this.btnSalvarPID_Click);
//
// lblPPR
//
this.lblPPR.AutoSize = true;
this.lblPPR.Location = new System.Drawing.Point(183, 23);
this.lblPPR.Location = new System.Drawing.Point(154, 18);
this.lblPPR.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblPPR.Name = "lblPPR";
this.lblPPR.Size = new System.Drawing.Size(32, 13);
this.lblPPR.Size = new System.Drawing.Size(29, 13);
this.lblPPR.TabIndex = 36;
this.lblPPR.Text = "PPR:";
this.lblPPR.Text = "PPR";
//
// nudPPR
//
this.nudPPR.Location = new System.Drawing.Point(185, 39);
this.nudPPR.Location = new System.Drawing.Point(156, 34);
this.nudPPR.Margin = new System.Windows.Forms.Padding(2);
this.nudPPR.Maximum = new decimal(new int[] {
999,
@ -653,7 +652,7 @@ namespace AgroBase.Forms.Movimentacao
this.nudPPR.TabIndex = 35;
this.nudPPR.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudPPR.Value = new decimal(new int[] {
40,
22,
0,
0,
0});
@ -662,26 +661,26 @@ namespace AgroBase.Forms.Movimentacao
// lblRampaMax
//
this.lblRampaMax.AutoSize = true;
this.lblRampaMax.Location = new System.Drawing.Point(93, 23);
this.lblRampaMax.Location = new System.Drawing.Point(83, 18);
this.lblRampaMax.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblRampaMax.Name = "lblRampaMax";
this.lblRampaMax.Size = new System.Drawing.Size(67, 13);
this.lblRampaMax.Size = new System.Drawing.Size(64, 13);
this.lblRampaMax.TabIndex = 34;
this.lblRampaMax.Text = "Rampa Max:";
this.lblRampaMax.Text = "Rampa Max";
//
// lblRampaMin
//
this.lblRampaMin.AutoSize = true;
this.lblRampaMin.Location = new System.Drawing.Point(11, 23);
this.lblRampaMin.Location = new System.Drawing.Point(11, 18);
this.lblRampaMin.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblRampaMin.Name = "lblRampaMin";
this.lblRampaMin.Size = new System.Drawing.Size(64, 13);
this.lblRampaMin.Size = new System.Drawing.Size(61, 13);
this.lblRampaMin.TabIndex = 33;
this.lblRampaMin.Text = "Rampa Min:";
this.lblRampaMin.Text = "Rampa Min";
//
// nudRampaMax
//
this.nudRampaMax.Location = new System.Drawing.Point(95, 39);
this.nudRampaMax.Location = new System.Drawing.Point(85, 34);
this.nudRampaMax.Margin = new System.Windows.Forms.Padding(2);
this.nudRampaMax.Maximum = new decimal(new int[] {
9999,
@ -693,7 +692,7 @@ namespace AgroBase.Forms.Movimentacao
this.nudRampaMax.TabIndex = 32;
this.nudRampaMax.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudRampaMax.Value = new decimal(new int[] {
4095,
1023,
0,
0,
0});
@ -701,7 +700,7 @@ namespace AgroBase.Forms.Movimentacao
//
// nudRampaMin
//
this.nudRampaMin.Location = new System.Drawing.Point(14, 39);
this.nudRampaMin.Location = new System.Drawing.Point(14, 34);
this.nudRampaMin.Margin = new System.Windows.Forms.Padding(2);
this.nudRampaMin.Maximum = new decimal(new int[] {
9999,
@ -714,12 +713,84 @@ namespace AgroBase.Forms.Movimentacao
this.nudRampaMin.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudRampaMin.ValueChanged += new System.EventHandler(this.nudRampaMin_ValueChanged);
//
// lblMargemRPM
//
this.lblMargemRPM.AutoSize = true;
this.lblMargemRPM.Location = new System.Drawing.Point(296, 18);
this.lblMargemRPM.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblMargemRPM.Name = "lblMargemRPM";
this.lblMargemRPM.Size = new System.Drawing.Size(72, 13);
this.lblMargemRPM.TabIndex = 41;
this.lblMargemRPM.Text = "Margem RPM";
//
// nudMargemRPM
//
this.nudMargemRPM.Location = new System.Drawing.Point(298, 34);
this.nudMargemRPM.Margin = new System.Windows.Forms.Padding(2);
this.nudMargemRPM.Maximum = new decimal(new int[] {
99,
0,
0,
0});
this.nudMargemRPM.Name = "nudMargemRPM";
this.nudMargemRPM.Size = new System.Drawing.Size(57, 20);
this.nudMargemRPM.TabIndex = 40;
this.nudMargemRPM.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudMargemRPM.Value = new decimal(new int[] {
5,
0,
0,
0});
this.nudMargemRPM.ValueChanged += new System.EventHandler(this.nudMargemRPM_ValueChanged);
//
// lblDelayBalanceamento
//
this.lblDelayBalanceamento.AutoSize = true;
this.lblDelayBalanceamento.Location = new System.Drawing.Point(225, 18);
this.lblDelayBalanceamento.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblDelayBalanceamento.Name = "lblDelayBalanceamento";
this.lblDelayBalanceamento.Size = new System.Drawing.Size(64, 13);
this.lblDelayBalanceamento.TabIndex = 39;
this.lblDelayBalanceamento.Text = "Delay Balan";
//
// nudDelayBalancemaneto
//
this.nudDelayBalancemaneto.Location = new System.Drawing.Point(227, 34);
this.nudDelayBalancemaneto.Margin = new System.Windows.Forms.Padding(2);
this.nudDelayBalancemaneto.Maximum = new decimal(new int[] {
99999,
0,
0,
0});
this.nudDelayBalancemaneto.Name = "nudDelayBalancemaneto";
this.nudDelayBalancemaneto.Size = new System.Drawing.Size(57, 20);
this.nudDelayBalancemaneto.TabIndex = 38;
this.nudDelayBalancemaneto.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudDelayBalancemaneto.Value = new decimal(new int[] {
2000,
0,
0,
0});
this.nudDelayBalancemaneto.ValueChanged += new System.EventHandler(this.nudDelayBalancemaneto_ValueChanged);
//
// btnSalvarSentido
//
this.btnSalvarSentido.Location = new System.Drawing.Point(222, 477);
this.btnSalvarSentido.Margin = new System.Windows.Forms.Padding(2);
this.btnSalvarSentido.Name = "btnSalvarSentido";
this.btnSalvarSentido.Size = new System.Drawing.Size(168, 24);
this.btnSalvarSentido.TabIndex = 136;
this.btnSalvarSentido.Text = "Salvar";
this.btnSalvarSentido.UseVisualStyleBackColor = true;
this.btnSalvarSentido.Click += new System.EventHandler(this.btnSalvarSentido_Click);
//
// frmMovConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(398, 512);
this.Controls.Add(this.btnSalvarSentido);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.gpbSentido);
this.Margin = new System.Windows.Forms.Padding(2);
@ -744,6 +815,8 @@ namespace AgroBase.Forms.Movimentacao
((System.ComponentModel.ISupportInitialize)(this.nudPPR)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudRampaMax)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudRampaMin)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudMargemRPM)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudDelayBalancemaneto)).EndInit();
this.ResumeLayout(false);
}
@ -760,7 +833,6 @@ namespace AgroBase.Forms.Movimentacao
private System.Windows.Forms.Label lblDFTras;
private System.Windows.Forms.Label lblDFFrente;
private System.Windows.Forms.GroupBox gpbEF;
private System.Windows.Forms.Button btnSalvarSentido;
private System.Windows.Forms.ComboBox cmbEFFrente;
private System.Windows.Forms.ComboBox cmbEFTras;
private System.Windows.Forms.ComboBox cmbEFDireita;
@ -803,5 +875,10 @@ namespace AgroBase.Forms.Movimentacao
private System.Windows.Forms.Label lblRampaMin;
private System.Windows.Forms.NumericUpDown nudRampaMax;
private System.Windows.Forms.NumericUpDown nudRampaMin;
private System.Windows.Forms.Label lblMargemRPM;
private System.Windows.Forms.NumericUpDown nudMargemRPM;
private System.Windows.Forms.Label lblDelayBalanceamento;
private System.Windows.Forms.NumericUpDown nudDelayBalancemaneto;
private System.Windows.Forms.Button btnSalvarSentido;
}
}

View File

@ -24,6 +24,8 @@ namespace AgroBase.Forms.Movimentacao
nudRampaMin.Value = MovimentacaoModel.RampaMin;
nudRampaMax.Value = MovimentacaoModel.RampaMax;
nudPPR.Value = MovimentacaoModel.PulsosPorRevolucao;
nudDelayBalancemaneto.Value = MovimentacaoModel._DelayBalanceamento;
nudMargemRPM.Value = MovimentacaoModel._MargemRPM;
chbMalhaFechada.Checked = MovimentacaoModel._FOC;
txtKd.Text = MovimentacaoModel.Kd.ToString();
txtKp.Text = MovimentacaoModel.Kp.ToString();
@ -116,18 +118,27 @@ namespace AgroBase.Forms.Movimentacao
private void btnSalvarPID_Click(object sender, EventArgs e)
{
if (double.TryParse(txtKp.Text, out double kp))
if (btnSalvarPID.Text == "Editar")
{
MovimentacaoModel.Kp = kp;
btnSalvarPID.Text = "Salvar";
}
if (double.TryParse(txtKi.Text, out double ki))
else
{
MovimentacaoModel.Ki = ki;
}
if (double.TryParse(txtKd.Text, out double kd))
{
MovimentacaoModel.Kd = kd;
btnSalvarPID.Text = "Editar";
if (double.TryParse(txtKp.Text, out double kp))
{
MovimentacaoModel.Kp = kp;
}
if (double.TryParse(txtKi.Text, out double ki))
{
MovimentacaoModel.Ki = ki;
}
if (double.TryParse(txtKd.Text, out double kd))
{
MovimentacaoModel.Kd = kd;
}
}
gpbPID.Enabled = btnSalvarPID.Text == "Salvar";
}
private void nudRampaMin_ValueChanged(object sender, EventArgs e)
@ -144,5 +155,15 @@ namespace AgroBase.Forms.Movimentacao
{
MovimentacaoModel.PulsosPorRevolucao = Convert.ToInt32(nudPPR.Value);
}
private void nudDelayBalancemaneto_ValueChanged(object sender, EventArgs e)
{
MovimentacaoModel._DelayBalanceamento = Convert.ToInt32(nudDelayBalancemaneto.Value);
}
private void nudMargemRPM_ValueChanged(object sender, EventArgs e)
{
MovimentacaoModel._MargemRPM = Convert.ToInt32(nudMargemRPM.Value);
}
}
}

View File

@ -160,6 +160,13 @@ namespace AgroBase.Forms
Minimo = Logs.Min(x => x.RPM) < Minimo ? Logs.Min(x => x.RPM) : Minimo;
Maximo = Logs.Max(x => x.RPM) > Maximo ? Logs.Max(x => x.RPM) : Maximo;
var serieRPMOffset = new Series("RPM Offset: " + (Log != null ? Log.RPM_Offset : 0));
serieRPMOffset.Points.DataBindXY(Momentos, Logs.Select(x => x.RPM_Offset).ToList());
serieRPMOffset.ChartType = SeriesChartType.Spline;
chart.Series.Add(serieRPMOffset);
Minimo = Logs.Min(x => x.RPM_Offset) < Minimo ? Logs.Min(x => x.RPM_Offset) : Minimo;
Maximo = Logs.Max(x => x.RPM_Offset) > Maximo ? Logs.Max(x => x.RPM_Offset) : Maximo;
var seriePotencia = new Series("Potencia: " + (Log != null ? Log.Potencia : 0));
seriePotencia.Points.DataBindXY(Momentos, Logs.Select(x => x.Potencia).ToList());
seriePotencia.ChartType = SeriesChartType.Line;

View File

@ -17,12 +17,14 @@ namespace AgroBase.Models
{
public static int _TaxaAmostragem { get; set; } = 500;
public static int RampaMin { get; set; } = 0;
public static int RampaMax { get; set; } = 4095;
public static int RampaMax { get; set; } = 1023;
public static int PulsosPorRevolucao { get; set; } = 22;
public static bool _FOC { get; set; } = true;
public static double Kp { get; set; } = 1.85;
public static double Ki { get; set; } = 2.1;
public static double Kd { get; set; } = 0.08;
public static int _DelayBalanceamento { get; set; } = 2000;
public static int _MargemRPM { get; set; } = 5;
public static double DiametroRoda { get; set; } = 0.3556;
public bool Conectado { get; set; } = false;
public static int LogsManter { get; set; } = 60;
@ -36,6 +38,7 @@ namespace AgroBase.Models
public Timer tmrRegistrador { get; set; }
public static MovimentacaoModel CarregarParametrosIniciais()
{
return new MovimentacaoModel()
@ -139,8 +142,10 @@ namespace AgroBase.Models
_TaxaAmostragem.ToString("00000") + ";" + // 5 ~ 9
(Pinout.Any(x => x.Funcao == FuncoesPinout.Geral) ? Pinout.FirstOrDefault(x => x.Funcao == FuncoesPinout.Geral).Pino.ToString("00") : "-1") + ";" + // 11 ~ 12
RampaMin.ToString("0000") + ";" + // 14 ~ 17
RampaMax.ToString("0000"); // 19 ~ 22
PulsosPorRevolucao.ToString("000"); // 24 ~ 26
RampaMax.ToString("0000") + // 19 ~ 22
PulsosPorRevolucao.ToString("000") + // 24 ~ 26
_DelayBalanceamento.ToString("000") + // 28 ~ 32
_MargemRPM.ToString("00");// 34 ~ 35
Config.Add(ProtocoloMOD);
return Config;
}
@ -182,6 +187,9 @@ namespace AgroBase.Models
int.TryParse(Dados[5], out sentido);
Motor.Sentido = (Sentido)sentido;
Motor.Revertendo = Dados[6] == "1";
double rpm_offset = 0;
double.TryParse(Dados[7].Replace(".", ","), out rpm_offset);
Motor.RPM_Offset = rpm_offset;
AtualizaGrafico = true;
break;
}
@ -246,6 +254,7 @@ namespace AgroBase.Models
ComponenteID = Motor.ID,
RPM_SP = Motor.RPM_SP,
RPM = Motor.RPM,
RPM_Offset = Motor.RPM_Offset,
Periodo = Motor.Intervalo,
Potencia = Motor.Potencia,
PotenciaSP = Motor.Potencia_SP,
@ -306,6 +315,7 @@ namespace AgroBase.Models
frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clStatus", "Status");
frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clPotencia", "Potencia");
frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clRPM", "RPM");
frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clRPMOffset", "RPM Offset");
frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clVelocidade", "Velocidade");
frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clTemperatura", "Temperatura");
//frmInstancial.frmPrincipal.gridSenMotores.Columns.Add("clUmidade", "Umidade");
@ -320,6 +330,7 @@ namespace AgroBase.Models
Enum.GetName(typeof(StatusMotor), Motor.Aceleracao),
Motor.Potencia.ToString(),
Motor.RPM.ToString(),
Motor.RPM_Offset.ToString(),
Motor.VelocidadeInstantanea.ToString(),
Motor.Temperatura.ToString(),
//Motor.Umidade.ToString(),
@ -338,9 +349,10 @@ namespace AgroBase.Models
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[4].Value = Enum.GetName(typeof(StatusMotor), Motor.Aceleracao);
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[5].Value = Motor.Potencia.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[6].Value = Motor.RPM.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[7].Value = Motor.VelocidadeInstantanea.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[8].Value = Motor.Temperatura.ToString();
//frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[9].Value = Motor.Umidade.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[7].Value = Motor.RPM_Offset.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[8].Value = Motor.VelocidadeInstantanea.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[9].Value = Motor.Temperatura.ToString();
//frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[10].Value = Motor.Umidade.ToString();
}
}
@ -369,7 +381,7 @@ namespace AgroBase.Models
Enabled = false
};
tmrRegistrador.Tick += TmrRegistrador_Tick;
tmrRegistrador.Enabled = true;
tmrRegistrador.Start();
}
private void TmrRegistrador_Tick(object sender, EventArgs e)
@ -394,6 +406,8 @@ namespace AgroBase.Models
double RPM = Math.Round((Velocidade * 1000) / (Math.PI * DiametroRoda * 60), 2);
return RPM;
}
}
public class MovSensoriamentoMotor
@ -413,6 +427,7 @@ namespace AgroBase.Models
public Sentido Sentido { get; set; } = Sentido.Parado;
public StatusMotor Aceleracao { get; set; } = StatusMotor.Estavel;
public double RPM { get; set; } = 0;
public double RPM_Offset { get; set; } = 0;
public long Intervalo { get; set; } = 0;
public double VelocidadeInstantanea { get; set; } = 0;
public double Temperatura { get; set; } = 0;
@ -529,6 +544,7 @@ namespace AgroBase.Models
public string ComponenteID { get; set; }
public int RPM_SP { get; set; }
public double RPM { get; set; }
public double RPM_Offset { get; set; }
public long Periodo { get; set; }
public double Potencia { get; set; }
public double PotenciaSP { get; set; }

View File

@ -370,7 +370,7 @@ namespace AgroBase.Models.Modules
null;
if (Motor != null)
{
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[8].Value = Motor.Temperatura.ToString();
frmInstancial.frmPrincipal.gridSenMotores.Rows[Motor.Canal].Cells[9].Value = Motor.Temperatura.ToString();
}
}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"Conectado":false,"Sensores":[{"LogGrafico":[],"ID":"TMVET","Prioridade":0,"Descricao":"Temperatura Motor Esquerdo Trás","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[22.13],"ValorMinimo":0.0,"ValorMaximo":125.27},{"LogGrafico":[],"ID":"TMVEF","Prioridade":0,"Descricao":"Temperatura Motor Esquerdo Frente","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[0.0],"ValorMinimo":0.0,"ValorMaximo":0.0},{"LogGrafico":[],"ID":"TMVDT","Prioridade":0,"Descricao":"Temperatura Motor Direito Trás","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[0.0],"ValorMinimo":0.0,"ValorMaximo":211.32},{"LogGrafico":[],"ID":"TMVDF","Prioridade":0,"Descricao":"Temperatura Motor Direito Frente","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[228.34],"ValorMinimo":0.0,"ValorMaximo":228.34},{"LogGrafico":[],"ID":"VBAT","Prioridade":20,"Descricao":"Tensão da bateria","Componente":112,"Aferir":true,"DelayAmostragem":500,"Inicializado":false,"Testando":false,"Funcoes":[28],"Parametros":[["V offset","-0.900"],["R1","120000"],["R2","010000"]],"UnidadeMedida":null,"Leituras":[327.0,0.33,4.28],"ValorMinimo":0.0,"ValorMaximo":13.66},{"LogGrafico":[],"ID":"ABAT","Prioridade":10,"Descricao":"Corrente da bateria","Componente":322,"Aferir":true,"DelayAmostragem":500,"Inicializado":false,"Testando":false,"Funcoes":[29],"Parametros":[["V offset","00.413"],["Sensibilidade","000.35"]],"UnidadeMedida":null,"Leituras":[446.0,0.36,-0.15],"ValorMinimo":-1.15,"ValorMaximo":1.51},{"LogGrafico":[],"ID":"TBAT","Prioridade":5,"Descricao":"Temperatura da bateria","Componente":411,"Aferir":true,"DelayAmostragem":500,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","0.0000"]],"UnidadeMedida":null,"Leituras":[179.53],"ValorMinimo":-273.15,"ValorMaximo":265.63}]}
{"Conectado":false,"Sensores":[{"LogGrafico":[],"ID":"TMVET","Prioridade":0,"Descricao":"Temperatura Motor Esquerdo Trás","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[10.41],"ValorMinimo":0.0,"ValorMaximo":125.27},{"LogGrafico":[],"ID":"TMVEF","Prioridade":0,"Descricao":"Temperatura Motor Esquerdo Frente","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[12.24],"ValorMinimo":0.0,"ValorMaximo":74.35},{"LogGrafico":[],"ID":"TMVDT","Prioridade":0,"Descricao":"Temperatura Motor Direito Trás","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[15.06],"ValorMinimo":0.0,"ValorMaximo":211.32},{"LogGrafico":[],"ID":"TMVDF","Prioridade":0,"Descricao":"Temperatura Motor Direito Frente","Componente":411,"Aferir":true,"DelayAmostragem":200,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","-1.038"]],"UnidadeMedida":null,"Leituras":[12.25],"ValorMinimo":0.0,"ValorMaximo":228.34},{"LogGrafico":[],"ID":"VBAT","Prioridade":20,"Descricao":"Tensão da bateria","Componente":112,"Aferir":true,"DelayAmostragem":500,"Inicializado":false,"Testando":false,"Funcoes":[28],"Parametros":[["V offset","-0.900"],["R1","120000"],["R2","010000"]],"UnidadeMedida":null,"Leituras":[4095.0,3.23,42.0],"ValorMinimo":0.0,"ValorMaximo":42.0},{"LogGrafico":[],"ID":"ABAT","Prioridade":10,"Descricao":"Corrente da bateria","Componente":322,"Aferir":true,"DelayAmostragem":500,"Inicializado":false,"Testando":false,"Funcoes":[29],"Parametros":[["V offset","00.413"],["Sensibilidade","000.35"]],"UnidadeMedida":null,"Leituras":[0.0,0.0,-1.18],"ValorMinimo":-1.18,"ValorMaximo":1.51},{"LogGrafico":[],"ID":"TBAT","Prioridade":5,"Descricao":"Temperatura da bateria","Componente":411,"Aferir":true,"DelayAmostragem":500,"Inicializado":false,"Testando":false,"Funcoes":[12],"Parametros":[["V offset","0.0000"]],"UnidadeMedida":null,"Leituras":[32.34],"ValorMinimo":-273.15,"ValorMaximo":265.63}]}

View File

@ -1 +1 @@
[{"Tipo":0,"Pino":99,"Descricao":"1","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":98,"Descricao":"2","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":97,"Descricao":"3","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":4,"Descricao":"4","Funcao":5,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":5,"Descricao":"5","Funcao":9,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":6,"Descricao":"6","Funcao":10,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":7,"Descricao":"7","Funcao":11,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":15,"Descricao":"8","Funcao":6,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":16,"Descricao":"9","Funcao":7,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":17,"Descricao":"10","Funcao":8,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":18,"Descricao":"11","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":8,"Descricao":"12","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":3,"Descricao":"13","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":46,"Descricao":"14","Funcao":7,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":9,"Descricao":"15","Funcao":8,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":10,"Descricao":"16","Funcao":6,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":11,"Descricao":"17","Funcao":11,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":12,"Descricao":"18","Funcao":10,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":13,"Descricao":"19","Funcao":9,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":14,"Descricao":"20","Funcao":5,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":96,"Descricao":"21","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":95,"Descricao":"22","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":94,"Descricao":"23","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":93,"Descricao":"24","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":19,"Descricao":"25","Funcao":5,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":20,"Descricao":"26","Funcao":9,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":21,"Descricao":"27","Funcao":10,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":47,"Descricao":"28","Funcao":11,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":48,"Descricao":"29","Funcao":6,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":45,"Descricao":"30","Funcao":8,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":0,"Descricao":"31","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":35,"Descricao":"32","Funcao":7,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":36,"Descricao":"33","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":37,"Descricao":"34","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":38,"Descricao":"35","Funcao":7,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":39,"Descricao":"36","Funcao":8,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":40,"Descricao":"37","Funcao":6,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":41,"Descricao":"38","Funcao":11,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":42,"Descricao":"39","Funcao":10,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":2,"Descricao":"40","Funcao":9,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":1,"Descricao":"41","Funcao":5,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":44,"Descricao":"42","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":43,"Descricao":"43","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":92,"Descricao":"44","Funcao":0,"Habilitado":false,"ComponenteID":""}]
[{"Tipo":0,"Pino":99,"Descricao":"1","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":98,"Descricao":"2","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":97,"Descricao":"3","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":4,"Descricao":"4","Funcao":5,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":5,"Descricao":"5","Funcao":9,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":6,"Descricao":"6","Funcao":10,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":7,"Descricao":"7","Funcao":11,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":15,"Descricao":"8","Funcao":6,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":16,"Descricao":"9","Funcao":7,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":17,"Descricao":"10","Funcao":8,"Habilitado":true,"ComponenteID":"ET"},{"Tipo":0,"Pino":18,"Descricao":"11","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":8,"Descricao":"12","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":3,"Descricao":"13","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":46,"Descricao":"14","Funcao":7,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":9,"Descricao":"15","Funcao":8,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":10,"Descricao":"16","Funcao":6,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":11,"Descricao":"17","Funcao":11,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":12,"Descricao":"18","Funcao":10,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":13,"Descricao":"19","Funcao":9,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":14,"Descricao":"20","Funcao":5,"Habilitado":true,"ComponenteID":"DT"},{"Tipo":0,"Pino":96,"Descricao":"21","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":95,"Descricao":"22","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":94,"Descricao":"23","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":93,"Descricao":"24","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":19,"Descricao":"25","Funcao":5,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":20,"Descricao":"26","Funcao":9,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":21,"Descricao":"27","Funcao":10,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":47,"Descricao":"28","Funcao":11,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":48,"Descricao":"29","Funcao":6,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":45,"Descricao":"30","Funcao":8,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":0,"Descricao":"31","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":35,"Descricao":"32","Funcao":7,"Habilitado":true,"ComponenteID":"DF"},{"Tipo":0,"Pino":36,"Descricao":"33","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":37,"Descricao":"34","Funcao":0,"Habilitado":true,"ComponenteID":""},{"Tipo":0,"Pino":38,"Descricao":"35","Funcao":8,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":39,"Descricao":"36","Funcao":7,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":40,"Descricao":"37","Funcao":6,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":41,"Descricao":"38","Funcao":11,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":42,"Descricao":"39","Funcao":10,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":2,"Descricao":"40","Funcao":9,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":1,"Descricao":"41","Funcao":5,"Habilitado":true,"ComponenteID":"EF"},{"Tipo":0,"Pino":44,"Descricao":"42","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":43,"Descricao":"43","Funcao":0,"Habilitado":false,"ComponenteID":""},{"Tipo":0,"Pino":92,"Descricao":"44","Funcao":0,"Habilitado":false,"ComponenteID":""}]

View File

@ -41,13 +41,14 @@ String MontarDadosProtocoloTeste(bool Testando, String Componente, String Result
return Protocolo;
}
String MontarDadosProtocoloRPM(float rpm, double potencia, StatusMotor aceleracao, Sentido sentido, bool revertendo) {
String MontarDadosProtocoloRPM(float rpm, double potencia, StatusMotor aceleracao, Sentido sentido, bool revertendo, float rpm_offset) {
String Protocolo =
(String)rpm + ";" +
(String)potencia + ";" +
(String)aceleracao + ";" +
(String)sentido + ";" +
(revertendo ? "1" : "0");
(revertendo ? "1" : "0") + ";" +
(String)rpm_offset;
return Protocolo;
}

View File

@ -0,0 +1,567 @@
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SerialService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\utils.h"
#include <PID_v1.h>
#define D_Code Mov
#define _pinoLED RGB_BUILTIN
int _pinoReleGeral = -1;
long _baudRate = 115200;
bool Conectado = false;
int _TaxaAmostragem = 500;
const int PPR = 22; // Pulsos por revolução
int RampaMin = 0;
int ZeroRampa = 0;
int RampaMax = 1023;
class Motor {
public:
// Construtor
Motor(String desc) {
_ID = desc;
}
// Definições
String _ID;
int _canal;
int _pinoPWM;
int _pinoDIR;
int _pinoBRK;
int _pinoSTP;
int _pinoHLA;
int _pinoHLB;
int _pinoHLC;
double _Kp;
double _Ki;
double _Kd;
PID* _PID = nullptr;
bool Iniciado = false;
bool Testando = false;
bool Revertendo = false;
bool SentidoContrario = false;
StatusMotor Aceleracao = Estavel;
StatusMotor AceleracaoA = Estavel;
// Consumo
const int leituras = 5;
volatile float RPM_arr[5];
volatile bool Hall_arr[5][3];
double RPM;
double PotenciaAtual;
volatile int ultimaLeituraHallA = 0;
volatile int ultimaLeituraHallB = 0;
volatile int ultimaLeituraHallC = 0;
volatile unsigned int tempoAnterior = 0;
volatile float periodo = 0;
// Entrada de dados
bool _MalhaFechada;
int _PotMap;
double _RPM_SP;
Sentido _SentidoSP = Parado;
Sentido _Sentido = Parado;
Sentido _SentidoU = Parado;
int _US_Addr;
bool _Freio = false;
int _Margem = 2;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
if (_pinoPWM > -1) {
ledcSetup(_canal, 1000, 10);
ledcAttachPin(_pinoPWM, _canal);
PotenciaAtual = ZeroRampa;
_PotMap = PotenciaAtual;
_RPM_SP = 0;
ledcWrite(_canal, _PotMap);
}
if (_pinoDIR > -1) {
pinMode(_pinoDIR, OUTPUT);
digitalWrite(_pinoDIR, LOW);
_SentidoU = Parado;
}
if (_pinoBRK > -1) {
pinMode(_pinoBRK, OUTPUT);
digitalWrite(_pinoBRK, LOW);
}
if (_pinoSTP > -1) {
pinMode(_pinoSTP, OUTPUT);
digitalWrite(_pinoSTP, HIGH);
}
if (_pinoHLA > -1) {
pinMode(_pinoHLA, INPUT);
ultimaLeituraHallA = digitalRead(_pinoHLA);
RPM = 0;
periodo = 0;
tempoAnterior = 0;
xTaskCreatePinnedToCore(&Motor::RPMTaskWrapper, "RPMTask", 15000, this, 25 - _canal, &RPMTaskHandle, tskNO_AFFINITY);
ReiniciarAceleracaoArr();
ReiniciarHallArr();
_PID = new PID(&RPM, &PotenciaAtual, &_RPM_SP, _Kp, _Ki, _Kd, DIRECT);
_PID->SetOutputLimits(RampaMin, RampaMax);
_PID->SetMode(AUTOMATIC);
}
if (_pinoHLB > -1) {
pinMode(_pinoHLB, INPUT);
ultimaLeituraHallB = digitalRead(_pinoHLB);
}
if (_pinoHLC > -1) {
pinMode(_pinoHLC, INPUT);
ultimaLeituraHallC = digitalRead(_pinoHLC);
}
xTaskCreatePinnedToCore(&Motor::RampaTaskWrapper, "RampaTask", 5000, this, 21 - _canal + 4, &RampaTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(RampaTaskHandle);
if (_pinoHLA > -1) {
vTaskDelete(RPMTaskHandle);
}
// Desanexar o canal PWM
if (_pinoPWM > -1) {
ledcDetachPin(_pinoPWM);
}
// Redefinir as configurações para os valores iniciais
pinMode(_pinoPWM, INPUT);
pinMode(_pinoDIR, INPUT);
pinMode(_pinoBRK, INPUT);
pinMode(_pinoSTP, INPUT);
pinMode(_pinoHLA, INPUT);
pinMode(_pinoHLB, INPUT);
pinMode(_pinoHLC, INPUT);
// Outras redefinições de variáveis de estado, se necessário
delete _PID;
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void ReiniciarAceleracaoArr() {
for (int i = 0; i < leituras; i++) {
RPM_arr[i] = -1.0;
}
}
void ReiniciarHallArr() {
for (int i = 0; i < leituras; i++) {
Hall_arr[i][0] = false;
Hall_arr[i][1] = false;
Hall_arr[i][2] = false;
}
}
void ReverterSentidoGiro() {
}
private:
TaskHandle_t RPMTaskHandle = NULL;
static void RPMTaskWrapper(void *pvParameters) {
Motor *motor = static_cast<Motor*>(pvParameters);
motor->RPMTask();
}
void RPMTask() {
const int RpmMax = 650; // RPM Máximo aferir
const float RelacaoPPR = (60 / PPR) * 1000; // Multiplicador do cálculo de RPM (período em ms)
const float MenorPeriodo = RelacaoPPR / RpmMax; // Tempo mínimo de leitura
unsigned long firstMilis = millis();
int pulsos = 0;
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
// Medir RPM apenas quando ocorrer um pulso no sensor HALL
bool LeituraHa = digitalRead(_pinoHLA) == 1;
if (LeituraHa != ultimaLeituraHallA) {
ultimaLeituraHallA = LeituraHa;
pulsos++;
// Calcular o período em microssegundos
unsigned long tempoAtual = micros();
unsigned long periodoUs = tempoAtual - tempoAnterior;
periodo = periodoUs / 1000.0; // Converte de us para ms (2300 us para 2,3 ms)
// Salva o valor do RPM anterior
double RPM_A = RPM;
// Se o período entre pulsos for menor que o tempo mínimo entre pulsos em ms, significa que o sensor está em uma posição em que existe oscilação de leitura,
// pois o RPM estaria acima do máximo, logo, assumir o valor de RPM aferido anteriormente
if (periodo < MenorPeriodo) {
RPM = RPM_A;
}
// Calcular RPM se houve variação de tempo entre o pulso atual e o pulso anterior
else if (periodo != 0) {
// RPM = 60 / (Pulsos por Revolução * Período em segundos)
// A fórmula foi adaptada para otimizar processamento
RPM = RelacaoPPR / periodo;
}
// Se não houve alteração no período, então o motor não se moveu
else {
RPM = 0;
}
CalcularSentidoGiro(RPM);
// Reiniciar variáveis
tempoAnterior = tempoAtual;
}
CorrigirPotenciaMotor();
long intMillis = (millis() - firstMilis);
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= _TaxaAmostragem) {
if (pulsos == 0) {
RPM = 0;
periodo = 0;
CalcularSentidoGiro(RPM);
}
pulsos = 0;
double PotAtual = fmap(PotenciaAtual, RampaMin, RampaMax, 0.0, 100.0);
EnviarDadosSerial(MontarProtocoloSensor(sRPM, _ID, MontarDadosProtocoloRPM(RPM, PotAtual, Aceleracao, _Sentido, Revertendo)));
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(1);
}
}
void CalcularSentidoGiro(float _RPM) {
if (_pinoHLA == -1 || _pinoHLB == -1 || _pinoHLC == -1) {
CalculaAceleracao(_RPM);
return;
}
bool LeituraHa = ultimaLeituraHallA == 1;
bool LeituraHb = digitalRead(_pinoHLB) == 1;
bool LeituraHc = digitalRead(_pinoHLC) == 1;
for (int i = 1; i < leituras; i++) {
Hall_arr[i - 1][0] = Hall_arr[i][0];
Hall_arr[i - 1][1] = Hall_arr[i][1];
Hall_arr[i - 1][2] = Hall_arr[i][2];
}
Hall_arr[leituras - 1][0] = LeituraHa;
Hall_arr[leituras - 1][1] = LeituraHb;
Hall_arr[leituras - 1][2] = LeituraHc;
// Leituras dos sensores Hall nas leituras anteriores
bool LeituraAnteriorHa = Hall_arr[leituras - 2][0];
bool LeituraAnteriorHb = Hall_arr[leituras - 2][1];
bool LeituraAnteriorHc = Hall_arr[leituras - 2][2];
// Comparação das leituras atuais com as leituras anteriores
if (LeituraHa == LeituraAnteriorHc && LeituraHc == LeituraAnteriorHa) {
_Sentido = Antihorario;
}
else if (LeituraHa == LeituraAnteriorHb && LeituraHb == LeituraAnteriorHa) {
_Sentido = Horario;
}
else {
// Outros casos (não determinados)
}
CalculaAceleracao(_RPM);
}
void CalculaAceleracao(float _RPM) {
float RPM_total = _RPM;
int Desconsiderar = 0;
// Salvar as ultimas leituras
for (int i = 1; i < leituras; i++) {
RPM_arr[i - 1] = RPM_arr[i];
RPM_total += RPM_arr[i - 1] < 0 ? 0 : RPM_arr[i - 1];
Desconsiderar += RPM_arr[i - 1] < 0 ? 1 : 0;
}
RPM_arr[leituras - 1] = _RPM;
float RPM_medio = RPM_total / (leituras - Desconsiderar);
AceleracaoA = Aceleracao;
if (_SentidoSP == Parado && _RPM == 0) {
Aceleracao = Estavel;
} else if (RPM_arr[leituras - 3] < (RPM_arr[leituras - 2] - _Margem) && RPM_arr[leituras - 2] < (_RPM - _Margem)) {
Aceleracao = Acelerando;
} else if (RPM_arr[leituras - 3] > (RPM_arr[leituras - 2] + _Margem) && RPM_arr[leituras - 2] > (_RPM + _Margem)) {
Aceleracao = Desacelerando;
} else {
Aceleracao = Estavel;
}
}
void CorrigirPotenciaMotor() {
if (_MalhaFechada && !Revertendo && _SentidoSP != Parado) {
if (_pinoHLA > -1 && _pinoHLB > -1 && _pinoHLC > -1) {
SentidoContrario = _Sentido != _SentidoSP;
}
float _rpmA = RPM;
if (SentidoContrario) {
RPM = RPM * -1;
}
/*else if (Aceleracao == Desacelerando && AceleracaoA == Estavel) {
RPM = 0;
}*/
_PID->Compute();
//RPM = _rpmA;
}
}
TaskHandle_t RampaTaskHandle = NULL;
static void RampaTaskWrapper(void *pvParameters) {
Motor *motor = static_cast<Motor*>(pvParameters);
motor->RampaTask();
}
void RampaTask() {
unsigned long firstMilis = millis();
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
Atualizar();
vTaskDelay(1);
}
}
void Atualizar() {
/*bool Travado = _PotMap > ZeroRampa && RPM_arr[leituras - 1] == 0 && RPM_arr[leituras - 2] > 0 && RPM_arr[leituras - 3] > 0 && _Sentido != Parado;
if (_pinoPWM > -1 && Travado) {
_PotMap = ZeroRampa;
ledcWrite(_canal, _PotMap);
vTaskDelay(400);
_PotMap = PotenciaAtual;
}*/
if (_pinoDIR > -1) {
bool ReleAtuado = _SentidoSP == Horario;
if (_SentidoSP != _SentidoU && ReleAtuado) {
digitalWrite(_pinoDIR, ReleAtuado);
vTaskDelay(1000);
}
digitalWrite(_pinoDIR, ReleAtuado);
_SentidoU = _SentidoSP;
}
if (_pinoBRK > -1) {
digitalWrite(_pinoBRK, _Freio);
}
if (_pinoSTP > -1) {
//digitalWrite(_pinoSTP, HIGH);
}
if (_pinoPWM > -1) {
if (_SentidoSP == Parado) {
_PotMap = ZeroRampa;
}
else {
_PotMap = PotenciaAtual;
}
ledcWrite(_canal, _PotMap);
}
}
};
Motor M1("ET");
Motor M2("EF");
Motor M3("DT");
Motor M4("DF");
Motor* MotorPorID(String ID) {
Motor* _motor =
ID == "ET" ? &M1 :
ID == "EF" ? &M2 :
ID == "DT" ? &M3 :
ID == "DF" ? &M4 :
nullptr;
return _motor;
}
void setup() {
Serial.begin(_baudRate);
delay(10);
if (_pinoReleGeral > -1) {
pinMode(_pinoReleGeral, OUTPUT);
digitalWrite(_pinoReleGeral, LOW);
}
}
void loop() {
if (Serial.available() > 3) {
String Protocolo = "";
F_Code _funcao = Nda;
while (Serial.available()) {
char Entrada = (char)Serial.read();
if (Entrada == EndLine) {
break;
}
Protocolo += Entrada;
if (Protocolo.length() == 3) {
if (_funcao == Nda) {
_funcao = (F_Code)((String)Protocolo[0] + (String)Protocolo[1] + (String)Protocolo[2]).toInt();
Protocolo = "";
}
}
}
EnviarDadosSerial("OK");
if (_funcao == Chk) {
EnviarDadosSerial(MontarProtocoloVerificacao(D_Code));
}
else if (_funcao == Cfg) {
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
bool Conectar = (String)Protocolo[3] == "1";
if (ID == "MD") {
_TaxaAmostragem = ((String)Protocolo[5] + (String)Protocolo[6] + (String)Protocolo[7] + (String)Protocolo[8] + (String)Protocolo[9]).toInt();
int pinoReleGeral = ((String)Protocolo[11] + (String)Protocolo[12]).toInt();
int _RampaMin = ((String)Protocolo[14] + (String)Protocolo[15] + (String)Protocolo[16] + (String)Protocolo[17]).toInt();
int _RampaMax = ((String)Protocolo[19] + (String)Protocolo[20] + (String)Protocolo[21] + (String)Protocolo[22]).toInt();
int _PPR = ((String)Protocolo[24] + (String)Protocolo[25] + (String)Protocolo[26]).toInt();
RampaMin = _RampaMin;
RampaMax = _RampaMax;
//PPR = _PPR;
if (pinoReleGeral > -1) {
pinMode(_pinoReleGeral, INPUT);
_pinoReleGeral = pinoReleGeral;
pinMode(_pinoReleGeral, OUTPUT);
digitalWrite(_pinoReleGeral, Conectar);
}
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, "MD", Conectado ? "1" : "0"));
}
else {
int canal = ((String)Protocolo[5]).toInt();
bool _foc = (String)Protocolo[7] == "1";
bool motor_ativado = (String)Protocolo[9] == "1";
double _Kp = ((String)Protocolo[11] + (String)Protocolo[12] + (String)Protocolo[13] + (String)Protocolo[14] + (String)Protocolo[15]).toDouble();
double _Ki = ((String)Protocolo[17] + (String)Protocolo[18] + (String)Protocolo[19] + (String)Protocolo[20] + (String)Protocolo[21]).toDouble();
double _Kd = ((String)Protocolo[23] + (String)Protocolo[24] + (String)Protocolo[25] + (String)Protocolo[26] + (String)Protocolo[27]).toDouble();
int pwm = ((String)Protocolo[29] + (String)Protocolo[30]).toInt();
int dir = ((String)Protocolo[32] + (String)Protocolo[33]).toInt();
int brk = ((String)Protocolo[35] + (String)Protocolo[36]).toInt();
int stp = ((String)Protocolo[38] + (String)Protocolo[39]).toInt();
int hallA = ((String)Protocolo[41] + (String)Protocolo[42]).toInt();
int hallB = ((String)Protocolo[44] + (String)Protocolo[45]).toInt();
int hallC = ((String)Protocolo[47] + (String)Protocolo[48]).toInt();
Motor* _motor = MotorPorID(ID);
if (motor_ativado) {
if (Conectar) {
_motor->_canal = canal;
_motor->_pinoPWM = pwm;
_motor->_pinoDIR = dir;
_motor->_pinoBRK = brk;
_motor->_pinoSTP = stp;
_motor->_pinoHLA = hallA;
_motor->_pinoHLB = hallB;
_motor->_pinoHLC = hallC;
_motor->_MalhaFechada = _foc;
_motor->_Kp = _Kp;
_motor->_Ki = _Ki;
_motor->_Kd = _Kd;
_motor->Inicializar();
}
else {
_motor->Desligar();
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
}
else if (_funcao == Cmd) {
//canal;potencia;sentido;rampa;precisao;rpm
//0;000;0;000;000;000
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
Motor* _motor = MotorPorID(ID);
_motor->_SentidoSP = (Sentido)((String)Protocolo[3]).toInt();
_motor->_RPM_SP = ((String)Protocolo[5] + (String)Protocolo[6] + (String)Protocolo[7]).toInt();
_motor->_MalhaFechada = (String)Protocolo[9] == "1";
_motor->ReiniciarAceleracaoArr();
bool reverter = ((String)Protocolo[11]) == "1";
if (reverter) {
_motor->ReverterSentidoGiro();
}
}
else if (_funcao == Tst) {
String ID = ((String)Protocolo[0] +(String)Protocolo[1]);
Motor* _motor = MotorPorID(ID);
bool EmTeste = _motor->Testando;
if (!EmTeste) {
//_motor->Testar();
}
}
}
}

View File

@ -0,0 +1,8 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
]
}

View File

@ -0,0 +1,636 @@
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SerialService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\utils.h"
#include <PID_v1.h>
#define D_Code Mov
#define _pinoLED RGB_BUILTIN
int _pinoReleGeral = -1;
long _baudRate = 115200;
bool Conectado = false;
int _TaxaAmostragem = 500;
int PPR = 22; // Pulsos por revolução
int RampaMin = 0;
int ZeroRampa = 0;
int RampaMax = 1023;
const int RpmMax = 650; // RPM Máximo aferir
float RelacaoPPR = 0;
float MenorPeriodo = 0;
int delayBalanceamento = 5000;
float RPM_Margem = 5.0;
float RPM_SetPoint = 0.0;
float RPM_Medio = 0.0;
bool RPM_Estavel = true;
class Motor {
public:
// Construtor
Motor(String desc) {
_ID = desc;
}
// Definições
String _ID;
int _canal;
int _pinoPWM;
int _pinoDIR;
int _pinoBRK;
int _pinoSTP;
int _pinoHLA;
int _pinoHLB;
int _pinoHLC;
double _Kp;
double _Ki;
double _Kd;
PID* _PID = nullptr;
bool Iniciado = false;
bool Testando = false;
bool Revertendo = false;
bool SentidoContrario = false;
StatusMotor Aceleracao = Estavel;
StatusMotor AceleracaoA = Estavel;
// Consumo
const int leituras = 5;
volatile float RPM_arr[5];
volatile bool Hall_arr[5][3];
double RPM;
double PotenciaAtual;
volatile int ultimaLeituraHallA = 0;
volatile int ultimaLeituraHallB = 0;
volatile int ultimaLeituraHallC = 0;
volatile unsigned int tempoAnterior = 0;
volatile float periodo = 0;
// Entrada de dados
bool _MalhaFechada;
int _PotMap;
double _RPM_SP;
Sentido _SentidoSP = Parado;
Sentido _Sentido = Parado;
Sentido _SentidoU = Parado;
int _US_Addr;
bool _Freio = false;
int _Margem = 2;
double _RPM_Offset = 0;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
if (_pinoPWM > -1) {
ledcSetup(_canal, 1000, 10);
ledcAttachPin(_pinoPWM, _canal);
PotenciaAtual = ZeroRampa;
_PotMap = PotenciaAtual;
_RPM_SP = 0;
ledcWrite(_canal, _PotMap);
}
if (_pinoDIR > -1) {
pinMode(_pinoDIR, OUTPUT);
digitalWrite(_pinoDIR, LOW);
_SentidoU = Parado;
}
if (_pinoBRK > -1) {
pinMode(_pinoBRK, OUTPUT);
digitalWrite(_pinoBRK, LOW);
}
if (_pinoSTP > -1) {
pinMode(_pinoSTP, OUTPUT);
digitalWrite(_pinoSTP, HIGH);
}
if (_pinoHLA > -1) {
pinMode(_pinoHLA, INPUT);
ultimaLeituraHallA = digitalRead(_pinoHLA);
RPM = 0;
periodo = 0;
tempoAnterior = 0;
xTaskCreatePinnedToCore(&Motor::RPMTaskWrapper, "RPMTask", 15000, this, 25 - _canal, &RPMTaskHandle, tskNO_AFFINITY);
ReiniciarAceleracaoArr();
ReiniciarHallArr();
_PID = new PID(&RPM, &PotenciaAtual, &_RPM_SP, _Kp, _Ki, _Kd, DIRECT);
_PID->SetOutputLimits(RampaMin, RampaMax);
_PID->SetMode(AUTOMATIC);
}
if (_pinoHLB > -1) {
pinMode(_pinoHLB, INPUT);
ultimaLeituraHallB = digitalRead(_pinoHLB);
}
if (_pinoHLC > -1) {
pinMode(_pinoHLC, INPUT);
ultimaLeituraHallC = digitalRead(_pinoHLC);
}
xTaskCreatePinnedToCore(&Motor::RampaTaskWrapper, "RampaTask", 5000, this, 21 - _canal + 4, &RampaTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(RampaTaskHandle);
if (_pinoHLA > -1) {
vTaskDelete(RPMTaskHandle);
}
// Desanexar o canal PWM
if (_pinoPWM > -1) {
ledcDetachPin(_pinoPWM);
}
// Redefinir as configurações para os valores iniciais
pinMode(_pinoPWM, INPUT);
pinMode(_pinoDIR, INPUT);
pinMode(_pinoBRK, INPUT);
pinMode(_pinoSTP, INPUT);
pinMode(_pinoHLA, INPUT);
pinMode(_pinoHLB, INPUT);
pinMode(_pinoHLC, INPUT);
// Outras redefinições de variáveis de estado, se necessário
delete _PID;
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void ReiniciarAceleracaoArr() {
for (int i = 0; i < leituras; i++) {
RPM_arr[i] = -1.0;
}
}
void ReiniciarHallArr() {
for (int i = 0; i < leituras; i++) {
Hall_arr[i][0] = false;
Hall_arr[i][1] = false;
Hall_arr[i][2] = false;
}
}
void ReverterSentidoGiro() {
}
private:
TaskHandle_t RPMTaskHandle = NULL;
static void RPMTaskWrapper(void *pvParameters) {
Motor *motor = static_cast<Motor*>(pvParameters);
motor->RPMTask();
}
void RPMTask() {
unsigned long firstMilis = millis();
int pulsos = 0;
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
// Medir RPM apenas quando ocorrer um pulso no sensor HALL
bool LeituraHa = digitalRead(_pinoHLA) == 1;
if (LeituraHa != ultimaLeituraHallA) {
ultimaLeituraHallA = LeituraHa;
pulsos++;
// Calcular o período em microssegundos
unsigned long tempoAtual = micros();
unsigned long periodoUs = tempoAtual - tempoAnterior;
periodo = periodoUs / 1000.0; // Converte de us para ms (2300 us para 2,3 ms)
// Salva o valor do RPM anterior
double RPM_A = RPM;
// Se o período entre pulsos for menor que o tempo mínimo entre pulsos em ms, significa que o sensor está em uma posição em que existe oscilação de leitura,
// pois o RPM estaria acima do máximo, logo, assumir o valor de RPM aferido anteriormente
if (periodo < MenorPeriodo) {
RPM = RPM_A;
}
// Calcular RPM se houve variação de tempo entre o pulso atual e o pulso anterior
else if (periodo != 0) {
// RPM = 60 / (Pulsos por Revolução * Período em segundos)
// A fórmula foi adaptada para otimizar processamento
RPM = RelacaoPPR / periodo;
}
// Se não houve alteração no período, então o motor não se moveu
else {
RPM = 0;
}
CalcularSentidoGiro(RPM);
// Reiniciar variáveis
tempoAnterior = tempoAtual;
}
CorrigirPotenciaMotor();
long intMillis = (millis() - firstMilis);
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= _TaxaAmostragem) {
if (pulsos == 0) {
RPM = 0;
periodo = 0;
CalcularSentidoGiro(RPM);
}
pulsos = 0;
double PotAtual = fmap(PotenciaAtual, RampaMin, RampaMax, 0.0, 100.0);
EnviarDadosSerial(MontarProtocoloSensor(sRPM, _ID, MontarDadosProtocoloRPM(RPM, PotAtual, Aceleracao, _Sentido, Revertendo, _RPM_Offset)));
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(1);
}
}
void CalcularSentidoGiro(float _RPM) {
if (_pinoHLA == -1 || _pinoHLB == -1 || _pinoHLC == -1) {
CalculaAceleracao(_RPM);
return;
}
bool LeituraHa = ultimaLeituraHallA == 1;
bool LeituraHb = digitalRead(_pinoHLB) == 1;
bool LeituraHc = digitalRead(_pinoHLC) == 1;
for (int i = 1; i < leituras; i++) {
Hall_arr[i - 1][0] = Hall_arr[i][0];
Hall_arr[i - 1][1] = Hall_arr[i][1];
Hall_arr[i - 1][2] = Hall_arr[i][2];
}
Hall_arr[leituras - 1][0] = LeituraHa;
Hall_arr[leituras - 1][1] = LeituraHb;
Hall_arr[leituras - 1][2] = LeituraHc;
// Leituras dos sensores Hall nas leituras anteriores
bool LeituraAnteriorHa = Hall_arr[leituras - 2][0];
bool LeituraAnteriorHb = Hall_arr[leituras - 2][1];
bool LeituraAnteriorHc = Hall_arr[leituras - 2][2];
// Comparação das leituras atuais com as leituras anteriores
if (LeituraHa == LeituraAnteriorHc && LeituraHc == LeituraAnteriorHa) {
_Sentido = Antihorario;
}
else if (LeituraHa == LeituraAnteriorHb && LeituraHb == LeituraAnteriorHa) {
_Sentido = Horario;
}
else {
// Outros casos (não determinados)
}
CalculaAceleracao(_RPM);
}
void CalculaAceleracao(float _RPM) {
float RPM_total = _RPM;
int Desconsiderar = 0;
// Salvar as ultimas leituras
for (int i = 1; i < leituras; i++) {
RPM_arr[i - 1] = RPM_arr[i];
RPM_total += RPM_arr[i - 1] < 0 ? 0 : RPM_arr[i - 1];
Desconsiderar += RPM_arr[i - 1] < 0 ? 1 : 0;
}
RPM_arr[leituras - 1] = _RPM;
float RPM_medio = RPM_total / (leituras - Desconsiderar);
AceleracaoA = Aceleracao;
if (_SentidoSP == Parado && _RPM == 0) {
Aceleracao = Estavel;
} else if (RPM_arr[leituras - 3] < (RPM_arr[leituras - 2] - _Margem) && RPM_arr[leituras - 2] < (_RPM - _Margem)) {
Aceleracao = Acelerando;
} else if (RPM_arr[leituras - 3] > (RPM_arr[leituras - 2] + _Margem) && RPM_arr[leituras - 2] > (_RPM + _Margem)) {
Aceleracao = Desacelerando;
} else {
Aceleracao = Estavel;
}
}
void CorrigirPotenciaMotor() {
if (_MalhaFechada && !Revertendo && _SentidoSP != Parado) {
if (_pinoHLA > -1 && _pinoHLB > -1 && _pinoHLC > -1) {
SentidoContrario = _Sentido != _SentidoSP;
}
if (SentidoContrario) {
RPM = RPM * -1;
}
/*else if (Aceleracao == Desacelerando && AceleracaoA == Estavel) {
RPM = 0;
}*/
float _rpmA = RPM;
if (RPM_Estavel) {
RPM = RPM + _RPM_Offset;
}
_PID->Compute();
RPM = _rpmA;
}
}
TaskHandle_t RampaTaskHandle = NULL;
static void RampaTaskWrapper(void *pvParameters) {
Motor *motor = static_cast<Motor*>(pvParameters);
motor->RampaTask();
}
void RampaTask() {
unsigned long firstMilis = millis();
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
Atualizar();
vTaskDelay(1);
}
}
void Atualizar() {
/*bool Travado = _PotMap > ZeroRampa && RPM_arr[leituras - 1] == 0 && RPM_arr[leituras - 2] > 0 && RPM_arr[leituras - 3] > 0 && _Sentido != Parado;
if (_pinoPWM > -1 && Travado) {
_PotMap = ZeroRampa;
ledcWrite(_canal, _PotMap);
vTaskDelay(400);
_PotMap = PotenciaAtual;
}*/
if (_pinoDIR > -1) {
bool ReleAtuado = _SentidoSP == Horario;
if (_SentidoSP != _SentidoU && ReleAtuado) {
digitalWrite(_pinoDIR, ReleAtuado);
vTaskDelay(1000);
}
digitalWrite(_pinoDIR, ReleAtuado);
_SentidoU = _SentidoSP;
}
if (_pinoBRK > -1) {
digitalWrite(_pinoBRK, _Freio);
}
if (_pinoSTP > -1) {
//digitalWrite(_pinoSTP, HIGH);
}
if (_pinoPWM > -1) {
if (_SentidoSP == Parado) {
_PotMap = ZeroRampa;
}
else {
_PotMap = PotenciaAtual;
}
ledcWrite(_canal, _PotMap);
}
}
};
Motor M1("ET");
Motor M2("EF");
Motor M3("DT");
Motor M4("DF");
Motor* MotorPorID(String ID) {
Motor* _motor =
ID == "ET" ? &M1 :
ID == "EF" ? &M2 :
ID == "DT" ? &M3 :
ID == "DF" ? &M4 :
nullptr;
return _motor;
}
void BalanceamentoTask(void *pvParameters);
TaskHandle_t BalanceamentoTaskHandle = NULL;
void setup() {
Serial.begin(_baudRate);
delay(10);
if (_pinoReleGeral > -1) {
pinMode(_pinoReleGeral, OUTPUT);
digitalWrite(_pinoReleGeral, LOW);
}
xTaskCreatePinnedToCore(BalanceamentoTask, "BalanceamentoTask", 8000, NULL, 5, &BalanceamentoTaskHandle, tskNO_AFFINITY);
RecalcularRelacaoPPR();
}
void loop() {
if (Serial.available() > 3) {
String Protocolo = "";
F_Code _funcao = Nda;
while (Serial.available()) {
char Entrada = (char)Serial.read();
if (Entrada == EndLine) {
break;
}
Protocolo += Entrada;
if (Protocolo.length() == 3) {
if (_funcao == Nda) {
_funcao = (F_Code)((String)Protocolo[0] + (String)Protocolo[1] + (String)Protocolo[2]).toInt();
Protocolo = "";
}
}
}
EnviarDadosSerial("OK");
if (_funcao == Chk) {
EnviarDadosSerial(MontarProtocoloVerificacao(D_Code));
}
else if (_funcao == Cfg) {
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
bool Conectar = (String)Protocolo[3] == "1";
if (ID == "MD") {
_TaxaAmostragem = ((String)Protocolo[5] + (String)Protocolo[6] + (String)Protocolo[7] + (String)Protocolo[8] + (String)Protocolo[9]).toInt();
int pinoReleGeral = ((String)Protocolo[11] + (String)Protocolo[12]).toInt();
int _RampaMin = ((String)Protocolo[14] + (String)Protocolo[15] + (String)Protocolo[16] + (String)Protocolo[17]).toInt();
int _RampaMax = ((String)Protocolo[19] + (String)Protocolo[20] + (String)Protocolo[21] + (String)Protocolo[22]).toInt();
int _PPR = ((String)Protocolo[24] + (String)Protocolo[25] + (String)Protocolo[26]).toInt();
int _delayBalanceamento = ((String)Protocolo[28] + (String)Protocolo[29] + (String)Protocolo[30] + (String)Protocolo[31] + (String)Protocolo[32]).toInt();
int _margemRPM = ((String)Protocolo[34] + (String)Protocolo[35]).toInt();
RampaMin = _RampaMin;
RampaMax = _RampaMax;
PPR = _PPR;
delayBalanceamento = _delayBalanceamento;
RPM_Margem = _margemRPM;
if (pinoReleGeral > -1) {
pinMode(_pinoReleGeral, INPUT);
_pinoReleGeral = pinoReleGeral;
pinMode(_pinoReleGeral, OUTPUT);
digitalWrite(_pinoReleGeral, Conectar);
}
RecalcularRelacaoPPR();
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, "MD", Conectado ? "1" : "0"));
}
else {
int canal = ((String)Protocolo[5]).toInt();
bool _foc = (String)Protocolo[7] == "1";
bool motor_ativado = (String)Protocolo[9] == "1";
double _Kp = ((String)Protocolo[11] + (String)Protocolo[12] + (String)Protocolo[13] + (String)Protocolo[14] + (String)Protocolo[15]).toDouble();
double _Ki = ((String)Protocolo[17] + (String)Protocolo[18] + (String)Protocolo[19] + (String)Protocolo[20] + (String)Protocolo[21]).toDouble();
double _Kd = ((String)Protocolo[23] + (String)Protocolo[24] + (String)Protocolo[25] + (String)Protocolo[26] + (String)Protocolo[27]).toDouble();
int pwm = ((String)Protocolo[29] + (String)Protocolo[30]).toInt();
int dir = ((String)Protocolo[32] + (String)Protocolo[33]).toInt();
int brk = ((String)Protocolo[35] + (String)Protocolo[36]).toInt();
int stp = ((String)Protocolo[38] + (String)Protocolo[39]).toInt();
int hallA = ((String)Protocolo[41] + (String)Protocolo[42]).toInt();
int hallB = ((String)Protocolo[44] + (String)Protocolo[45]).toInt();
int hallC = ((String)Protocolo[47] + (String)Protocolo[48]).toInt();
Motor* _motor = MotorPorID(ID);
if (motor_ativado) {
if (Conectar) {
_motor->_canal = canal;
_motor->_pinoPWM = pwm;
_motor->_pinoDIR = dir;
_motor->_pinoBRK = brk;
_motor->_pinoSTP = stp;
_motor->_pinoHLA = hallA;
_motor->_pinoHLB = hallB;
_motor->_pinoHLC = hallC;
_motor->_MalhaFechada = _foc;
_motor->_Kp = _Kp;
_motor->_Ki = _Ki;
_motor->_Kd = _Kd;
_motor->Inicializar();
}
else {
_motor->Desligar();
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
}
else if (_funcao == Cmd) {
//canal;potencia;sentido;rampa;precisao;rpm
//0;000;0;000;000;000
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
Motor* _motor = MotorPorID(ID);
_motor->_SentidoSP = (Sentido)((String)Protocolo[3]).toInt();
_motor->_RPM_SP = ((String)Protocolo[5] + (String)Protocolo[6] + (String)Protocolo[7]).toInt();
_motor->_MalhaFechada = (String)Protocolo[9] == "1";
_motor->ReiniciarAceleracaoArr();
bool reverter = ((String)Protocolo[11]) == "1";
if (reverter) {
_motor->ReverterSentidoGiro();
}
}
else if (_funcao == Tst) {
String ID = ((String)Protocolo[0] +(String)Protocolo[1]);
Motor* _motor = MotorPorID(ID);
bool EmTeste = _motor->Testando;
if (!EmTeste) {
//_motor->Testar();
}
}
}
}
void RecalcularRelacaoPPR() {
RelacaoPPR = (60 / PPR) * 1000; // Multiplicador do cálculo de RPM (período em ms)
MenorPeriodo = RelacaoPPR / RpmMax; // Tempo mínimo de leitura
}
void BalanceamentoTask(void *pvParameters) {
while (1)
{
int _delay = delayBalanceamento > 0 ? delayBalanceamento : 5000;
if (Conectado && delayBalanceamento > 0) {
BalancearCargasMotores();
}
vTaskDelay(_delay);
}
}
void BalancearCargasMotores() {
RPM_Medio = (M1.RPM + M2.RPM + M3.RPM + M4.RPM) / 4.0;
RPM_SetPoint = (M1._RPM_SP + M2._RPM_SP + M3._RPM_SP + M4._RPM_SP) / 4.0;
RPM_Estavel = (RPM_Medio >= (RPM_SetPoint - RPM_Margem)) && (RPM_Medio <= (RPM_SetPoint + RPM_Margem));
double M1_Pot = M1.PotenciaAtual;
double M2_Pot = M2.PotenciaAtual;
double M3_Pot = M3.PotenciaAtual;
double M4_Pot = M4.PotenciaAtual;
double mediaPotencia = (M1_Pot + M2_Pot + M3_Pot + M4_Pot) / 4.0;
// Certifique-se de verificar se a potência atual não é zero antes de dividir
double offsetM1_RPM = M1_Pot != 0 ? (M1.RPM * (mediaPotencia - M1_Pot)) / M1_Pot : 0;
double offsetM2_RPM = M2_Pot != 0 ? (M2.RPM * (mediaPotencia - M2_Pot)) / M2_Pot : 0;
double offsetM3_RPM = M3_Pot != 0 ? (M3.RPM * (mediaPotencia - M3_Pot)) / M3_Pot : 0;
double offsetM4_RPM = M4_Pot != 0 ? (M4.RPM * (mediaPotencia - M4_Pot)) / M4_Pot : 0;
const double maxOffset = 10.0; // Valor máximo de offset para RPM, ajuste conforme necessário
// Aplica o offset com limitação
M1._RPM_Offset = fmin(fmax(offsetM1_RPM, -maxOffset), maxOffset);
M2._RPM_Offset = fmin(fmax(offsetM2_RPM, -maxOffset), maxOffset);
M3._RPM_Offset = fmin(fmax(offsetM3_RPM, -maxOffset), maxOffset);
M4._RPM_Offset = fmin(fmax(offsetM4_RPM, -maxOffset), maxOffset);
}

View File

@ -0,0 +1,8 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
]
}

View File

@ -30,6 +30,8 @@ class SensorTemperatura {
bool Iniciado = false;
SimpleKalmanFilter* tempKalman;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
@ -47,6 +49,8 @@ class SensorTemperatura {
Iniciado = true;
tempKalman = new SimpleKalmanFilter(2, 2, 0.01);
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
@ -60,6 +64,8 @@ class SensorTemperatura {
// Parar a execução das tarefas
vTaskDelete(STTaskHandle);
delete tempKalman;
// Redefinir as configurações para os valores iniciais
pinMode(_pino, INPUT);
@ -114,8 +120,7 @@ class SensorTemperatura {
double Vout, Rt = 0;
double T, Tc, Tf, adc = 0;
adc = analogRead(_pino); // VARIÁVEL QUE RECEBE A LEITURA DO NTC10K
//float adcValue = tempKalman->updateEstimate(adc);
float adcValue = adc;
float adcValue = tempKalman->updateEstimate(adc);
//CALCULOS PARA CONVERSÃO DA LEITURA RECEBIDA PELO ESP32 EM TEMPERATURA EM °C
Vout = (adcValue * Vs / adcMax) + Voffset;
Rt = R1 * Vout / (Vs - Vout);