From 1ae1be349ba02e8cd69d15b79e6d0ced2d40d8ae Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Fri, 3 Jul 2026 15:03:33 -0300 Subject: [PATCH] tratamentos de erro e robustez da classe serial service --- Instalador/Instalador.iss | 2 +- OrionTardPro/OrionTardPro/Enuns.cs | 10 + .../OrionTardPro/Forms/frmConexao.Designer.cs | 15 +- OrionTardPro/OrionTardPro/Forms/frmConexao.cs | 2 +- .../OrionTardPro/Forms/frmControlecarro.cs | 9 + .../Forms/frmParametros.Designer.cs | 164 +- .../OrionTardPro/Forms/frmParametros.cs | 9 + .../Forms/frmPrincipal.Designer.cs | 143 +- .../OrionTardPro/Forms/frmPrincipal.cs | 37 +- .../OrionTardPro/Forms/frmPrincipal.resx | 6 +- OrionTardPro/OrionTardPro/FuncoesGlobais.cs | 77 +- OrionTardPro/OrionTardPro/GeneralJoystick.cs | 35 +- OrionTardPro/OrionTardPro/Models/LogsModel.cs | 11 +- .../OrionTardPro/Models/PerfilModel.cs | 7 +- .../OrionTardPro/Properties/AssemblyInfo.cs | 4 +- .../OrionTardPro/Services/SerialService.cs | 1501 +++++++++++------ OrionTardPro/OrionTardPro/Variaveis.cs | 22 +- 17 files changed, 1428 insertions(+), 626 deletions(-) diff --git a/Instalador/Instalador.iss b/Instalador/Instalador.iss index 31c5734..d797c63 100644 --- a/Instalador/Instalador.iss +++ b/Instalador/Instalador.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "OrionTard Pro" -#define MyAppVersion "1.0.1.5" +#define MyAppVersion "1.0.1.8" #define MyAppPublisher "Zendion, Inc." #define MyAppURL "https://zendioninc.com.br" #define MyAppExeName "OrionTardPro.exe" diff --git a/OrionTardPro/OrionTardPro/Enuns.cs b/OrionTardPro/OrionTardPro/Enuns.cs index d0c687f..b4e912f 100644 --- a/OrionTardPro/OrionTardPro/Enuns.cs +++ b/OrionTardPro/OrionTardPro/Enuns.cs @@ -81,6 +81,7 @@ namespace OrionTardPro Tmp, // Temperatura Ods, // Odometro Pns, // Ping + Mod, // Dados Modulo } public enum TipoEmbreagem @@ -138,6 +139,15 @@ namespace OrionTardPro Perfil = 0, } + public enum ModeloEquipamento + { + Indefinido = 0, + Tardigrado = 1, + Factor2 = 2, + Factor3 = 3, + Factor4 = 4, + } + } } diff --git a/OrionTardPro/OrionTardPro/Forms/frmConexao.Designer.cs b/OrionTardPro/OrionTardPro/Forms/frmConexao.Designer.cs index 4ec5f2e..f641c1e 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmConexao.Designer.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmConexao.Designer.cs @@ -50,6 +50,7 @@ this.lblEnvios = new System.Windows.Forms.Label(); this.txtEnvios = new System.Windows.Forms.NumericUpDown(); this.btnConectar = new System.Windows.Forms.Button(); + this.chbPingCamera = new System.Windows.Forms.CheckBox(); this.tabControl1.SuspendLayout(); this.tabConexao.SuspendLayout(); this.tabReceptor.SuspendLayout(); @@ -233,6 +234,7 @@ // // tabTransmissor // + this.tabTransmissor.Controls.Add(this.chbPingCamera); this.tabTransmissor.Controls.Add(this.chbCamera); this.tabTransmissor.Controls.Add(this.lblSegundos); this.tabTransmissor.Controls.Add(this.lblTempoPings); @@ -250,7 +252,7 @@ // chbCamera // this.chbCamera.AutoSize = true; - this.chbCamera.Location = new System.Drawing.Point(17, 77); + this.chbCamera.Location = new System.Drawing.Point(11, 69); this.chbCamera.Name = "chbCamera"; this.chbCamera.Size = new System.Drawing.Size(204, 20); this.chbCamera.TabIndex = 5; @@ -343,6 +345,16 @@ this.btnConectar.UseVisualStyleBackColor = true; this.btnConectar.Click += new System.EventHandler(this.btnConectar_Click); // + // chbPingCamera + // + this.chbPingCamera.AutoSize = true; + this.chbPingCamera.Location = new System.Drawing.Point(11, 89); + this.chbPingCamera.Name = "chbPingCamera"; + this.chbPingCamera.Size = new System.Drawing.Size(184, 20); + this.chbPingCamera.TabIndex = 6; + this.chbPingCamera.Text = "Enviar ping para a câmera"; + this.chbPingCamera.UseVisualStyleBackColor = true; + // // frmConexao // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); @@ -399,5 +411,6 @@ public System.Windows.Forms.ComboBox cmbBaud; public System.Windows.Forms.ComboBox cmbPorta; public System.Windows.Forms.CheckBox chbRequisitarDados; + public System.Windows.Forms.CheckBox chbPingCamera; } } \ No newline at end of file diff --git a/OrionTardPro/OrionTardPro/Forms/frmConexao.cs b/OrionTardPro/OrionTardPro/Forms/frmConexao.cs index 73c0646..ef06647 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmConexao.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmConexao.cs @@ -55,7 +55,7 @@ namespace OrionTardPro SerialService.SensoresTimer.Interval = Convert.ToInt32(txtDelay.Value); SerialService.SensoresTimer.Start(); SerialService.EnvioTimer.Start(); - Variaveis.frmPrincipal.lblCarroconexao.Text = "Carro: Conectado"; + Variaveis.frmPrincipal.lblCarroconexao.Text = $"Carro: Conectado ({Variaveis._Model.ToString()} | NS {Variaveis._RobotNS} | FV {Variaveis._FirmwareVersion})"; } else MessageBox.Show("Houve um erro ao tentar conectar-se à prota " + SerialService.PortaCom + ".", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); diff --git a/OrionTardPro/OrionTardPro/Forms/frmControlecarro.cs b/OrionTardPro/OrionTardPro/Forms/frmControlecarro.cs index bc7348a..dd713b4 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmControlecarro.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmControlecarro.cs @@ -69,6 +69,15 @@ namespace OrionTardPro case Comando.ReleGeral: GeneralJoystick.AlternarStatusReleGeral(); break; + case Comando.MedidorEspessura: + bool carimbar = e.KeyCode == Keys.Q; + if (!carimbar) + { + Variaveis.frmPrincipal.trkMedidorEspessura.Value = Variaveis.Angulo_MedidorEspessuraVertical == 0 ? Variaveis.PerfilVigente.AnguloMedicaoIdeal : 0; + GeneralJoystick.AtualizaAnguloMedidorEspessura(Variaveis.frmPrincipal.trkMedidorEspessura.Value); + } + GeneralJoystick.AlternarAnguloMedidorEspessura(carimbar); + break; } } diff --git a/OrionTardPro/OrionTardPro/Forms/frmParametros.Designer.cs b/OrionTardPro/OrionTardPro/Forms/frmParametros.Designer.cs index f1be59a..8c467b3 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmParametros.Designer.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmParametros.Designer.cs @@ -125,6 +125,7 @@ this.chbCam = new System.Windows.Forms.CheckBox(); this.gpbAtuadores = new System.Windows.Forms.GroupBox(); this.pnlAtuadores = new System.Windows.Forms.Panel(); + this.chbMep = new System.Windows.Forms.CheckBox(); this.chbBrc = new System.Windows.Forms.CheckBox(); this.chbTransmissor = new System.Windows.Forms.CheckBox(); this.chbRaque = new System.Windows.Forms.CheckBox(); @@ -176,7 +177,14 @@ this.gpbTipoPerfil = new System.Windows.Forms.GroupBox(); this.rdbF4 = new System.Windows.Forms.RadioButton(); this.rdbF3 = new System.Windows.Forms.RadioButton(); - this.chbMep = new System.Windows.Forms.CheckBox(); + this.nudAnguloCarimboHorizontal = new System.Windows.Forms.NumericUpDown(); + this.lblAnguloCarimboHorizontal = new System.Windows.Forms.Label(); + this.nudAnguloMedicaoIdeal = new System.Windows.Forms.NumericUpDown(); + this.lblAnguloMedicaoIdeal = new System.Windows.Forms.Label(); + this.nudAnguloCarimboVertical = new System.Windows.Forms.NumericUpDown(); + this.lblAnguloCarimboVertical = new System.Windows.Forms.Label(); + this.nudAnguloMedicaoMargemLimite = new System.Windows.Forms.NumericUpDown(); + this.lblAnguloMedicaoMargemLimite = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.txtPings)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.txtResolucao)).BeginInit(); this.gpbParametros.SuspendLayout(); @@ -215,6 +223,10 @@ ((System.ComponentModel.ISupportInitialize)(this.nudOffsetDesenrolar)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nudOffsetEnrolar)).BeginInit(); this.gpbTipoPerfil.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloCarimboHorizontal)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloMedicaoIdeal)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloCarimboVertical)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloMedicaoMargemLimite)).BeginInit(); this.SuspendLayout(); // // lblDescricao @@ -384,6 +396,14 @@ // pnlParametros // this.pnlParametros.AutoScroll = true; + this.pnlParametros.Controls.Add(this.nudAnguloMedicaoMargemLimite); + this.pnlParametros.Controls.Add(this.lblAnguloMedicaoMargemLimite); + this.pnlParametros.Controls.Add(this.nudAnguloCarimboVertical); + this.pnlParametros.Controls.Add(this.lblAnguloCarimboVertical); + this.pnlParametros.Controls.Add(this.nudAnguloMedicaoIdeal); + this.pnlParametros.Controls.Add(this.lblAnguloMedicaoIdeal); + this.pnlParametros.Controls.Add(this.nudAnguloCarimboHorizontal); + this.pnlParametros.Controls.Add(this.lblAnguloCarimboHorizontal); this.pnlParametros.Controls.Add(this.nudCanalReleGeral); this.pnlParametros.Controls.Add(this.lblCanalReleGeral); this.pnlParametros.Controls.Add(this.nudEnderecoReleGeral); @@ -520,7 +540,7 @@ this.nudOdometroInspecao.Location = new System.Drawing.Point(235, 417); this.nudOdometroInspecao.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.nudOdometroInspecao.Maximum = new decimal(new int[] { - 99, + 99999, 0, 0, 0}); @@ -1391,6 +1411,16 @@ this.pnlAtuadores.Size = new System.Drawing.Size(155, 165); this.pnlAtuadores.TabIndex = 12; // + // chbMep + // + this.chbMep.AutoSize = true; + this.chbMep.Location = new System.Drawing.Point(8, 170); + this.chbMep.Name = "chbMep"; + this.chbMep.Size = new System.Drawing.Size(119, 20); + this.chbMep.TabIndex = 7; + this.chbMep.Text = "Medidor Espess."; + this.chbMep.UseVisualStyleBackColor = true; + // // chbBrc // this.chbBrc.AutoSize = true; @@ -1938,15 +1968,117 @@ this.rdbF3.Text = "<= F3"; this.rdbF3.UseVisualStyleBackColor = true; // - // chbMep + // nudAnguloCarimboHorizontal // - this.chbMep.AutoSize = true; - this.chbMep.Location = new System.Drawing.Point(8, 170); - this.chbMep.Name = "chbMep"; - this.chbMep.Size = new System.Drawing.Size(119, 20); - this.chbMep.TabIndex = 7; - this.chbMep.Text = "Medidor Espess."; - this.chbMep.UseVisualStyleBackColor = true; + this.nudAnguloCarimboHorizontal.Location = new System.Drawing.Point(235, 510); + this.nudAnguloCarimboHorizontal.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.nudAnguloCarimboHorizontal.Maximum = new decimal(new int[] { + 180, + 0, + 0, + 0}); + this.nudAnguloCarimboHorizontal.Name = "nudAnguloCarimboHorizontal"; + this.nudAnguloCarimboHorizontal.Size = new System.Drawing.Size(60, 23); + this.nudAnguloCarimboHorizontal.TabIndex = 58; + this.nudAnguloCarimboHorizontal.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.nudAnguloCarimboHorizontal.Value = new decimal(new int[] { + 67, + 0, + 0, + 0}); + // + // lblAnguloCarimboHorizontal + // + this.lblAnguloCarimboHorizontal.AutoSize = true; + this.lblAnguloCarimboHorizontal.Location = new System.Drawing.Point(20, 512); + this.lblAnguloCarimboHorizontal.Name = "lblAnguloCarimboHorizontal"; + this.lblAnguloCarimboHorizontal.Size = new System.Drawing.Size(162, 16); + this.lblAnguloCarimboHorizontal.TabIndex = 57; + this.lblAnguloCarimboHorizontal.Text = "Angulo Carimbo Horizontal"; + // + // nudAnguloMedicaoIdeal + // + this.nudAnguloMedicaoIdeal.Location = new System.Drawing.Point(235, 572); + this.nudAnguloMedicaoIdeal.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.nudAnguloMedicaoIdeal.Maximum = new decimal(new int[] { + 180, + 0, + 0, + 0}); + this.nudAnguloMedicaoIdeal.Name = "nudAnguloMedicaoIdeal"; + this.nudAnguloMedicaoIdeal.Size = new System.Drawing.Size(60, 23); + this.nudAnguloMedicaoIdeal.TabIndex = 60; + this.nudAnguloMedicaoIdeal.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.nudAnguloMedicaoIdeal.Value = new decimal(new int[] { + 132, + 0, + 0, + 0}); + // + // lblAnguloMedicaoIdeal + // + this.lblAnguloMedicaoIdeal.AutoSize = true; + this.lblAnguloMedicaoIdeal.Location = new System.Drawing.Point(20, 574); + this.lblAnguloMedicaoIdeal.Name = "lblAnguloMedicaoIdeal"; + this.lblAnguloMedicaoIdeal.Size = new System.Drawing.Size(133, 16); + this.lblAnguloMedicaoIdeal.TabIndex = 59; + this.lblAnguloMedicaoIdeal.Text = "Angulo Medição Ideal"; + // + // nudAnguloCarimboVertical + // + this.nudAnguloCarimboVertical.Location = new System.Drawing.Point(235, 541); + this.nudAnguloCarimboVertical.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.nudAnguloCarimboVertical.Maximum = new decimal(new int[] { + 180, + 0, + 0, + 0}); + this.nudAnguloCarimboVertical.Name = "nudAnguloCarimboVertical"; + this.nudAnguloCarimboVertical.Size = new System.Drawing.Size(60, 23); + this.nudAnguloCarimboVertical.TabIndex = 62; + this.nudAnguloCarimboVertical.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.nudAnguloCarimboVertical.Value = new decimal(new int[] { + 63, + 0, + 0, + 0}); + // + // lblAnguloCarimboVertical + // + this.lblAnguloCarimboVertical.AutoSize = true; + this.lblAnguloCarimboVertical.Location = new System.Drawing.Point(20, 543); + this.lblAnguloCarimboVertical.Name = "lblAnguloCarimboVertical"; + this.lblAnguloCarimboVertical.Size = new System.Drawing.Size(145, 16); + this.lblAnguloCarimboVertical.TabIndex = 61; + this.lblAnguloCarimboVertical.Text = "Angulo Carimbo Vertical"; + // + // nudAnguloMedicaoMargemLimite + // + this.nudAnguloMedicaoMargemLimite.Location = new System.Drawing.Point(235, 603); + this.nudAnguloMedicaoMargemLimite.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.nudAnguloMedicaoMargemLimite.Maximum = new decimal(new int[] { + 180, + 0, + 0, + 0}); + this.nudAnguloMedicaoMargemLimite.Name = "nudAnguloMedicaoMargemLimite"; + this.nudAnguloMedicaoMargemLimite.Size = new System.Drawing.Size(60, 23); + this.nudAnguloMedicaoMargemLimite.TabIndex = 64; + this.nudAnguloMedicaoMargemLimite.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.nudAnguloMedicaoMargemLimite.Value = new decimal(new int[] { + 20, + 0, + 0, + 0}); + // + // lblAnguloMedicaoMargemLimite + // + this.lblAnguloMedicaoMargemLimite.AutoSize = true; + this.lblAnguloMedicaoMargemLimite.Location = new System.Drawing.Point(20, 605); + this.lblAnguloMedicaoMargemLimite.Name = "lblAnguloMedicaoMargemLimite"; + this.lblAnguloMedicaoMargemLimite.Size = new System.Drawing.Size(199, 16); + this.lblAnguloMedicaoMargemLimite.TabIndex = 63; + this.lblAnguloMedicaoMargemLimite.Text = "Margem Medição Margem Limite"; // // frmParametros // @@ -2023,6 +2155,10 @@ ((System.ComponentModel.ISupportInitialize)(this.nudOffsetEnrolar)).EndInit(); this.gpbTipoPerfil.ResumeLayout(false); this.gpbTipoPerfil.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloCarimboHorizontal)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloMedicaoIdeal)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloCarimboVertical)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudAnguloMedicaoMargemLimite)).EndInit(); this.ResumeLayout(false); } @@ -2176,5 +2312,13 @@ public System.Windows.Forms.CheckBox chbBrc; public System.Windows.Forms.Button btnVerOdometro; public System.Windows.Forms.CheckBox chbMep; + public System.Windows.Forms.NumericUpDown nudAnguloMedicaoMargemLimite; + private System.Windows.Forms.Label lblAnguloMedicaoMargemLimite; + public System.Windows.Forms.NumericUpDown nudAnguloCarimboVertical; + private System.Windows.Forms.Label lblAnguloCarimboVertical; + public System.Windows.Forms.NumericUpDown nudAnguloMedicaoIdeal; + private System.Windows.Forms.Label lblAnguloMedicaoIdeal; + public System.Windows.Forms.NumericUpDown nudAnguloCarimboHorizontal; + private System.Windows.Forms.Label lblAnguloCarimboHorizontal; } } \ No newline at end of file diff --git a/OrionTardPro/OrionTardPro/Forms/frmParametros.cs b/OrionTardPro/OrionTardPro/Forms/frmParametros.cs index ff49400..7ad14db 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmParametros.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmParametros.cs @@ -44,6 +44,10 @@ namespace OrionTardPro rdbF4.Checked = Variaveis.PerfilVigente.FirmwareF4; nudEnderecoReleGeral.Value = Variaveis.PerfilVigente.EnderecoReleGeral; nudCanalReleGeral.Value = Variaveis.PerfilVigente.CanalReleGeral; + nudAnguloCarimboHorizontal.Value = Variaveis.PerfilVigente.AnguloCarimboHorizontal; + nudAnguloCarimboVertical.Value = Variaveis.PerfilVigente.AnguloCarimboVertical; + nudAnguloMedicaoIdeal.Value = Variaveis.PerfilVigente.AnguloMedicaoIdeal; + nudAnguloMedicaoMargemLimite.Value = Variaveis.PerfilVigente.AnguloMedicaoMargemLimite; chbGas.Checked = Variaveis.PerfilVigente.Sensor_Ativado_GAS == Estado.Ligado; chbTmp.Checked = Variaveis.PerfilVigente.Sensor_Ativado_TMP == Estado.Ligado; @@ -163,6 +167,11 @@ namespace OrionTardPro Variaveis.PerfilVigente.EnderecoReleGeral = Convert.ToByte(nudEnderecoReleGeral.Value); Variaveis.PerfilVigente.CanalReleGeral = Convert.ToInt32(nudCanalReleGeral.Value); + Variaveis.PerfilVigente.AnguloCarimboHorizontal = Convert.ToInt32(nudAnguloCarimboHorizontal.Value); + Variaveis.PerfilVigente.AnguloCarimboVertical = Convert.ToInt32(nudAnguloCarimboVertical.Value); + Variaveis.PerfilVigente.AnguloMedicaoIdeal = Convert.ToInt32(nudAnguloMedicaoIdeal.Value); + Variaveis.PerfilVigente.AnguloMedicaoMargemLimite = Convert.ToInt32(nudAnguloMedicaoMargemLimite.Value); + Variaveis.SetVariaveisGerais(false); Variaveis.frmPrincipal.AtualizaDadosIniciais(false); } diff --git a/OrionTardPro/OrionTardPro/Forms/frmPrincipal.Designer.cs b/OrionTardPro/OrionTardPro/Forms/frmPrincipal.Designer.cs index 60812de..768ebf8 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmPrincipal.Designer.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmPrincipal.Designer.cs @@ -151,7 +151,10 @@ this.gpbMarcadores = new System.Windows.Forms.GroupBox(); this.imgInicio = new System.Windows.Forms.PictureBox(); this.imgAddmarcacao = new System.Windows.Forms.PictureBox(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.tmrTempoAtivo = new System.Windows.Forms.Timer(this.components); + this.tmrVelocidade = new System.Windows.Forms.Timer(this.components); + this.btnMedir = new System.Windows.Forms.Button(); this.lblCarroconexao = new System.Windows.Forms.ToolStripStatusLabel(); this.lblJoystickconexao = new System.Windows.Forms.ToolStripStatusLabel(); this.lblCameraconexao = new System.Windows.Forms.ToolStripStatusLabel(); @@ -165,9 +168,7 @@ this.lblPerfil = new System.Windows.Forms.ToolStripStatusLabel(); this.lblDivisor4 = new System.Windows.Forms.ToolStripStatusLabel(); this.lblTempo = new System.Windows.Forms.ToolStripStatusLabel(); - this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); - this.tmrTempoAtivo = new System.Windows.Forms.Timer(this.components); - this.tmrVelocidade = new System.Windows.Forms.Timer(this.components); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.menuStrip1.SuspendLayout(); this.pnlEsquerdo.SuspendLayout(); this.tabControl1.SuspendLayout(); @@ -864,6 +865,7 @@ // // gpbMedidorEspessura // + this.gpbMedidorEspessura.Controls.Add(this.btnMedir); this.gpbMedidorEspessura.Controls.Add(this.lblMepStatus); this.gpbMedidorEspessura.Controls.Add(this.imgMepContato); this.gpbMedidorEspessura.Controls.Add(this.btnCarimbar); @@ -872,7 +874,7 @@ this.gpbMedidorEspessura.Controls.Add(this.lblAnguloMedidorEspessura); this.gpbMedidorEspessura.Location = new System.Drawing.Point(4, 519); this.gpbMedidorEspessura.Name = "gpbMedidorEspessura"; - this.gpbMedidorEspessura.Size = new System.Drawing.Size(178, 146); + this.gpbMedidorEspessura.Size = new System.Drawing.Size(178, 162); this.gpbMedidorEspessura.TabIndex = 33; this.gpbMedidorEspessura.TabStop = false; this.gpbMedidorEspessura.Text = "Medidor de Espessura"; @@ -881,7 +883,7 @@ // this.lblMepStatus.AutoSize = true; this.lblMepStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblMepStatus.Location = new System.Drawing.Point(92, 88); + this.lblMepStatus.Location = new System.Drawing.Point(7, 104); this.lblMepStatus.Name = "lblMepStatus"; this.lblMepStatus.Size = new System.Drawing.Size(41, 13); this.lblMepStatus.TabIndex = 32; @@ -890,7 +892,7 @@ // imgMepContato // this.imgMepContato.Image = global::OrionTardPro.Properties.Resources.led_vermelho_off; - this.imgMepContato.Location = new System.Drawing.Point(135, 105); + this.imgMepContato.Location = new System.Drawing.Point(8, 122); this.imgMepContato.Name = "imgMepContato"; this.imgMepContato.Size = new System.Drawing.Size(34, 34); this.imgMepContato.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; @@ -899,9 +901,9 @@ // // btnCarimbar // - this.btnCarimbar.Location = new System.Drawing.Point(6, 83); + this.btnCarimbar.Location = new System.Drawing.Point(6, 20); this.btnCarimbar.Name = "btnCarimbar"; - this.btnCarimbar.Size = new System.Drawing.Size(75, 23); + this.btnCarimbar.Size = new System.Drawing.Size(69, 23); this.btnCarimbar.TabIndex = 4; this.btnCarimbar.Text = "Carimbar"; this.btnCarimbar.UseVisualStyleBackColor = true; @@ -909,9 +911,9 @@ // // btnRetornar // - this.btnRetornar.Location = new System.Drawing.Point(6, 112); + this.btnRetornar.Location = new System.Drawing.Point(6, 78); this.btnRetornar.Name = "btnRetornar"; - this.btnRetornar.Size = new System.Drawing.Size(75, 23); + this.btnRetornar.Size = new System.Drawing.Size(69, 23); this.btnRetornar.TabIndex = 30; this.btnRetornar.Text = "Retornar"; this.btnRetornar.UseVisualStyleBackColor = true; @@ -920,12 +922,14 @@ // trkMedidorEspessura // this.trkMedidorEspessura.BackColor = System.Drawing.Color.White; - this.trkMedidorEspessura.Location = new System.Drawing.Point(6, 32); + this.trkMedidorEspessura.Location = new System.Drawing.Point(127, 7); this.trkMedidorEspessura.Maximum = 180; this.trkMedidorEspessura.Name = "trkMedidorEspessura"; - this.trkMedidorEspessura.Size = new System.Drawing.Size(166, 45); + this.trkMedidorEspessura.Orientation = System.Windows.Forms.Orientation.Vertical; + this.trkMedidorEspessura.Size = new System.Drawing.Size(45, 152); this.trkMedidorEspessura.TabIndex = 29; this.trkMedidorEspessura.TickFrequency = 10; + this.trkMedidorEspessura.TickStyle = System.Windows.Forms.TickStyle.TopLeft; this.trkMedidorEspessura.Scroll += new System.EventHandler(this.trkMedidorEspessura_Scroll); this.trkMedidorEspessura.KeyUp += new System.Windows.Forms.KeyEventHandler(this.trkMedidorEspessura_KeyUp); this.trkMedidorEspessura.MouseUp += new System.Windows.Forms.MouseEventHandler(this.trkMedidorEspessura_MouseUp); @@ -934,7 +938,7 @@ // this.lblAnguloMedidorEspessura.AutoSize = true; this.lblAnguloMedidorEspessura.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblAnguloMedidorEspessura.Location = new System.Drawing.Point(140, 16); + this.lblAnguloMedidorEspessura.Location = new System.Drawing.Point(93, 138); this.lblAnguloMedidorEspessura.Name = "lblAnguloMedidorEspessura"; this.lblAnguloMedidorEspessura.Size = new System.Drawing.Size(29, 13); this.lblAnguloMedidorEspessura.TabIndex = 28; @@ -1573,28 +1577,32 @@ this.imgAddmarcacao.TabStop = false; this.imgAddmarcacao.Click += new System.EventHandler(this.imgAddmarcacao_Click); // - // statusStrip1 + // contextMenuStrip1 // - this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.lblCarroconexao, - this.lblJoystickconexao, - this.lblCameraconexao, - this.lblCameraselecionada, - this.lblStatusCamera, - this.lblPipeline1, - this.lblEnvio, - this.pgbEnvio, - this.lblDebugcontrole, - this.lblDivisor3, - this.lblPerfil, - this.lblDivisor4, - this.lblTempo}); - this.statusStrip1.Location = new System.Drawing.Point(0, 645); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(1294, 22); - this.statusStrip1.TabIndex = 1; - this.statusStrip1.Text = "statusStrip1"; + this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); + // + // tmrTempoAtivo + // + this.tmrTempoAtivo.Enabled = true; + this.tmrTempoAtivo.Interval = 1000; + this.tmrTempoAtivo.Tick += new System.EventHandler(this.tmrTempoAtivo_Tick); + // + // tmrVelocidade + // + this.tmrVelocidade.Interval = 10; + this.tmrVelocidade.Tick += new System.EventHandler(this.tmrVelocidade_Tick); + // + // btnMedir + // + this.btnMedir.Location = new System.Drawing.Point(6, 49); + this.btnMedir.Name = "btnMedir"; + this.btnMedir.Size = new System.Drawing.Size(69, 23); + this.btnMedir.TabIndex = 33; + this.btnMedir.Text = "Medir"; + this.btnMedir.UseVisualStyleBackColor = true; + this.btnMedir.Click += new System.EventHandler(this.btnMedir_Click); // // lblCarroconexao // @@ -1676,22 +1684,28 @@ this.lblTempo.Size = new System.Drawing.Size(280, 17); this.lblTempo.Text = "Tempo Ativo: 00:00:00 - Tempo Conectado: 00:00:00"; // - // contextMenuStrip1 + // statusStrip1 // - this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); - // - // tmrTempoAtivo - // - this.tmrTempoAtivo.Enabled = true; - this.tmrTempoAtivo.Interval = 1000; - this.tmrTempoAtivo.Tick += new System.EventHandler(this.tmrTempoAtivo_Tick); - // - // tmrVelocidade - // - this.tmrVelocidade.Interval = 10; - this.tmrVelocidade.Tick += new System.EventHandler(this.tmrVelocidade_Tick); + this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.lblCarroconexao, + this.lblJoystickconexao, + this.lblCameraconexao, + this.lblCameraselecionada, + this.lblStatusCamera, + this.lblPipeline1, + this.lblEnvio, + this.pgbEnvio, + this.lblDebugcontrole, + this.lblDivisor3, + this.lblPerfil, + this.lblDivisor4, + this.lblTempo}); + this.statusStrip1.Location = new System.Drawing.Point(0, 645); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(1294, 22); + this.statusStrip1.TabIndex = 1; + this.statusStrip1.Text = "statusStrip1"; // // frmPrincipal // @@ -1809,10 +1823,6 @@ private System.Windows.Forms.Panel pnlCameraBottom; private System.Windows.Forms.ToolStripMenuItem serviçoToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem controleToolStripMenuItem; - private System.Windows.Forms.StatusStrip statusStrip1; - public System.Windows.Forms.ToolStripStatusLabel lblCarroconexao; - public System.Windows.Forms.ToolStripStatusLabel lblJoystickconexao; - public System.Windows.Forms.ToolStripStatusLabel lblCameraconexao; private System.Windows.Forms.PictureBox imgSalvar; public System.Windows.Forms.PictureBox imgCamera; public System.Windows.Forms.Label lblLegendaexemplo; @@ -1830,7 +1840,6 @@ private System.Windows.Forms.ToolStripMenuItem verToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem btnGaleria; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; - private System.Windows.Forms.ToolStripStatusLabel lblPipeline1; public System.Windows.Forms.PictureBox imgAnalogico; private System.Windows.Forms.ToolStripMenuItem btnEmpresa; private System.Windows.Forms.ToolStripMenuItem btnSobre; @@ -1855,17 +1864,11 @@ public System.Windows.Forms.PictureBox imgBrilhomenos; public System.Windows.Forms.PictureBox imgBrilhomais; public System.Windows.Forms.PictureBox imgLigalaser; - private System.Windows.Forms.ToolStripStatusLabel lblEnvio; - public System.Windows.Forms.ToolStripStatusLabel lblDebugcontrole; public System.Windows.Forms.GroupBox gpbImagem; - private System.Windows.Forms.ToolStripStatusLabel lblDivisor3; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; private System.Windows.Forms.ToolStripMenuItem perfilToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem btnSalvarperfil; private System.Windows.Forms.ToolStripMenuItem btnCarregarperfil; - public System.Windows.Forms.ToolStripStatusLabel lblPerfil; - private System.Windows.Forms.ToolStripStatusLabel lblDivisor4; - private System.Windows.Forms.ToolStripStatusLabel lblTempo; private System.Windows.Forms.Timer tmrTempoAtivo; private System.Windows.Forms.TabControl tabControl1; private System.Windows.Forms.TabPage tabSensores; @@ -1876,7 +1879,6 @@ private System.Windows.Forms.PictureBox imgIniciarGravacao; private System.Windows.Forms.PictureBox imgPararGravacao; public System.Windows.Forms.GroupBox gpbGravacao; - private System.Windows.Forms.ToolStripStatusLabel lblStatusCamera; public System.Windows.Forms.Label lblInclinacaoy; public System.Windows.Forms.Label lblInclinacaox; public System.Windows.Forms.Label lblTemperaturavalor; @@ -1891,7 +1893,6 @@ public System.Windows.Forms.Label lblOdometroTempo; private System.Windows.Forms.ToolStripMenuItem teclasDeAtalhoToolStripMenuItem; private System.Windows.Forms.PictureBox picRoboSuperior; - public System.Windows.Forms.ToolStripProgressBar pgbEnvio; public System.Windows.Forms.GroupBox gpbControlemotores; public System.Windows.Forms.PictureBox imgLaser; public System.Windows.Forms.Timer tmrVelocidade; @@ -1904,7 +1905,6 @@ public System.Windows.Forms.PictureBox imgInicio; public System.Windows.Forms.Label lblOdometroparcial; public System.Windows.Forms.Label lblDeslocamentovalor; - public System.Windows.Forms.ToolStripStatusLabel lblCameraselecionada; public System.Windows.Forms.Label lblCameraAtual; public CircularProgressBar.CircularProgressBar pgbUmidade; public System.Windows.Forms.PictureBox imgTermometro; @@ -1936,6 +1936,21 @@ private System.Windows.Forms.Button btnRetornar; public System.Windows.Forms.Label lblMepStatus; public System.Windows.Forms.PictureBox imgMepContato; + private System.Windows.Forms.Button btnMedir; + public System.Windows.Forms.ToolStripStatusLabel lblCarroconexao; + public System.Windows.Forms.ToolStripStatusLabel lblJoystickconexao; + public System.Windows.Forms.ToolStripStatusLabel lblCameraconexao; + public System.Windows.Forms.ToolStripStatusLabel lblCameraselecionada; + private System.Windows.Forms.ToolStripStatusLabel lblStatusCamera; + private System.Windows.Forms.ToolStripStatusLabel lblPipeline1; + private System.Windows.Forms.ToolStripStatusLabel lblEnvio; + public System.Windows.Forms.ToolStripProgressBar pgbEnvio; + public System.Windows.Forms.ToolStripStatusLabel lblDebugcontrole; + private System.Windows.Forms.ToolStripStatusLabel lblDivisor3; + public System.Windows.Forms.ToolStripStatusLabel lblPerfil; + private System.Windows.Forms.ToolStripStatusLabel lblDivisor4; + private System.Windows.Forms.ToolStripStatusLabel lblTempo; + private System.Windows.Forms.StatusStrip statusStrip1; } } diff --git a/OrionTardPro/OrionTardPro/Forms/frmPrincipal.cs b/OrionTardPro/OrionTardPro/Forms/frmPrincipal.cs index 4be288a..211c9e0 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmPrincipal.cs +++ b/OrionTardPro/OrionTardPro/Forms/frmPrincipal.cs @@ -22,6 +22,7 @@ namespace OrionTardPro public bool FechandoControle = false; public System.Drawing.Point P1Odometro; public System.Drawing.Point P2Odometro; + Timer tmrAtualizacao; #endregion @@ -69,6 +70,19 @@ namespace OrionTardPro GeneralJoystick.InstanciaJoystick(); Variaveis.frmCamera.AtualizaListaCameras(); + + tmrAtualizacao = new Timer(); + tmrAtualizacao.Interval = 500; + tmrAtualizacao.Tick += tmrAtualizacao_Tick; + tmrAtualizacao.Start(); + } + + private void tmrAtualizacao_Tick(object sender, EventArgs e) + { + lblMepStatus.Text = + Variaveis.Carimbando ? "Carimbando" : + Variaveis.Angulo_MedidorEspessuraVertical > 0 ? "Atuado" : + "Parado"; } private void frmPrincipal_FormClosed(object sender, FormClosedEventArgs e) @@ -81,13 +95,13 @@ namespace OrionTardPro { LogsFuncoes.RegistrarLog(); - if (MessageBox.Show("Tem certeza que deseja sair?", "Sair", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + if (MessageBox.Show("Tem certeza que deseja sair?", "Sair", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { - Environment.Exit(0); + e.Cancel = true; } else { - e.Cancel = true; + try { Environment.Exit(0); } catch { } } } @@ -390,6 +404,7 @@ namespace OrionTardPro { trkVelocidade.Maximum = Variaveis.PerfilVigente.PotenciaMaxima; trkVelocidade.Minimum = Variaveis.PerfilVigente.PotenciaMinima; + trkMedidorEspessura.Maximum = Variaveis.PerfilVigente.AnguloMedicaoIdeal + Variaveis.PerfilVigente.AnguloMedicaoMargemLimite; Variaveis.frmControle.trkRampaaceleracao.Maximum = Variaveis.PerfilVigente.RampaMaxima; Variaveis.frmControle.trkRampaaceleracao.Minimum = Variaveis.PerfilVigente.RampaMinima; Variaveis.frmControle.trkPrecisaorampa.Maximum = Variaveis.PerfilVigente.PrecisaoMaxima; @@ -452,9 +467,10 @@ namespace OrionTardPro pgbUmidade.Value = 0; AlturaCano = pnlDireito.Height - 50; + this.Text = VariaveisGerais.NomeProjeto + " v" + VariaveisGerais.Versao; if (Variaveis.Cliente != null) { - this.Text = VariaveisGerais.NomeProjeto + " v" + VariaveisGerais.Versao + " - " + Variaveis.Cliente.Servico + " (" + Variaveis.Cliente.Nome + ")"; + this.Text += " - " + Variaveis.Cliente.Servico + " (" + Variaveis.Cliente.Nome + ")"; DirectoryInfo Path = new DirectoryInfo(Variaveis.Cliente.Path); Variaveis.IndexFotosIndentificacao = Path.GetFiles().Count(x => x.Extension == Variaveis.ExtIdentificacao); @@ -690,7 +706,10 @@ namespace OrionTardPro System.Environment.NewLine + "Capturar Imagem: C" + System.Environment.NewLine + "Adicionar Marcador: M" + System.Environment.NewLine + - "Iniciar/Parar Odômetro Parcial: O" + System.Environment.NewLine + + "Iniciar/Parar Odômetro Parcial: O" + System.Environment.NewLine + + System.Environment.NewLine + + "Carimbar Medidor de Espessura: Q" + System.Environment.NewLine + + "Avançar/Recuar Medidor de Espessura: E" + System.Environment.NewLine + ""; MessageBox.Show(Mensagem, "Teclas de Atalho", MessageBoxButtons.OK, MessageBoxIcon.Information); } @@ -731,9 +750,13 @@ namespace OrionTardPro GeneralJoystick.AlternarAnguloMedidorEspessura(false); } - + private void btnMedir_Click(object sender, EventArgs e) + { + trkMedidorEspessura.Value = Variaveis.PerfilVigente.AnguloMedicaoIdeal; + GeneralJoystick.AtualizaAnguloMedidorEspessura(Variaveis.PerfilVigente.AnguloMedicaoIdeal); + GeneralJoystick.AlternarAnguloMedidorEspessura(false); + } - } } diff --git a/OrionTardPro/OrionTardPro/Forms/frmPrincipal.resx b/OrionTardPro/OrionTardPro/Forms/frmPrincipal.resx index c490b5e..a12b118 100644 --- a/OrionTardPro/OrionTardPro/Forms/frmPrincipal.resx +++ b/OrionTardPro/OrionTardPro/Forms/frmPrincipal.resx @@ -368,9 +368,6 @@ TkSuQmCC - - 522, 16 - 645, 16 @@ -380,6 +377,9 @@ 1263, 23 + + 522, 16 + 63 diff --git a/OrionTardPro/OrionTardPro/FuncoesGlobais.cs b/OrionTardPro/OrionTardPro/FuncoesGlobais.cs index ca5cc27..1a82d02 100644 --- a/OrionTardPro/OrionTardPro/FuncoesGlobais.cs +++ b/OrionTardPro/OrionTardPro/FuncoesGlobais.cs @@ -112,55 +112,62 @@ namespace OrionTardPro public static Image RotacionarImagem(Image img, double rotationAngle, bool redimensionarParaCaber = true) { - // Calcula as novas dimensões do bitmap com base na rotação - double angleRad = rotationAngle / 180.0 * Math.PI; - double sin = Math.Abs(Math.Sin(angleRad)); - double cos = Math.Abs(Math.Cos(angleRad)); - int newWidth = (int)(img.Width * cos + img.Height * sin); - int newHeight = (int)(img.Width * sin + img.Height * cos); - - Bitmap bmp; - - if (redimensionarParaCaber) + try { - // Cria um novo bitmap com as dimensões calculadas - bmp = new Bitmap(newWidth, newHeight); - } - else - { - // Cria um novo bitmap com as dimensões originais - bmp = new Bitmap(img.Width, img.Height); - } + // Calcula as novas dimensões do bitmap com base na rotação + double angleRad = rotationAngle / 180.0 * Math.PI; + double sin = Math.Abs(Math.Sin(angleRad)); + double cos = Math.Abs(Math.Cos(angleRad)); + int newWidth = (int)(img.Width * cos + img.Height * sin); + int newHeight = (int)(img.Width * sin + img.Height * cos); - using (Graphics gfx = Graphics.FromImage(bmp)) - { - gfx.Clear(Color.Transparent); // Define a cor de fundo como transparente + Bitmap bmp; if (redimensionarParaCaber) { - gfx.TranslateTransform(newWidth / 2f, newHeight / 2f); // Move o ponto de rotação para o centro do novo bitmap + // Cria um novo bitmap com as dimensões calculadas + bmp = new Bitmap(newWidth, newHeight); } else { - gfx.TranslateTransform(img.Width / 2f, img.Height / 2f); // Move o ponto de rotação para o centro do bitmap original + // Cria um novo bitmap com as dimensões originais + bmp = new Bitmap(img.Width, img.Height); } - gfx.RotateTransform((float)rotationAngle); // Aplica a rotação - - if (redimensionarParaCaber) + using (Graphics gfx = Graphics.FromImage(bmp)) { - gfx.TranslateTransform(-img.Width / 2f, -img.Height / 2f); // Move a imagem de volta para o centro - } - else - { - gfx.TranslateTransform(-img.Width / 2f, -img.Height / 2f); // Move a imagem de volta para o centro + gfx.Clear(Color.Transparent); // Define a cor de fundo como transparente + + if (redimensionarParaCaber) + { + gfx.TranslateTransform(newWidth / 2f, newHeight / 2f); // Move o ponto de rotação para o centro do novo bitmap + } + else + { + gfx.TranslateTransform(img.Width / 2f, img.Height / 2f); // Move o ponto de rotação para o centro do bitmap original + } + + gfx.RotateTransform((float)rotationAngle); // Aplica a rotação + + if (redimensionarParaCaber) + { + gfx.TranslateTransform(-img.Width / 2f, -img.Height / 2f); // Move a imagem de volta para o centro + } + else + { + gfx.TranslateTransform(-img.Width / 2f, -img.Height / 2f); // Move a imagem de volta para o centro + } + + gfx.InterpolationMode = InterpolationMode.HighQualityBicubic; + gfx.DrawImage(img, 0, 0, img.Width, img.Height); // Desenha a imagem original no bitmap } - gfx.InterpolationMode = InterpolationMode.HighQualityBicubic; - gfx.DrawImage(img, 0, 0, img.Width, img.Height); // Desenha a imagem original no bitmap + return bmp; + } + catch (Exception ex) + { + return null; } - - return bmp; } public static double NormalizarAngulo(double angulo) diff --git a/OrionTardPro/OrionTardPro/GeneralJoystick.cs b/OrionTardPro/OrionTardPro/GeneralJoystick.cs index 06c9a17..2e93c51 100644 --- a/OrionTardPro/OrionTardPro/GeneralJoystick.cs +++ b/OrionTardPro/OrionTardPro/GeneralJoystick.cs @@ -30,6 +30,8 @@ namespace OrionTardPro static bool UltimoDireita = false; static bool UltimoCima = false; + static int PulsosCameraLedMais = 0; + public static void Inicializar() { joystickTimer = new System.Windows.Forms.Timer() @@ -427,8 +429,8 @@ namespace OrionTardPro public static void AtualizaAnguloMedidorEspessura(int Angulo) { - Variaveis.Angulo_MedidorEspessura = Angulo; - Variaveis.frmPrincipal.lblAnguloMedidorEspessura.Text = Variaveis.Angulo_MedidorEspessura.ToString("000") + "°"; + Variaveis.Angulo_MedidorEspessuraVertical = Angulo; + Variaveis.frmPrincipal.lblAnguloMedidorEspessura.Text = Variaveis.Angulo_MedidorEspessuraVertical.ToString("000") + "°"; } @@ -647,6 +649,17 @@ namespace OrionTardPro } + public static void EnviarPingCamera() + { + if (Variaveis.frmConexao.chbPingCamera.Checked && PulsosCameraLedMais > 0) + { + for (int i = 0; i < PulsosCameraLedMais; i++) + { + AumentarIntensidadeBrilhoLED(); + } + } + } + public static void ReduzirIntensidadeBrilhoLED() { if (SerialService.Conectado) @@ -654,6 +667,7 @@ namespace OrionTardPro Variaveis.frmPrincipal.lblDebugcontrole.Text = "Câmera LED -"; if (Variaveis.frmConexao.chbCamera.Checked) { + PulsosCameraLedMais = 0; SerialService.ControleCamera(0xbb); SerialService.ControleCamera(0x66); } @@ -666,13 +680,15 @@ namespace OrionTardPro AvisoFuncaoDesconectado(); } - public static void AumentarIntensidadeBrilhoLED() + public static void AumentarIntensidadeBrilhoLED(bool ping = false) { if (SerialService.Conectado) { Variaveis.frmPrincipal.lblDebugcontrole.Text = "Câmera LED +"; if (Variaveis.frmConexao.chbCamera.Checked) { + if (!ping) + PulsosCameraLedMais = Math.Min(PulsosCameraLedMais + 1, 5); SerialService.ControleCamera(0xbb); SerialService.ControleCamera(0x55); } @@ -737,6 +753,13 @@ namespace OrionTardPro public static void AlternarAnguloMedidorEspessura(bool carimbar) { + if (Variaveis.Carimbando) + { + MessageBox.Show("Processo de carimbo em andamento!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning); + Variaveis.frmPrincipal.trkMedidorEspessura.Value = 0; + AtualizaAnguloMedidorEspessura(0); + return; + } if (!SerialService.Conectado) AvisoFuncaoDesconectado(); else if (Variaveis.PerfilVigente.Atuador_Ativado_MEP == Estado.Desligado) @@ -750,7 +773,7 @@ namespace OrionTardPro private static void AtualizaProtocoloMedidorEspessura(bool carimbar) { Variaveis.Carimbar = carimbar; - Variaveis.frmPrincipal.lblDebugcontrole.Text = "Angulo do Medidor: " + Variaveis.Angulo_MedidorEspessura.ToString("000") + "°"; + Variaveis.frmPrincipal.lblDebugcontrole.Text = "Angulo do Medidor: " + Variaveis.Angulo_MedidorEspessuraVertical.ToString("000") + "°"; SerialService.EnviaProtocolo(TipoProtocolo.Carro, TipoAtuador.Mep); } @@ -805,6 +828,10 @@ namespace OrionTardPro case Keys.G: TipoControle = Comando.ReleGeral; break; + case Keys.Q: + case Keys.E: + TipoControle = Comando.MedidorEspessura; + break; } return TipoControle; diff --git a/OrionTardPro/OrionTardPro/Models/LogsModel.cs b/OrionTardPro/OrionTardPro/Models/LogsModel.cs index 32e2966..f48f074 100644 --- a/OrionTardPro/OrionTardPro/Models/LogsModel.cs +++ b/OrionTardPro/OrionTardPro/Models/LogsModel.cs @@ -6,11 +6,6 @@ using System.Collections.Specialized; using System.Device.Location; using System.IO; using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using System.Web.UI.WebControls; using static OrionTardPro.Enuns; namespace OrionTardPro.Models @@ -27,6 +22,9 @@ namespace OrionTardPro.Models public class LogModel { public DateTime data { get; set; } + public int firmwareVersao { get; set; } + public int robotNs { get; set; } + public string modelo { get; set; } public string versao { get; set; } public string cpf { get; set; } public string usuario { get; set; } @@ -81,6 +79,9 @@ namespace OrionTardPro.Models LogModel Log = new LogModel() { data = DateTime.Now, + firmwareVersao = Variaveis._FirmwareVersion, + robotNs = Variaveis._RobotNS, + modelo = Variaveis._Model.ToString(), versao = VariaveisGerais.Versao, servico = Variaveis.Cliente, camera = Variaveis.frmPrincipal.lblCameraconexao.Text, diff --git a/OrionTardPro/OrionTardPro/Models/PerfilModel.cs b/OrionTardPro/OrionTardPro/Models/PerfilModel.cs index 537f59c..e75dca2 100644 --- a/OrionTardPro/OrionTardPro/Models/PerfilModel.cs +++ b/OrionTardPro/OrionTardPro/Models/PerfilModel.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using static OrionTardPro.Enuns; namespace OrionTardPro.Models @@ -84,6 +81,10 @@ namespace OrionTardPro.Models public bool FirmwareF4 { get; set; } = false; public byte EnderecoReleGeral { get; set; } = 0x00; public int CanalReleGeral { get; set; } = 1; + public int AnguloCarimboHorizontal { get; set; } = 67; + public int AnguloCarimboVertical { get; set; } = 63; + public int AnguloMedicaoIdeal { get; set; } = 132; + public int AnguloMedicaoMargemLimite { get; set; } = 20; public List ListaAlertas { get; set; } = new List(); diff --git a/OrionTardPro/OrionTardPro/Properties/AssemblyInfo.cs b/OrionTardPro/OrionTardPro/Properties/AssemblyInfo.cs index 95e25f2..939cb87 100644 --- a/OrionTardPro/OrionTardPro/Properties/AssemblyInfo.cs +++ b/OrionTardPro/OrionTardPro/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // É possível especificar todos os valores ou usar como padrão os Números de Build e da Revisão // utilizando o "*" como mostrado abaixo: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.1.5")] -[assembly: AssemblyFileVersion("1.0.1.5")] +[assembly: AssemblyVersion("1.0.1.8")] +[assembly: AssemblyFileVersion("1.0.1.8")] diff --git a/OrionTardPro/OrionTardPro/Services/SerialService.cs b/OrionTardPro/OrionTardPro/Services/SerialService.cs index 215fdbc..27e76f9 100644 --- a/OrionTardPro/OrionTardPro/Services/SerialService.cs +++ b/OrionTardPro/OrionTardPro/Services/SerialService.cs @@ -1,39 +1,73 @@ -using System; +using System; using System.Collections.Generic; +using System.Globalization; using System.IO.Ports; using System.Linq; using System.Text; -using System.Threading.Tasks; -using static OrionTardPro.Enuns; -using System.Windows.Forms; using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using static OrionTardPro.Enuns; namespace OrionTardPro.Services { public class SerialService { + public enum EstrategiaCameraSerial + { + Auto = 0, + PortaSeparada = 1, + MesmaPortaMesmoBaud = 2, + PonteFirmwareTexto = 3, + TrocaBaudMesmaPortaExperimental = 4, + Desabilitada = 5 + } + public static SerialPort _PortaRS485; + private static SerialPort _PortaCamera; public static bool Conectado { get; set; } + public static bool CameraConectada { get; private set; } + + // Porta do rover/firmware. + public static string PortaCom { get; set; } + + // Configure essa porta somente se a câmera estiver em OUTRA COM física. + // Não use o mesmo valor de PortaCom aqui. Windows normalmente não permite abrir a mesma COM duas vezes. + public static string PortaComCamera { get; set; } = ""; + public static int BaudRateCamera { get; set; } = 9600; + + // Estratégia padrão: + // 1) se houver PortaComCamera diferente, usa porta separada; + // 2) se rover e câmera estiverem no mesmo baud, usa a mesma porta sem trocar baud; + // 3) se o baud for diferente na mesma porta, não troca baud por padrão, para não corromper RX. + public static EstrategiaCameraSerial EstrategiaCamera { get; set; } = EstrategiaCameraSerial.Auto; + + // Só habilite para teste de bancada. Em campo, prefira PortaSeparada ou mesmo baud. + public static bool PermitirTrocaBaudCameraNaMesmaPorta { get; set; } = true; private static readonly object _FilaLock = new object(); - private static List FilaComandos = new List(); + private static readonly object _CameraLock = new object(); + private static readonly SemaphoreSlim _SerialLock = new SemaphoreSlim(1, 1); + private static readonly StringBuilder _RxFrame = new StringBuilder(); + + private static readonly List FilaComandos = new List(); private static System.Timers.Timer tmrLoopComandos; + private static volatile bool _IgnorarRxSerial = false; + private static DateTime _IgnorarRxAte = DateTime.MinValue; + private static int _RxEmAndamento = 0; - #region VARIAVEIS public static int TempoAtivo { get; set; } = 0; public static int TempoConectado { get; set; } = 0; - public static string PortaCom { get; set; } + public static int BaudRateFirmware { - get - { - return Variaveis.PerfilVigente.FirmwareF4 ? 38400 : 4800; - } + get { return Variaveis.PerfilVigente.FirmwareF4 ? 38400 : 4800; } } + public static string InicioRaque { get; } = "!"; public static string InicioComandos { get; } = "#"; public static string InicioSensores { get; } = "@"; @@ -41,13 +75,16 @@ namespace OrionTardPro.Services public static string InicioCamera { get; } = "*"; public static string FimProtocolo { get; } = "$"; public static string FimSensores { get; } = "'"; + public static int Pings { get; set; } = 0; public static ProtocoloModel ProtocoloEntrada { get; set; } = new ProtocoloModel(); public static ProtocoloModel ProtocoloEntrada2 { get; set; } = new ProtocoloModel(); public static DateTime UltimoProtocoloProcessado { get; set; } = DateTime.MinValue; + private static TipoProtocolo UltimoTipoProtocolo; private static TipoAtuador UltimoTipoAtuador; public static int EnviosUltimoProtocolo = 0; + public static System.Windows.Forms.Timer EnvioTimer = null; public static System.Windows.Forms.Timer SensoresTimer = null; @@ -56,6 +93,7 @@ namespace OrionTardPro.Services public static void Inicializar() { _PortaRS485 = new SerialPort(); + ConfigurarPortaSerialPadrao(_PortaRS485); _PortaRS485.DataReceived += _PortaRS485_DataReceived; EnvioTimer = new System.Windows.Forms.Timer() @@ -73,48 +111,105 @@ namespace OrionTardPro.Services tmrLoopComandos = new System.Timers.Timer() { Interval = 100, + AutoReset = false, }; tmrLoopComandos.Elapsed += TmrLoopComandos_Elapsed; tmrLoopComandos.Start(); } - + private static void ConfigurarPortaSerialPadrao(SerialPort porta) + { + if (porta == null) + return; + + porta.Parity = Parity.None; + porta.DataBits = 8; + porta.StopBits = StopBits.One; + porta.Handshake = Handshake.None; + porta.Encoding = Encoding.ASCII; + porta.ReadTimeout = 300; + porta.WriteTimeout = 300; + porta.NewLine = "\n"; + porta.ReceivedBytesThreshold = 1; + } + + private static void LogSerial(string msg) + { + Console.WriteLine("[SERIAL] " + msg); + } + + private static bool MesmaPorta(string a, string b) + { + if (string.IsNullOrWhiteSpace(a) || string.IsNullOrWhiteSpace(b)) + return false; + + return string.Equals(a.Trim(), b.Trim(), StringComparison.OrdinalIgnoreCase); + } + + private static bool TemPortaCameraSeparadaConfigurada() + { + return !string.IsNullOrWhiteSpace(PortaComCamera) && !MesmaPorta(PortaComCamera, PortaCom); + } + + private static EstrategiaCameraSerial ResolverEstrategiaCamera() + { + if (EstrategiaCamera != EstrategiaCameraSerial.Auto) + return EstrategiaCamera; + + if (TemPortaCameraSeparadaConfigurada()) + return EstrategiaCameraSerial.PortaSeparada; + + if (Variaveis.PerfilVigente.BaudRate == BaudRateCamera) + return EstrategiaCameraSerial.MesmaPortaMesmoBaud; + + if (PermitirTrocaBaudCameraNaMesmaPorta) + return EstrategiaCameraSerial.TrocaBaudMesmaPortaExperimental; + + return EstrategiaCameraSerial.Desabilitada; + } private static void SensoresTimer_Tick(object sender, EventArgs e) { ((System.Windows.Forms.Timer)sender).Stop(); - if (Conectado) + try { - int delay = 0; - if (Variaveis.PerfilVigente.RequisitarDados) + if (Conectado) { - Variaveis.frmPrincipal.lblDebugcontrole.Text = "Req sensores "; - EnviaProtocolo(TipoProtocolo.Carro, TipoAtuador.Sen); - delay = 500; + int delay = 0; + if (Variaveis.PerfilVigente.RequisitarDados) + { + Variaveis.frmPrincipal.lblDebugcontrole.Text = "Req sensores "; + EnviaProtocolo(TipoProtocolo.Carro, TipoAtuador.Sen); + delay = 500; + } + + Task.Run(async () => + { + await Task.Delay(delay); + + bool protocoloNovo = + !string.IsNullOrEmpty(ProtocoloEntrada.Dados) && + ProtocoloEntrada.Sensores && + ProtocoloEntrada.Completo; + + Variaveis.Sensoriamento.AtualizaSaidasSensores(false, protocoloNovo); + }); } - - Task.Run(async () => - { - await Task.Delay(delay); - - //if (!string.IsNullOrEmpty(ProtocoloEntrada.Dados) && ProtocoloEntrada.Sensores && ProtocoloEntrada.Completo) - bool protocoloNovo = !string.IsNullOrEmpty(ProtocoloEntrada.Dados) && ProtocoloEntrada.Sensores && ProtocoloEntrada.Completo; - Variaveis.Sensoriamento.AtualizaSaidasSensores(false, protocoloNovo); - }); } - - ((System.Windows.Forms.Timer)sender).Start(); + finally + { + ((System.Windows.Forms.Timer)sender).Start(); + } } - private static async Task EnviarDadosConfiguracao(bool Conectar) + private static async Task EnviarDadosConfiguracao(bool conectar) { - string ProtocoloConfiguracao = InicioConfig + - //Convert.ToInt32((Firmware) ? 0 : 1) + ";" + // Variaveis.frmConexao.chbProtocolocompleto.Checked - FuncoesGlobais.CorrigeProtocoloEstado((Conectar) ? Estado.Ligado : Estado.Desligado) + ";" + - (Variaveis.PerfilVigente.NumeroPingsMaximo).ToString("00") + ";" + - (Variaveis.PerfilVigente.TempoRecepcaoSensores).ToString("0000") + ";" + - (Variaveis.PerfilVigente.BaudRate).ToString("00000000") + ";" + + string protocoloConfiguracao = InicioConfig + + FuncoesGlobais.CorrigeProtocoloEstado(conectar ? Estado.Ligado : Estado.Desligado) + ";" + + Variaveis.PerfilVigente.NumeroPingsMaximo.ToString("00") + ";" + + Variaveis.PerfilVigente.TempoRecepcaoSensores.ToString("0000") + ";" + + Variaveis.PerfilVigente.BaudRate.ToString("00000000") + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.ZerarTempopercorrido) + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Sensor_Ativado_GAS) + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Sensor_Ativado_UMI) + ";" + @@ -130,37 +225,36 @@ namespace OrionTardPro.Services FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Sensor_Ativado_COR) + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Atuador_Ativado_Transmissor) + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Sensor_Ativado_Watchdog) + ";" + - ((Variaveis.PerfilVigente.TempoEntrePings)).ToString("00") + ";" + + Variaveis.PerfilVigente.TempoEntrePings.ToString("00") + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Sensor_Ativado_TMP) + ";" + - (Variaveis.PerfilVigente.ResolucaoLeitura).ToString("00") + ";" + + Variaveis.PerfilVigente.ResolucaoLeitura.ToString("00") + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Atuador_Ativado_BRC) + ";" + (Variaveis.PerfilVigente.ControleIndividualCamera ? "1" : "0") + ";" + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.PerfilVigente.Atuador_Ativado_MEP) + ";" + FimProtocolo; - /*AdicionarMensagemFila(new ProtocoloMensagemModel() - { - Momento = DateTime.Now, - Dados = ProtocoloConfiguracao, - });*/ - - _PortaRS485.BaudRate = Conectar ? BaudRateFirmware : Variaveis.PerfilVigente.BaudRate; - _PortaRS485.Write(ProtocoloConfiguracao); - Console.WriteLine(ProtocoloConfiguracao); + await EnviarDadosSerialDiretoRover(protocoloConfiguracao, conectar ? BaudRateFirmware : Variaveis.PerfilVigente.BaudRate, true); + Console.WriteLine(protocoloConfiguracao); await Task.Delay(1000); - Variaveis.Sensoriamento.LimparOffsetSensores(); } public static async Task ConectaPortaSerial() { Conectado = false; + + if (_PortaRS485 == null) + Inicializar(); + if (!_PortaRS485.IsOpen) { _PortaRS485.BaudRate = Variaveis.PerfilVigente.BaudRate; _PortaRS485.PortName = PortaCom; + + ConfigurarPortaSerialPadrao(_PortaRS485); _PortaRS485.Open(); + if (_PortaRS485.IsOpen) { Variaveis.frmPrincipal.imgLampGasVerd.Image = OrionTardPro.Properties.Resources.led_verde_on; @@ -169,15 +263,12 @@ namespace OrionTardPro.Services Variaveis.frmPrincipal.btnDesconectar.Enabled = true; Variaveis.frmPrincipal.btnCalibragem.Enabled = true; - //Variaveis.Com_Embreagem = TipoEmbreagem.Acoplado; - //VerificaEstadoEmbreagem(false); - await EnviarDadosConfiguracao(true); if (Variaveis.PerfilVigente.EnderecoReleGeral > 0x00) - { Variaveis.Sensoriamento.ReleGeralConectado = await ConectaReleGeral(); - } + + await ConectarCameraSeNecessario(); Conectado = true; @@ -191,10 +282,61 @@ namespace OrionTardPro.Services MessageBox.Show("Erro ao conectar-se ao carro", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); } } + return Conectado; } - public static async Task Desconectar(bool Proposital = true) + private static async Task ConectarCameraSeNecessario() + { + EstrategiaCameraSerial estrategia = ResolverEstrategiaCamera(); + + if (estrategia != EstrategiaCameraSerial.PortaSeparada) + { + CameraConectada = false; + return; + } + + if (!TemPortaCameraSeparadaConfigurada()) + { + CameraConectada = false; + LogSerial("PortaSeparada selecionada, mas PortaComCamera não foi configurada ou é igual à PortaCom do rover."); + return; + } + + await Task.Run(() => + { + lock (_CameraLock) + { + try + { + if (_PortaCamera == null) + { + _PortaCamera = new SerialPort(); + ConfigurarPortaSerialPadrao(_PortaCamera); + } + + if (_PortaCamera.IsOpen) + return; + + _PortaCamera.PortName = PortaComCamera; + _PortaCamera.BaudRate = BaudRateCamera; + _PortaCamera.Open(); + CameraConectada = _PortaCamera.IsOpen; + + LogSerial(CameraConectada + ? $"Câmera conectada em {PortaComCamera} @ {BaudRateCamera}." + : "Câmera não conectada."); + } + catch (Exception ex) + { + CameraConectada = false; + LogSerial("Erro ao abrir porta da câmera: " + ex.Message); + } + } + }); + } + + public static async Task Desconectar(bool proposital = true) { if (false && MessageBox.Show("Deseja zerar o odômetro de referência do robô?", "Referência", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) Variaveis.ZerarTempopercorrido = Estado.Reset; @@ -207,7 +349,9 @@ namespace OrionTardPro.Services if (Variaveis.frmControlecarro.Visible) Variaveis.frmPrincipal.imgAnalogicocamera_Click(sender, e); - if (!await DesconectaPortaSerial(Proposital)) + await DesconectarCamera(); + + if (!await DesconectaPortaSerial(proposital)) { SensoresTimer.Enabled = false; GeneralJoystick.joystickTimer.Enabled = false; @@ -215,28 +359,45 @@ namespace OrionTardPro.Services Variaveis.frmPrincipal.lblCarroconexao.Text = "Carro: Desconectado"; Variaveis.ZerarTempopercorrido = Estado.Desligado; Conectado = false; - //MessageBox.Show("Desconectado com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); Variaveis.Sensoriamento.AtualizaSaidasSensores(true, false); } } - private static async Task DesconectaPortaSerial(bool Proposital = true) + private static async Task DesconectarCamera() { - bool Conectado = true; + await Task.Run(() => + { + lock (_CameraLock) + { + try + { + if (_PortaCamera != null && _PortaCamera.IsOpen) + _PortaCamera.Close(); + } + catch { } + + CameraConectada = false; + } + }); + } + + private static async Task DesconectaPortaSerial(bool proposital = true) + { + bool conectado = true; + if (_PortaRS485.IsOpen) { - if (Proposital) + if (proposital) await EnviarDadosConfiguracao(false); - //Variaveis.Com_Embreagem = TipoEmbreagem.Desacoplado; - //VerificaEstadoEmbreagem(false); - _PortaRS485.Close(); } + Variaveis.frmPrincipal.imgComandoembreagem.Image = OrionTardPro.Properties.Resources.switch_0; + if (!_PortaRS485.IsOpen) { - Conectado = false; + conectado = false; Variaveis.frmPrincipal.btnConectaraocarro.Enabled = true; Variaveis.frmPrincipal.btnDesconectar.Enabled = false; Variaveis.frmPrincipal.btnCalibragem.Enabled = false; @@ -244,31 +405,29 @@ namespace OrionTardPro.Services Variaveis.frmPrincipal.imgLampGasVerm.Image = OrionTardPro.Properties.Resources.led_vermelho_off; lock (_FilaLock) - { FilaComandos.ForEach(x => x.Enviado = true); - } } - return Conectado; + return conectado; } - public static void EnvioTimer_Tick(object sender, EventArgs e) { - bool EnviaPing = true; + bool enviaPing = true; + if (EnviosUltimoProtocolo > 0 && EnviosUltimoProtocolo < Variaveis.PerfilVigente.QuantidadeEnvios) { EnviaProtocolo(UltimoTipoProtocolo, UltimoTipoAtuador); return; } - else - { - if (EnviosUltimoProtocolo > 0) - EnviaPing = false; - EnviosUltimoProtocolo = 0; - EnvioTimer.Interval = Variaveis.PerfilVigente.TempoEntrePings * 1000; - } - if (EnviaPing) + + if (EnviosUltimoProtocolo > 0) + enviaPing = false; + + EnviosUltimoProtocolo = 0; + EnvioTimer.Interval = Variaveis.PerfilVigente.TempoEntrePings * 1000; + + if (enviaPing) { Variaveis.frmPrincipal.lblDebugcontrole.Text = "Ping de conexão "; EnviaProtocolo(TipoProtocolo.Carro, TipoAtuador.Png); @@ -289,156 +448,413 @@ namespace OrionTardPro.Services ProtocoloEntrada2.Momento = ProtocoloEntrada.Momento; ProtocoloEntrada2.Dados = ProtocoloEntrada.Dados; Pings = 0; - Variaveis.frmPrincipal.lblCarroconexao.Text = "Carro: Conectado"; + Variaveis.frmPrincipal.lblCarroconexao.Text = $"Carro: Conectado ({Variaveis._Model} | NS {Variaveis._RobotNS} | FV {Variaveis._FirmwareVersion})"; + } + } + + #region RX ROBUSTO + + private static bool EhFrameAsciiValido(string frame) + { + if (string.IsNullOrWhiteSpace(frame)) return false; + if (!frame.StartsWith("@")) return false; + if (!frame.EndsWith("$") && !frame.EndsWith("'")) return false; + + foreach (char c in frame) + { + bool ok = char.IsDigit(c) || c == '@' || c == ';' || c == '.' || c == ',' || c == '-' || c == '$' || c == '\''; + if (!ok) return false; + } + + return true; + } + + private static bool TryInt(string valor, out int resultado) + { + resultado = 0; + if (string.IsNullOrWhiteSpace(valor)) return false; + return int.TryParse(valor.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out resultado); + } + + private static bool TryDouble(string valor, out double resultado) + { + resultado = 0; + if (string.IsNullOrWhiteSpace(valor)) return false; + valor = valor.Trim().Replace(',', '.'); + return double.TryParse(valor, NumberStyles.Float, CultureInfo.InvariantCulture, out resultado); + } + + private static bool TryBool01(string valor, out bool resultado) + { + resultado = false; + if (valor == "1") { resultado = true; return true; } + if (valor == "0") { resultado = false; return true; } + return false; + } + + private static void LimparRxSeguro(string motivo = "") + { + try + { + _RxFrame.Clear(); + if (_PortaRS485?.IsOpen == true) + _PortaRS485.DiscardInBuffer(); + + if (!string.IsNullOrWhiteSpace(motivo)) + LogSerial("RX limpo: " + motivo); + } + catch { } + } + + private static string LerFrameSensorComTimeout(int timeoutMs) + { + DateTime fim = DateTime.Now.AddMilliseconds(timeoutMs); + + while (DateTime.Now < fim) + { + try + { + if (_PortaRS485 == null || !_PortaRS485.IsOpen) + { + _RxFrame.Clear(); + return ""; + } + + if (_PortaRS485.BytesToRead <= 0) + { + Thread.Sleep(1); + continue; + } + + int b = _PortaRS485.ReadByte(); + if (b < 0) continue; + + char c = (char)b; + + if (c == '@') + { + _RxFrame.Clear(); + _RxFrame.Append(c); + continue; + } + + if (_RxFrame.Length == 0) + continue; + + if (char.IsControl(c) && c != '\r' && c != '\n') + { + LogSerial("Frame abortado por byte de controle."); + _RxFrame.Clear(); + continue; + } + + _RxFrame.Append(c); + + if (_RxFrame.Length > 512) + { + LogSerial("Frame abortado por tamanho excessivo."); + _RxFrame.Clear(); + continue; + } + + if (c == '$' || c == '\'') + { + string frame = _RxFrame.ToString(); + _RxFrame.Clear(); + return frame; + } + } + catch (Exception ex) + { + _RxFrame.Clear(); + LogSerial("Erro lendo frame: " + ex.Message); + return ""; + } + } + + return ""; + } + + private static void MarcarUltimaRequisicaoRespondida() + { + lock (_FilaLock) + { + var req = FilaComandos + .Where(x => x.Enviado && !x.Respondido && x.AguardarResposta) + .OrderByDescending(x => x.EnviadoEm) + .FirstOrDefault(); + + if (req != null) + { + req.Respondido = true; + req.RespondidoEm = DateTime.Now; + } + } + } + + private static bool ProcessarFrameTodF4(string frame, string[] p) + { + if (p.Length < 25) + { + LogSerial($"Frame Tod F4 incompleto: campos={p.Length}; frame={frame}"); + return false; + } + + bool mpuIniciado, inaIniciado, shtIniciado, mepCarimbando, mepContato; + double aceX, aceY, aceZ, gyrX, gyrY, gyrZ, magX, magY, magZ, bmpTmp, bmpPrs, bmpAlt; + double inaCor, inaTen, inaTmp, inaEng, shtUmd, shtTmp; + int mq2Gas; + + if (!TryBool01(p[1], out mpuIniciado) || + !TryDouble(p[2], out aceX) || !TryDouble(p[3], out aceY) || !TryDouble(p[4], out aceZ) || + !TryDouble(p[5], out gyrX) || !TryDouble(p[6], out gyrY) || !TryDouble(p[7], out gyrZ) || + !TryDouble(p[8], out magX) || !TryDouble(p[9], out magY) || !TryDouble(p[10], out magZ) || + !TryDouble(p[11], out bmpTmp) || !TryDouble(p[12], out bmpPrs) || !TryDouble(p[13], out bmpAlt) || + !TryBool01(p[14], out inaIniciado) || + !TryDouble(p[15], out inaCor) || !TryDouble(p[16], out inaTen) || !TryDouble(p[17], out inaTmp) || !TryDouble(p[18], out inaEng) || + !TryBool01(p[19], out shtIniciado) || + !TryDouble(p[20], out shtUmd) || !TryDouble(p[21], out shtTmp) || + !TryInt(p[22], out mq2Gas) || + !TryBool01(p[23], out mepCarimbando) || !TryBool01(p[24], out mepContato)) + { + LogSerial("Frame Tod F4 contaminado: " + frame); + return false; + } + + Variaveis.Sensoriamento.MPU_Iniciado = mpuIniciado; + Variaveis.Sensoriamento.AceX = aceX; + Variaveis.Sensoriamento.AceY = aceY; + Variaveis.Sensoriamento.AceZ = aceZ; + Variaveis.Sensoriamento.GyrX = gyrX; + Variaveis.Sensoriamento.GyrY = gyrY; + Variaveis.Sensoriamento.GyrZ = gyrZ; + Variaveis.Sensoriamento.MagX = magX; + Variaveis.Sensoriamento.MagY = magY; + Variaveis.Sensoriamento.MagZ = magZ; + Variaveis.Sensoriamento.BmpTmp = bmpTmp; + Variaveis.Sensoriamento.BmpPrs = bmpPrs; + Variaveis.Sensoriamento.BmpAlt = bmpAlt; + Variaveis.Sensoriamento.INA_Iniciado = inaIniciado; + Variaveis.Sensoriamento.InaCor = inaCor; + Variaveis.Sensoriamento.InaTen = inaTen; + Variaveis.Sensoriamento.InaTmp = inaTmp; + Variaveis.Sensoriamento.InaEng = inaEng; + Variaveis.Sensoriamento.SHT_Iniciado = shtIniciado; + Variaveis.Sensoriamento.ShtUmd = shtUmd; + Variaveis.Sensoriamento.ShtTmp = shtTmp; + Variaveis.Sensoriamento.Mq2Gas = mq2Gas; + Variaveis.Sensoriamento.MepCarimbando = mepCarimbando; + Variaveis.Sensoriamento.MepContato = mepContato; + + return true; + } + + private static bool ProcessarFrameTodLegado(string frame, string[] p) + { + if (p.Length < 21) + { + LogSerial($"Frame Tod legado incompleto: campos={p.Length}; frame={frame}"); + return false; + } + + double aceX, aceY, aceZ, gyrX, gyrY, gyrZ, magX, magY, magZ, bmpTmp, bmpPrs, bmpAlt; + double acumuladorCorrente, shtUmd, shtTmp, leituraTensao; + int mq2Gas; + + if (!TryDouble(p[1], out aceX) || !TryDouble(p[2], out aceY) || !TryDouble(p[3], out aceZ) || + !TryDouble(p[4], out gyrX) || !TryDouble(p[5], out gyrY) || !TryDouble(p[6], out gyrZ) || + !TryDouble(p[7], out magX) || !TryDouble(p[8], out magY) || !TryDouble(p[9], out magZ) || + !TryDouble(p[10], out bmpTmp) || !TryDouble(p[11], out bmpPrs) || !TryDouble(p[12], out bmpAlt) || + !TryDouble(p[13], out acumuladorCorrente) || + !TryDouble(p[14], out shtUmd) || !TryDouble(p[15], out shtTmp) || + !TryDouble(p[19], out leituraTensao) || !TryInt(p[20], out mq2Gas)) + { + LogSerial("Frame Tod legado contaminado: " + frame); + return false; + } + + acumuladorCorrente = Math.Sqrt(acumuladorCorrente) * Variaveis.PerfilVigente.COR_multiplicador; + acumuladorCorrente = (acumuladorCorrente * Variaveis.PerfilVigente.COR_coeficienteA) + Variaveis.PerfilVigente.COR_coeficienteB; + + double porcentagemBateriaTensao = (leituraTensao / Variaveis.PerfilVigente.ValorMaximoAnalogico) * 100.0; + double tensaoConvertida = (porcentagemBateriaTensao / 100.0) * Variaveis.PerfilVigente.TensaoMaximaBateria; + + Variaveis.Sensoriamento.AceX = aceX; + Variaveis.Sensoriamento.AceY = aceY; + Variaveis.Sensoriamento.AceZ = aceZ; + Variaveis.Sensoriamento.GyrX = gyrX; + Variaveis.Sensoriamento.GyrY = gyrY; + Variaveis.Sensoriamento.GyrZ = gyrZ; + Variaveis.Sensoriamento.MagX = magX; + Variaveis.Sensoriamento.MagY = magY; + Variaveis.Sensoriamento.MagZ = magZ; + Variaveis.Sensoriamento.BmpTmp = bmpTmp; + Variaveis.Sensoriamento.BmpPrs = bmpPrs; + Variaveis.Sensoriamento.BmpAlt = bmpAlt; + Variaveis.Sensoriamento.InaCor = acumuladorCorrente; + Variaveis.Sensoriamento.InaTen = tensaoConvertida; + Variaveis.Sensoriamento.ShtUmd = shtUmd; + Variaveis.Sensoriamento.ShtTmp = shtTmp; + Variaveis.Sensoriamento.Mq2Gas = mq2Gas; + + return true; + } + + private static bool ProcessarFrameMod(string frame, string[] p) + { + if (p.Length < 4) + { + LogSerial("Frame Mod incompleto: " + frame); + return false; + } + + int firmwareVersion, robotNs, modelInt; + if (!TryInt(p[1], out firmwareVersion) || !TryInt(p[2], out robotNs) || !TryInt(p[3], out modelInt)) + { + LogSerial("Frame Mod contaminado: " + frame); + return false; + } + + Variaveis._FirmwareVersion = firmwareVersion; + Variaveis._RobotNS = robotNs; + Variaveis._Model = (ModeloEquipamento)modelInt; + return true; + } + + private static bool ProcessarFrameOds(string frame, string[] p) + { + if (p.Length < 2) + { + LogSerial("Frame Ods incompleto: " + frame); + return false; + } + + int segundosOdometro; + if (!TryInt(p[1], out segundosOdometro)) + { + LogSerial("Frame Ods contaminado: " + frame); + return false; + } + + MessageBox.Show(FuncoesGlobais.SegundosParaTempo(segundosOdometro), "Odometro", MessageBoxButtons.OK, MessageBoxIcon.Information); + return true; + } + + private static bool ProcessarFramePns(string frame, string[] p) + { + if (p.Length < 5) + { + LogSerial("Frame Pns incompleto: " + frame); + return false; + } + + int total, conectado, motoresLigados, motoresLigadosParcial; + if (!TryInt(p[1], out total) || !TryInt(p[2], out conectado) || !TryInt(p[3], out motoresLigados) || !TryInt(p[4], out motoresLigadosParcial)) + { + LogSerial("Frame Pns contaminado: " + frame); + return false; + } + + Variaveis.Sensoriamento.SetValorVariavelOdometro(total, Variaveis.OdometroEnderecoTotal); + Variaveis.Sensoriamento.SetValorVariavelOdometro(conectado, Variaveis.OdometroEnderecoConectado); + Variaveis.Sensoriamento.SetValorVariavelOdometro(motoresLigados, Variaveis.OdometroEnderecoMotorLigado); + Variaveis.Sensoriamento.SetValorVariavelOdometro(motoresLigadosParcial, Variaveis.OdometroEnderecoMotorLigadoParcial); + return true; + } + + private static bool ProcessarFrameSensor(string frame) + { + if (!EhFrameAsciiValido(frame)) + { + LogSerial("Frame inválido/contaminado: " + frame); + return false; + } + + string payload = frame.Substring(1, frame.Length - 2); + string[] p = payload.Split(new[] { ';' }, StringSplitOptions.None); + + int tipoInt; + if (p.Length == 0 || !TryInt(p[0], out tipoInt)) + { + LogSerial("Frame sem tipo válido: " + frame); + return false; + } + + TipoSensor tipo = (TipoSensor)tipoInt; + + switch (tipo) + { + case TipoSensor.Tod: + return Variaveis.PerfilVigente.FirmwareF4 + ? ProcessarFrameTodF4(frame, p) + : ProcessarFrameTodLegado(frame, p); + + case TipoSensor.Mod: + return ProcessarFrameMod(frame, p); + + case TipoSensor.Ods: + return ProcessarFrameOds(frame, p); + + case TipoSensor.Pns: + return ProcessarFramePns(frame, p); + + default: + LogSerial("Tipo de sensor não tratado: " + frame); + return false; } } private static void _PortaRS485_DataReceived(object sender, SerialDataReceivedEventArgs e) { - var Req = FilaComandos.Where(x => x.Enviado && !x.Respondido).OrderByDescending(x => x.EnviadoEm).FirstOrDefault(); - if (Req != null) + if (_IgnorarRxSerial || DateTime.Now < _IgnorarRxAte) { - Req.Respondido = true; - Req.RespondidoEm = DateTime.Now; + LimparRxSeguro("RX ignorado durante janela crítica"); + return; } - string MensagemProtocolo = ""; + if (_PortaRS485 == null || !_PortaRS485.IsOpen) + return; + + if (_PortaRS485.BaudRate != Variaveis.PerfilVigente.BaudRate) + { + LimparRxSeguro("baud atual diferente do baud do firmware"); + return; + } + + if (Interlocked.Exchange(ref _RxEmAndamento, 1) == 1) + return; + try { - //ProtocoloEntrada.Dados = _PortaRS485.ReadLine(); - ProtocoloEntrada.Dados = ReadLineWithTimeout(1000); + string frame = LerFrameSensorComTimeout(350); + + if (string.IsNullOrWhiteSpace(frame)) + { + LogSerial("Frame descartado: vazio/incompleto"); + return; + } + + if (!ProcessarFrameSensor(frame)) + return; + + ProtocoloEntrada.Dados = frame; ProtocoloEntrada.Momento = DateTime.Now; + MarcarUltimaRequisicaoRespondida(); + Console.WriteLine(frame); } catch (Exception ex) { - MensagemProtocolo = "Falha ao requisitar protocolo serial! Erro: " + ex.Message; - Console.WriteLine(MensagemProtocolo); - return; + LogSerial("Erro inesperado no RX: " + ex.Message); } - - if (string.IsNullOrEmpty(ProtocoloEntrada.Dados)) + finally { - return; - } - - Console.WriteLine(ProtocoloEntrada.Dados); - string[] ProtocoloRecebido = ProtocoloEntrada.Dados.Split(Convert.ToChar(InicioSensores)); - string[] ProtocoloRecebidoRaque; - - try - { - // PROTOCOLO CARRO - //MensagemProtocolo = "#" + Variaveis.ProtocoloEntrada.Split('#')[1].Split('$')[0] + "$"; - MensagemProtocolo = ProtocoloEntrada.Dados; - string[] ParametrosSensor = ProtocoloRecebido[ProtocoloRecebido.Length - 1].Split(';'); //Variaveis.ProtocoloEntrada.Substring(1, Variaveis.ProtocoloEntrada.Length - 1).Split(';'); - TipoSensor Tipo = (TipoSensor)Convert.ToInt32(ParametrosSensor[0]); - switch (Tipo) - { - case TipoSensor.Tod: - string[] Parametros = ProtocoloRecebido[ProtocoloRecebido.Length - 1].Split(';'); - - if (Variaveis.PerfilVigente.FirmwareF4) - { - try { Variaveis.Sensoriamento.MPU_Iniciado = ParametrosSensor[1] == "1"; } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.AceX = Convert.ToDouble(ParametrosSensor[2].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.AceY = Convert.ToDouble(ParametrosSensor[3].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.AceZ = Convert.ToDouble(ParametrosSensor[4].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.GyrX = Convert.ToDouble(ParametrosSensor[5].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.GyrY = Convert.ToDouble(ParametrosSensor[6].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.GyrZ = Convert.ToDouble(ParametrosSensor[7].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.MagX = Convert.ToDouble(ParametrosSensor[8].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.MagY = Convert.ToDouble(ParametrosSensor[9].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.MagZ = Convert.ToDouble(ParametrosSensor[10].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.BmpTmp = Convert.ToDouble(ParametrosSensor[11].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.BmpPrs = Convert.ToDouble(ParametrosSensor[12].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.BmpAlt = Convert.ToDouble(ParametrosSensor[13].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.INA_Iniciado = ParametrosSensor[14] == "1"; } catch { Console.WriteLine("Erro ao receber valor do sensor INA228"); }; - try { Variaveis.Sensoriamento.InaCor = Convert.ToDouble(ParametrosSensor[15].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor INA228"); }; - try { Variaveis.Sensoriamento.InaTen = Convert.ToDouble(ParametrosSensor[16].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor INA228"); }; - try { Variaveis.Sensoriamento.InaTmp = Convert.ToDouble(ParametrosSensor[17].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor INA228"); }; - try { Variaveis.Sensoriamento.InaEng = Convert.ToDouble(ParametrosSensor[18].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor INA228"); }; - try { Variaveis.Sensoriamento.SHT_Iniciado = ParametrosSensor[19] == "1"; } catch { Console.WriteLine("Erro ao receber valor do sensor SHT030"); }; - try { Variaveis.Sensoriamento.ShtUmd = Convert.ToDouble(ParametrosSensor[20].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor SHT030"); }; - try { Variaveis.Sensoriamento.ShtTmp = Convert.ToDouble(ParametrosSensor[21].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor SHT030"); }; - try { Variaveis.Sensoriamento.Mq2Gas = Convert.ToInt32(ParametrosSensor[22].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MQ2"); }; - try { Variaveis.Sensoriamento.MepCarimbando = ParametrosSensor[23] == "1"; } catch { Console.WriteLine("Erro ao receber valor do medidor de espessura"); }; - try { Variaveis.Sensoriamento.MepContato = ParametrosSensor[24] == "1"; } catch { Console.WriteLine("Erro ao receber valor do medidor de espessura"); }; - } - else - { - try { Variaveis.Sensoriamento.AceX = Convert.ToDouble(ParametrosSensor[1].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.AceY = Convert.ToDouble(ParametrosSensor[2].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.AceZ = Convert.ToDouble(ParametrosSensor[3].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.GyrX = Convert.ToDouble(ParametrosSensor[4].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.GyrY = Convert.ToDouble(ParametrosSensor[5].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.GyrZ = Convert.ToDouble(ParametrosSensor[6].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.MagX = Convert.ToDouble(ParametrosSensor[7].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.MagY = Convert.ToDouble(ParametrosSensor[8].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.MagZ = Convert.ToDouble(ParametrosSensor[9].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.BmpTmp = Convert.ToDouble(ParametrosSensor[10].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.BmpPrs = Convert.ToDouble(ParametrosSensor[11].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try { Variaveis.Sensoriamento.BmpAlt = Convert.ToDouble(ParametrosSensor[12].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor MPU9250"); }; - try - { - double acumuladorCorrente = Convert.ToDouble(ParametrosSensor[13].Replace('.', ',')); - acumuladorCorrente = Math.Sqrt(acumuladorCorrente) * Variaveis.PerfilVigente.COR_multiplicador; //RMS da captura - acumuladorCorrente = (acumuladorCorrente * Variaveis.PerfilVigente.COR_coeficienteA) + (Variaveis.PerfilVigente.COR_coeficienteB); //Conversao em amperes - Variaveis.Sensoriamento.InaCor = acumuladorCorrente; - } catch { Console.WriteLine("Erro ao receber valor do sensor de corrente"); }; - try { Variaveis.Sensoriamento.ShtUmd = Convert.ToDouble(ParametrosSensor[14].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor DHT11"); }; - try { Variaveis.Sensoriamento.ShtTmp = Convert.ToDouble(ParametrosSensor[15].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor DHT11"); }; - //try { Variaveis.Sensoriamento.Sensor_DHT_IndiceCalor = Convert.ToDouble(ParametrosSensor[16].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor DHT11"); }; - //try { Variaveis.Sensoriamento.Sensor_DHT_Condensacao = Convert.ToDouble(ParametrosSensor[17].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do sensor DHT11"); }; - //try { Variaveis.Sensoriamento.Sensor_DHT_Status = ParametrosSensor[18]; } catch { Console.WriteLine("Erro ao receber valor do sensor DHT11"); }; - try - { - double leituraTensao = Convert.ToDouble(ParametrosSensor[19].Replace('.', ',')); - double PorcentagemBateriaTensao = (leituraTensao / Variaveis.PerfilVigente.ValorMaximoAnalogico) * 100.0; - Variaveis.Sensoriamento.InaTen = (PorcentagemBateriaTensao / 100.0) * Variaveis.PerfilVigente.TensaoMaximaBateria; - } catch { Console.WriteLine("Erro ao receber valor do divisor de tensao"); }; - try { Variaveis.Sensoriamento.Mq2Gas = Convert.ToInt32(ParametrosSensor[20].Replace('.', ',')); } catch { Console.WriteLine("Erro ao receber valor do MQ2"); }; - } - break; - case TipoSensor.Ods: - string Dados = ParametrosSensor[1]; - string Endereco = ParametrosSensor.Length > 3 ? ParametrosSensor[2] : Variaveis.OdometroEnderecoTotal.ToString(); - TimeSpan TempoOdometro = TimeSpan.FromSeconds(int.Parse(Dados)); - MessageBox.Show(FuncoesGlobais.SegundosParaTempo(int.Parse(Dados)), "Odometro", MessageBoxButtons.OK, MessageBoxIcon.Information); - break; - case TipoSensor.Pns: - if (ParametrosSensor.Length > 3) - { - string Total = ParametrosSensor[1]; - Variaveis.Sensoriamento.SetValorVariavelOdometro(int.Parse(Total), Variaveis.OdometroEnderecoTotal); - string Conectado = ParametrosSensor[2]; - Variaveis.Sensoriamento.SetValorVariavelOdometro(int.Parse(Conectado), Variaveis.OdometroEnderecoConectado); - string MotoresLigados = ParametrosSensor[3]; - Variaveis.Sensoriamento.SetValorVariavelOdometro(int.Parse(MotoresLigados), Variaveis.OdometroEnderecoMotorLigado); - string MotoresLigadosParcial = ParametrosSensor[4]; - Variaveis.Sensoriamento.SetValorVariavelOdometro(int.Parse(MotoresLigadosParcial), Variaveis.OdometroEnderecoMotorLigadoParcial); - } - break; - } - - } - catch (Exception ex) - { - if (ProtocoloEntrada.Dados != "") - { - try - { - MensagemProtocolo = "Erro no protocolo de entrada: Sensor " + ProtocoloEntrada.Dados.Substring(1, 1) + " ; Entrada: " + ProtocoloEntrada; - } - catch (Exception e2) - { - MensagemProtocolo = "Erro no protocolo de entrada"; - } - } - Console.WriteLine(MensagemProtocolo + " - " + ex.Message); + Interlocked.Exchange(ref _RxEmAndamento, 0); } } - public static void EnviaProtocolo(TipoProtocolo Tipo, TipoAtuador Atuador) + #endregion + + public static void EnviaProtocolo(TipoProtocolo tipo, TipoAtuador atuador) { Variaveis.frmPrincipal.Invoke((MethodInvoker)delegate { @@ -448,21 +864,22 @@ namespace OrionTardPro.Services if (!Conectado) return; - ProtocoloMensagemModel ProtocoloEnvio = new ProtocoloMensagemModel(); - - if (Tipo == TipoProtocolo.Carro) + ProtocoloMensagemModel protocoloEnvio = new ProtocoloMensagemModel(); + + if (tipo == TipoProtocolo.Carro) { - Variaveis.ProtocoloCarro = InicioComandos + FuncoesGlobais.CorrigeProtocoloTipoAtuador(Atuador) + ";"; - switch (Atuador) + Variaveis.ProtocoloCarro = InicioComandos + FuncoesGlobais.CorrigeProtocoloTipoAtuador(atuador) + ";"; + + switch (atuador) { case TipoAtuador.Mot: Variaveis.ProtocoloCarro += - FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.GetPotenciaAtual(1)) + "," + - FuncoesGlobais.CorrigeProtocoloSentido(Variaveis.Sentido_Driver1) + "," + - FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.RampaAtual) + ";" + - FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.GetPotenciaAtual(2)) + "," + - FuncoesGlobais.CorrigeProtocoloSentido(Variaveis.Sentido_Driver2) + "," + - FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.PrecisaoAtual); + FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.GetPotenciaAtual(1)) + "," + + FuncoesGlobais.CorrigeProtocoloSentido(Variaveis.Sentido_Driver1) + "," + + FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.RampaAtual) + ";" + + FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.GetPotenciaAtual(2)) + "," + + FuncoesGlobais.CorrigeProtocoloSentido(Variaveis.Sentido_Driver2) + "," + + FuncoesGlobais.CorrigeProtocoloNumerico(Variaveis.PerfilVigente.PrecisaoAtual); break; case TipoAtuador.Ilu: @@ -474,9 +891,8 @@ namespace OrionTardPro.Services break; case TipoAtuador.Emb: - Variaveis.ProtocoloCarro += - FuncoesGlobais.CorrigeProtocoloTipoEmbreagem(Variaveis.Com_Embreagem); - Variaveis.frmPrincipal.gpbControlemotores.Text = "Controle - Motores alternando para " + Variaveis.Com_Embreagem.ToString(); + Variaveis.ProtocoloCarro += FuncoesGlobais.CorrigeProtocoloTipoEmbreagem(Variaveis.Com_Embreagem); + Variaveis.frmPrincipal.gpbControlemotores.Text = "Controle - Motores alternando para " + Variaveis.Com_Embreagem; break; case TipoAtuador.Cam: @@ -484,21 +900,25 @@ namespace OrionTardPro.Services break; case TipoAtuador.Png: + GeneralJoystick.EnviarPingCamera(); Variaveis.ProtocoloCarro += DateTime.Now.Second.ToString(); - ProtocoloEnvio.AguardarResposta = true; - ProtocoloEnvio.Timeout = 1000; + protocoloEnvio.AguardarResposta = true; + protocoloEnvio.Timeout = 1000; break; case TipoAtuador.Odo: - Variaveis.ProtocoloCarro += FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.FuncaoOdometro) + ";" + Variaveis.Sensoriamento.GetEnderecoOdometro() + ";" + Variaveis.ValorOdometroEnviar.ToString("0000000000"); - ProtocoloEnvio.AguardarResposta = true; - ProtocoloEnvio.Timeout = 1000; + Variaveis.ProtocoloCarro += + FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.FuncaoOdometro) + ";" + + Variaveis.Sensoriamento.GetEnderecoOdometro() + ";" + + Variaveis.ValorOdometroEnviar.ToString("0000000000"); + protocoloEnvio.AguardarResposta = true; + protocoloEnvio.Timeout = 1000; break; case TipoAtuador.Sen: Variaveis.ProtocoloCarro += "req"; - ProtocoloEnvio.AguardarResposta = true; - ProtocoloEnvio.Timeout = 1000; + protocoloEnvio.AguardarResposta = true; + protocoloEnvio.Timeout = 1000; break; case TipoAtuador.Brc: @@ -506,422 +926,516 @@ namespace OrionTardPro.Services break; case TipoAtuador.Mep: - Variaveis.ProtocoloCarro += (Variaveis.Carimbar ? "1" : "0") + Variaveis.Angulo_MedidorEspessura.ToString("000"); + if (Variaveis.Carimbar) + { + Variaveis.PosicaoCarimbo = (Variaveis.PosicaoCarimbo + 1) % 3; + int deslocamento = (Variaveis.PosicaoCarimbo - 1) * 9; + int anguloCarimboH = Variaveis.PerfilVigente.AnguloCarimboHorizontal + deslocamento; + Variaveis.ProtocoloCarro += "1" + Variaveis.PerfilVigente.AnguloCarimboVertical.ToString("000") + anguloCarimboH.ToString("000"); + Variaveis.InicioCarimbo = DateTime.Now; + } + else + { + Variaveis.ProtocoloCarro += "0" + Variaveis.Angulo_MedidorEspessuraVertical.ToString("000") + "000"; + } break; } Variaveis.ProtocoloCarro += ";" + FimProtocolo; - if (Atuador != TipoAtuador.Png && Atuador != TipoAtuador.Sen && Atuador != TipoAtuador.Emb && Atuador != TipoAtuador.Odo && Variaveis.PerfilVigente.QuantidadeEnvios > 1) + if (atuador != TipoAtuador.Png && atuador != TipoAtuador.Sen && atuador != TipoAtuador.Emb && atuador != TipoAtuador.Odo && Variaveis.PerfilVigente.QuantidadeEnvios > 1) { - UltimoTipoProtocolo = Tipo; - UltimoTipoAtuador = Atuador; + UltimoTipoProtocolo = tipo; + UltimoTipoAtuador = atuador; EnviosUltimoProtocolo++; EnvioTimer.Interval = 100; } - ProtocoloEnvio.Dados = Variaveis.ProtocoloCarro; + protocoloEnvio.Dados = Variaveis.ProtocoloCarro; } - else if (Tipo == TipoProtocolo.Raque) + else if (tipo == TipoProtocolo.Raque) { - Variaveis.ProtocoloRaque = InicioRaque + FuncoesGlobais.CorrigeProtocoloTipoAtuador(Atuador) + ";"; - switch (Atuador) + Variaveis.ProtocoloRaque = InicioRaque + FuncoesGlobais.CorrigeProtocoloTipoAtuador(atuador) + ";"; + + switch (atuador) { case TipoAtuador.Buz: Variaveis.ProtocoloRaque += FuncoesGlobais.CorrigeProtocoloEstado(Variaveis.Com_BuzzerRaque); break; + case TipoAtuador.Enc: Variaveis.ProtocoloRaque += Variaveis.Sensoriamento.VelocidadeAtual.ToString("0.00"); break; + case TipoAtuador.Mot: - Sentido SentidoMotor = Sentido.Parado; - int Offset = 0; + Sentido sentidoMotor = Sentido.Parado; + int offset = 0; + switch (GeneralJoystick.UltimaDirecao) { case Direcao.Cima: - SentidoMotor = Variaveis.PerfilVigente.Raque_Desenrolar; - Offset = Variaveis.PerfilVigente.Offsett_Raque_Desenrolar; + sentidoMotor = Variaveis.PerfilVigente.Raque_Desenrolar; + offset = Variaveis.PerfilVigente.Offsett_Raque_Desenrolar; break; case Direcao.Baixo: - SentidoMotor = Variaveis.PerfilVigente.Raque_Enrolar; - Offset = Variaveis.PerfilVigente.Offsett_Raque_Enrolar; - break; - default: - SentidoMotor = Sentido.Parado; - Offset = 0; + sentidoMotor = Variaveis.PerfilVigente.Raque_Enrolar; + offset = Variaveis.PerfilVigente.Offsett_Raque_Enrolar; break; } + Variaveis.ProtocoloRaque += - Variaveis.Sensoriamento.VelocidadeAtual.ToString("0.00") + "," + - FuncoesGlobais.CorrigeProtocoloSentido(SentidoMotor) + "," + - FuncoesGlobais.CorrigeProtocoloNumerico(Offset); + Variaveis.Sensoriamento.VelocidadeAtual.ToString("0.00") + "," + + FuncoesGlobais.CorrigeProtocoloSentido(sentidoMotor) + "," + + FuncoesGlobais.CorrigeProtocoloNumerico(offset); break; } + Variaveis.ProtocoloRaque += ";" + FimProtocolo; - - ProtocoloEnvio.Dados = Variaveis.ProtocoloRaque; + protocoloEnvio.Dados = Variaveis.ProtocoloRaque; } - AdicionarMensagemFila(ProtocoloEnvio); - - /*try - { - _PortaRS485.Write(ProtocoloEnvio); - - Variaveis.frmPrincipal.Invoke((MethodInvoker)delegate - { - if (!Variaveis.frmPrincipal.lblDebugcontrole.Text.Contains("Enviado") && !Variaveis.frmPrincipal.lblDebugcontrole.Text.Contains("desabilitado")) - Variaveis.frmPrincipal.lblDebugcontrole.Text += " Enviado"; - - Variaveis.frmPrincipal.pgbEnvio.Value = 100; - }); - - // Se requisitou dados, aguarda um tempo antes de enviar qualquer outro comando, garantindo que nao haja conflitos de fluxo de dados - if (UltimoTipoAtuador == TipoAtuador.Sen) - { - await VerificaRespostaRequisicao(); - } - } - catch (Exception e) - { - Console.WriteLine("Erro ao enviar o protocolo: " + e.Message); - - Variaveis.frmPrincipal.Invoke((MethodInvoker)delegate - { - Variaveis.frmPrincipal.lblCarroconexao.Text = "Carro: Desconectado"; - }); - }*/ + AdicionarMensagemFila(protocoloEnvio); } - - - - public static void EnviarProtocoloCamera(int Comando) + public static void EnviarProtocoloCamera(int comando) { if (!Conectado) return; - string ProtocoloEnvio = InicioCamera + Comando + ";" + FimProtocolo; + string protocoloEnvio = InicioCamera + comando + ";" + FimProtocolo; AdicionarMensagemFila(new ProtocoloMensagemModel() { - Momento = DateTime.Now, - Dados = ProtocoloEnvio, + Momento = DateTime.Now, + Dados = protocoloEnvio, + AguardarResposta = false, + PermitirDuplicado = true, }); - - //_PortaRS485.Write(ProtocoloEnvio); - //Console.WriteLine(ProtocoloEnvio); } - public static void ControleCamera(byte Comando) + public static void ControleCamera(byte comando) { if (!Conectado) return; - /*AdicionarMensagemFila(new ProtocoloMensagemModel() - { - Momento = DateTime.Now, - Bytes = new byte[] { Comando }, - });*/ + EstrategiaCameraSerial estrategia = ResolverEstrategiaCamera(); + bool comandoParar = comando == 0x00; - _PortaRS485.BaudRate = 9600; - _PortaRS485.Write(new byte[] { Comando }, 0, 1); - Console.WriteLine("Câmera - Comando enviado: " + Comando); + switch (estrategia) + { + case EstrategiaCameraSerial.PortaSeparada: + EnviarComandoCameraPortaSeparada(comando); + return; + + case EstrategiaCameraSerial.MesmaPortaMesmoBaud: + AdicionarMensagemFila(new ProtocoloMensagemModel() + { + Momento = comandoParar ? DateTime.Now.AddMilliseconds(-500) : DateTime.Now, + Bytes = new[] { comando }, + BaudRate = Variaveis.PerfilVigente.BaudRate, + AguardarResposta = false, + PermitirDuplicado = true, + Prioritario = comandoParar, + }); + return; + + case EstrategiaCameraSerial.PonteFirmwareTexto: + EnviarProtocoloCamera(comando); + return; + + case EstrategiaCameraSerial.TrocaBaudMesmaPortaExperimental: + AdicionarMensagemFila(new ProtocoloMensagemModel() + { + Momento = comandoParar ? DateTime.Now.AddMilliseconds(-500) : DateTime.Now, + Bytes = new[] { comando }, + BaudRate = BaudRateCamera, + AguardarResposta = false, + PermitirDuplicado = true, + Prioritario = comandoParar, + EhCameraBaudTemporario = true, + }); + return; + + case EstrategiaCameraSerial.Desabilitada: + default: + LogSerial($"Comando câmera ignorado: rover @ {Variaveis.PerfilVigente.BaudRate}, câmera @ {BaudRateCamera}, mesma COM sem troca de baud permitida."); + return; + } + } + + private static void EnviarComandoCameraPortaSeparada(byte comando) + { + Task.Run(() => + { + lock (_CameraLock) + { + try + { + if (_PortaCamera == null || !_PortaCamera.IsOpen) + { + CameraConectada = false; + LogSerial("Comando câmera não enviado: porta da câmera não está aberta."); + return; + } + + _PortaCamera.Write(new[] { comando }, 0, 1); + CameraConectada = true; + } + catch (Exception ex) + { + CameraConectada = false; + LogSerial("Erro enviando comando para câmera: " + ex.Message); + } + } + }); } - public static async Task ConectaReleGeral() { - SerialPort _porta = new SerialPort() + SerialPort porta = new SerialPort() { PortName = _PortaRS485.PortName }; + ConfigurarPortaSerialPadrao(porta); - _PortaRS485.Close(); - - bool Sucesso = false; - - byte[] ComandoBaud = ModbusHelper.CreateBaudRateCommand(Variaveis.PerfilVigente.EnderecoReleGeral, _PortaRS485.BaudRate); - - for (int i = 0; i < ModbusHelper.ReleBaudRates.Count() - 1; i++) + await _SerialLock.WaitAsync(); + try { - var baud = ModbusHelper.ReleBaudRates.Keys.Skip(i).First(); - _porta.BaudRate = baud; + if (_PortaRS485.IsOpen) + _PortaRS485.Close(); - try + bool sucesso = false; + byte[] comandoBaud = ModbusHelper.CreateBaudRateCommand(Variaveis.PerfilVigente.EnderecoReleGeral, _PortaRS485.BaudRate); + + for (int i = 0; i < ModbusHelper.ReleBaudRates.Count() - 1; i++) { - _porta.Open(); + var baud = ModbusHelper.ReleBaudRates.Keys.Skip(i).First(); + porta.BaudRate = baud; - if (_porta.IsOpen) + try { - _porta.Write(ComandoBaud, 0, ComandoBaud.Length); - byte[] resposta = await LerDadosDaPortaSerialAsync(_porta, 8); - if (resposta.Length > 0) + porta.Open(); + + if (porta.IsOpen) { - Sucesso = true; - _porta.Close(); - break; + porta.Write(comandoBaud, 0, comandoBaud.Length); + byte[] resposta = await LerDadosDaPortaSerialAsync(porta, 8); + if (resposta.Length > 0) + { + sucesso = true; + porta.Close(); + break; + } + porta.Close(); } - _porta.Close(); + } + catch (Exception ex) + { + LogSerial($"Erro ao conectar porta {porta.PortName} com baud {porta.BaudRate}: {ex.Message}"); + try { porta.Close(); } catch { } } } - catch (Exception ex) - { - Console.WriteLine($"Erro ao conectar-se a porta {_porta.PortName} com o baud rate {_porta.BaudRate}: {ex.Message}"); - _porta.Close(); - } + + _PortaRS485.Open(); + return sucesso; + } + finally + { + _SerialLock.Release(); } - - _PortaRS485.Open(); - - return Sucesso; } - + public static void ControleReleGeral(Estado estado) { if (!Conectado) return; - byte[] Comando = ModbusHelper.CreateRelayCommand(Variaveis.PerfilVigente.EnderecoReleGeral, Variaveis.PerfilVigente.CanalReleGeral, estado); + byte[] comando = ModbusHelper.CreateRelayCommand(Variaveis.PerfilVigente.EnderecoReleGeral, Variaveis.PerfilVigente.CanalReleGeral, estado); AdicionarMensagemFila(new ProtocoloMensagemModel() { - Momento = DateTime.Now, - Bytes = Comando, + Momento = DateTime.Now, + Bytes = comando, + BaudRate = Variaveis.PerfilVigente.BaudRate, }); - - //_PortaRS485.Write(Comando, 0, 8); - //Console.WriteLine("Rele geral - Comando enviado: " + string.Join(" ", Comando)); } - public static async Task LerDadosDaPortaSerialAsync(SerialPort porta, int tamanhoEsperado, int Timeout = 500) + public static async Task LerDadosDaPortaSerialAsync(SerialPort porta, int tamanhoEsperado, int timeout = 500) { DateTime inicio = DateTime.Now; List buffer = new List(); - while (buffer.Count < tamanhoEsperado && inicio.AddMilliseconds(Timeout) > DateTime.Now) + + while (buffer.Count < tamanhoEsperado && inicio.AddMilliseconds(timeout) > DateTime.Now) { - await Task.Delay(50); - if (porta == null) - { + await Task.Delay(20); + + if (porta == null || !porta.IsOpen) break; - } + int bytesDisponiveis = porta.BytesToRead; - if (bytesDisponiveis > 0) - { - byte[] tempBuffer = new byte[bytesDisponiveis]; - int bytesLidos = porta.Read(tempBuffer, 0, bytesDisponiveis); - buffer.AddRange(tempBuffer.Take(bytesLidos)); - } + if (bytesDisponiveis <= 0) + continue; + + byte[] tempBuffer = new byte[bytesDisponiveis]; + int bytesLidos = porta.Read(tempBuffer, 0, bytesDisponiveis); + buffer.AddRange(tempBuffer.Take(bytesLidos)); } + return buffer.ToArray(); } - private static string ReadLineWithTimeout_old(int timeout) - { - CancellationTokenSource cts = new CancellationTokenSource(); - try - { - Task task = Task.Run(() => _PortaRS485.ReadLine(), cts.Token); - - if (task.Wait(timeout)) - { - return task.Result; - } - else - { - cts.Cancel(); - return ""; // ou string.Empty, dependendo de como você deseja lidar com isso - } - } - catch - { - return ""; - } - } - - private static string ReadLineWithTimeout(int timeoutMs) - { - DateTime startTime = DateTime.Now; - StringBuilder buffer = new StringBuilder(); - - while ((DateTime.Now - startTime).TotalMilliseconds < timeoutMs) - { - try - { - if (_PortaRS485.BytesToRead > 0) - { - int b = _PortaRS485.ReadByte(); - if (b == -1) continue; // nada lido - - char c = (char)b; - if (c == '\n') // fim da linha - break; - - buffer.Append(c); - } - else - { - Thread.Sleep(1); // evita uso excessivo da CPU - } - } - catch - { - break; - } - } - - return buffer.ToString().TrimEnd('\r'); // remove o \r final, se houver - } - - - - private static async void TmrLoopComandos_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { - tmrLoopComandos.Stop(); - - List Fila = new List(); - lock (_FilaLock) + try { - Fila = FilaComandos.Where(x => !x.Enviado).OrderBy(x => x.Momento).ToList(); - } + List fila; - foreach (var Protocolo in Fila) - { - bool Sucesso = EnviarDadosSerial(Protocolo); - if (Sucesso) + lock (_FilaLock) { - Variaveis.frmPrincipal.Invoke((MethodInvoker)delegate - { - if (!Variaveis.frmPrincipal.lblDebugcontrole.Text.Contains("Enviado") && !Variaveis.frmPrincipal.lblDebugcontrole.Text.Contains("desabilitado")) - Variaveis.frmPrincipal.lblDebugcontrole.Text += " Enviado"; + fila = FilaComandos + .Where(x => !x.Enviado) + .OrderByDescending(x => x.Prioritario) + .ThenBy(x => x.Momento) + .ToList(); + } - Variaveis.frmPrincipal.pgbEnvio.Value = 100; - }); + foreach (var protocolo in fila) + { + bool sucesso = await EnviarDadosSerial(protocolo); - // Se requisitou dados, aguarda um tempo antes de enviar qualquer outro comando, garantindo que nao haja conflitos de fluxo de dados - if (Protocolo.AguardarResposta) + if (sucesso) { - await VerificaRespostaRequisicao(); + if (protocolo.AguardarResposta) + await VerificaRespostaRequisicao(protocolo.Timeout); + else + { + protocolo.Respondido = true; + protocolo.RespondidoEm = DateTime.Now; + } } else { - Protocolo.Respondido = true; - Protocolo.RespondidoEm = DateTime.Now; + Variaveis.frmPrincipal.Invoke((MethodInvoker)delegate + { + Variaveis.frmPrincipal.lblCarroconexao.Text = "Carro: Desconectado"; + }); } } - else - { - Variaveis.frmPrincipal.Invoke((MethodInvoker)delegate - { - Variaveis.frmPrincipal.lblCarroconexao.Text = "Carro: Desconectado"; - }); - } - } - tmrLoopComandos.Start(); + LimparFilaAntiga(); + } + catch (Exception ex) + { + LogSerial("Erro no loop de comandos: " + ex.Message); + } + finally + { + if (tmrLoopComandos != null) + tmrLoopComandos.Start(); + } } - private static bool EnviarDadosSerial(ProtocoloMensagemModel Protocolo) + private static async Task EnviarDadosSerialDiretoRover(string dados, int baud, bool limparAntes) { - if (!Conectado || !_PortaRS485.IsOpen) + await _SerialLock.WaitAsync(); + try { + if (!await PrepararBaudRover(baud, limparAntes, false)) + return false; + + _PortaRS485.Write(dados); + await Task.Delay(10); + return true; + } + catch (Exception ex) + { + LogSerial("Erro ao enviar direto: " + ex.Message); return false; } + finally + { + _SerialLock.Release(); + } + } + + private static async Task PrepararBaudRover(int baudDesejado, bool limparAntes, bool ehBaudTemporario) + { + if (!Conectado && _PortaRS485?.IsOpen != true) + return false; + + if (_PortaRS485 == null || !_PortaRS485.IsOpen) + return false; + + if (ehBaudTemporario) + _IgnorarRxSerial = true; + + if (limparAntes) + LimparRxSeguro("preparando envio"); + + if (_PortaRS485.BaudRate != baudDesejado) + { + _PortaRS485.BaudRate = baudDesejado; + await Task.Delay(120); + } + + return true; + } + + private static async Task EnviarDadosSerial(ProtocoloMensagemModel protocolo) + { + if (!Conectado || _PortaRS485 == null || !_PortaRS485.IsOpen) + return false; + + await _SerialLock.WaitAsync(); + + int baudFirmware = Variaveis.PerfilVigente.BaudRate; + int baudDesejado = protocolo.BaudRate ?? baudFirmware; + bool baudTemporario = protocolo.EhCameraBaudTemporario || baudDesejado != baudFirmware; try { - if (!string.IsNullOrEmpty(Protocolo.Dados)) + if (baudTemporario && !PermitirTrocaBaudCameraNaMesmaPorta) { - Console.WriteLine(Protocolo.Dados); - _PortaRS485.BaudRate = Variaveis.PerfilVigente.BaudRate; - _PortaRS485.Write(Protocolo.Dados); - } - else if (Protocolo.Bytes != null) - { - Console.WriteLine(string.Join(" ", Protocolo.Bytes)); - _PortaRS485.Write(Protocolo.Bytes, 0, Protocolo.Bytes.Length); + LogSerial("Envio com troca de baud bloqueado por segurança."); + protocolo.Enviado = true; + protocolo.Respondido = true; + return true; } - Protocolo.Enviado = true; - Protocolo.EnviadoEm = DateTime.Now; + if (!await PrepararBaudRover(baudDesejado, protocolo.LimparInputAntes || baudTemporario, baudTemporario)) + return false; + + if (protocolo.LimparOutputAntes || baudTemporario) + { + try { _PortaRS485.DiscardOutBuffer(); } catch { } + } + + if (!string.IsNullOrEmpty(protocolo.Dados)) + _PortaRS485.Write(protocolo.Dados); + else if (protocolo.Bytes != null && protocolo.Bytes.Length > 0) + _PortaRS485.Write(protocolo.Bytes, 0, protocolo.Bytes.Length); + + await Task.Delay(protocolo.DelayAposEnvioMs); + + protocolo.Enviado = true; + protocolo.EnviadoEm = DateTime.Now; return true; } - catch (Exception e) + catch (Exception ex) { - Console.WriteLine("Erro ao enviar o protocolo: " + e.Message); - + LogSerial("Erro ao enviar protocolo: " + ex.Message); return false; } + finally + { + if (baudTemporario && _PortaRS485 != null && _PortaRS485.IsOpen) + { + try { _PortaRS485.DiscardInBuffer(); } catch { } + + if (_PortaRS485.BaudRate != baudFirmware) + { + _PortaRS485.BaudRate = baudFirmware; + await Task.Delay(150); + } + + try { _PortaRS485.DiscardInBuffer(); } catch { } + _IgnorarRxAte = DateTime.Now.AddMilliseconds(250); + _IgnorarRxSerial = false; + } + + _SerialLock.Release(); + } } - private static async Task VerificaRespostaRequisicao() + private static async Task VerificaRespostaRequisicao(int timeoutMs = 1000) { - List Fila = new List(); - DateTime Agora = DateTime.Now; - DateTime UltimoEnvio = DateTime.MinValue; - bool ReqRespondido = false; + DateTime limite = DateTime.Now.AddMilliseconds(timeoutMs); + bool reqRespondido = false; + DateTime ultimoEnvio = DateTime.MinValue; lock (_FilaLock) { - var P = FilaComandos.Where(x => x.Enviado && !x.Respondido).OrderByDescending(x => x.EnviadoEm).FirstOrDefault(); - if (P != null) - { - UltimoEnvio = P.EnviadoEm; - } + var p = FilaComandos.Where(x => x.Enviado && !x.Respondido && x.AguardarResposta).OrderByDescending(x => x.EnviadoEm).FirstOrDefault(); + if (p != null) + ultimoEnvio = p.EnviadoEm; } - while (!ReqRespondido && Agora.AddMilliseconds(1000) > DateTime.Now) + while (!reqRespondido && DateTime.Now < limite) { lock (_FilaLock) { - ReqRespondido = FilaComandos.Any(x => x.EnviadoEm >= UltimoEnvio && x.Respondido && x.RespondidoEm.AddMilliseconds(150) > DateTime.Now); + reqRespondido = FilaComandos.Any(x => + x.EnviadoEm >= ultimoEnvio && + x.Respondido && + x.RespondidoEm.AddMilliseconds(150) > DateTime.Now); } - await Task.Delay(100); + await Task.Delay(50); } - if (!ReqRespondido) - { - if (_PortaRS485.IsOpen) - { - _PortaRS485.DiscardInBuffer(); - } - } + if (!reqRespondido) + LimparRxSeguro("timeout aguardando resposta"); } - private static void AdicionarMensagemFila(ProtocoloMensagemModel Protocolo) + private static void AdicionarMensagemFila(ProtocoloMensagemModel protocolo) { + if (protocolo == null) + return; + + if (protocolo.Momento == DateTime.MinValue) + protocolo.Momento = DateTime.Now; + lock (_FilaLock) { - if (!FilaComandos.Any(x => !x.Enviado && x.Dados == Protocolo.Dados)) - { - FilaComandos.Add(Protocolo); - } + bool jaExiste = FilaComandos.Any(x => !x.Enviado && MensagensIguais(x, protocolo)); + + if (protocolo.PermitirDuplicado || !jaExiste) + FilaComandos.Add(protocolo); } - } + private static bool MensagensIguais(ProtocoloMensagemModel a, ProtocoloMensagemModel b) + { + if (a == null || b == null) + return false; + if (!string.IsNullOrEmpty(a.Dados) || !string.IsNullOrEmpty(b.Dados)) + return a.Dados == b.Dados; + + if (a.Bytes == null || b.Bytes == null) + return false; + + return a.Bytes.SequenceEqual(b.Bytes) && a.BaudRate == b.BaudRate; + } + + private static void LimparFilaAntiga() + { + DateTime limite = DateTime.Now.AddMinutes(-2); + + lock (_FilaLock) + { + FilaComandos.RemoveAll(x => x.Enviado && x.Momento < limite); + } + } } public class ProtocoloModel { public DateTime Momento { get; set; } = DateTime.MinValue; - public string Dados { get; set; } + public string Dados { get; set; } = ""; + public bool Sensores { - get - { - return Dados.Contains(SerialService.InicioSensores); - } + get { return !string.IsNullOrEmpty(Dados) && Dados.Contains(SerialService.InicioSensores); } } + public bool Completo { get { - return Dados.Contains(SerialService.FimProtocolo) || Dados.Contains(SerialService.FimSensores); + return !string.IsNullOrEmpty(Dados) && + (Dados.Contains(SerialService.FimProtocolo) || Dados.Contains(SerialService.FimSensores)); } } } @@ -931,12 +1445,23 @@ namespace OrionTardPro.Services public DateTime Momento { get; set; } public string Dados { get; set; } = ""; public byte[] Bytes { get; set; } = null; + + public int? BaudRate { get; set; } = null; + public bool LimparInputAntes { get; set; } = false; + public bool LimparOutputAntes { get; set; } = false; + public int DelayAposEnvioMs { get; set; } = 20; + public bool Enviado { get; set; } = false; - public DateTime EnviadoEm { get; set; } + public DateTime EnviadoEm { get; set; } + public bool Respondido { get; set; } = false; public DateTime RespondidoEm { get; set; } + public bool AguardarResposta { get; set; } = false; public int Timeout { get; set; } = 500; - } + public bool PermitirDuplicado { get; set; } = false; + public bool Prioritario { get; set; } = false; + public bool EhCameraBaudTemporario { get; set; } = false; + } } diff --git a/OrionTardPro/OrionTardPro/Variaveis.cs b/OrionTardPro/OrionTardPro/Variaveis.cs index 8704511..04607ee 100644 --- a/OrionTardPro/OrionTardPro/Variaveis.cs +++ b/OrionTardPro/OrionTardPro/Variaveis.cs @@ -106,6 +106,11 @@ namespace OrionTardPro public static FilterInfoCollection videoDevices; public static bool EditandoFoto { get; set; } = false; + // Equipamento conectado + public static ModeloEquipamento _Model { get; set; } = ModeloEquipamento.Indefinido; + public static int _FirmwareVersion { get; set; } = 0; + public static int _RobotNS { get; set; } = 0; + // Protocolo do carro public static string ProtocoloCarro { get; set; } public static Estado Com_Iluminacao { get; set; } = Estado.Desligado; @@ -119,7 +124,16 @@ namespace OrionTardPro public static Estado EstadoReleGeral { get; set; } = Estado.Desligado; public static int Angulo_Braco { get; set; } = 0; public static bool Carimbar { get; set; } = false; - public static int Angulo_MedidorEspessura { get; set; } = 0; + public static DateTime InicioCarimbo { get; set; } + public static bool Carimbando + { + get + { + return InicioCarimbo.AddMilliseconds(7000) > DateTime.Now; + } + } + public static int Angulo_MedidorEspessuraVertical { get; set; } = 0; + public static int PosicaoCarimbo { get; set; } = 1; // Protocolo do raque public static string ProtocoloRaque { get; set; } @@ -288,7 +302,11 @@ namespace OrionTardPro FirmwareF4 = frmParametros.rdbF4.Checked, RequisitarDados = frmConexao.chbRequisitarDados.Checked, EnderecoReleGeral = Convert.ToByte(frmParametros.nudEnderecoReleGeral.Value), - CanalReleGeral = Convert.ToInt32(frmParametros.nudCanalReleGeral.Value) + CanalReleGeral = Convert.ToInt32(frmParametros.nudCanalReleGeral.Value), + AnguloCarimboHorizontal = Convert.ToInt32(frmParametros.nudAnguloCarimboHorizontal.Value), + AnguloCarimboVertical = Convert.ToInt32(frmParametros.nudAnguloCarimboVertical.Value), + AnguloMedicaoIdeal = Convert.ToInt32(frmParametros.nudAnguloMedicaoIdeal.Value), + AnguloMedicaoMargemLimite = Convert.ToInt32(frmParametros.nudAnguloMedicaoMargemLimite.Value), }; string PerfilJson = JsonConvert.SerializeObject(PerfilVigente); File.WriteAllText(Diretorio, PerfilJson);