diff --git a/TelemetryIO/MainForm.Designer.cs b/TelemetryIO/MainForm.Designer.cs index 4a97fd3..f75ea9c 100644 --- a/TelemetryIO/MainForm.Designer.cs +++ b/TelemetryIO/MainForm.Designer.cs @@ -28,66 +28,29 @@ /// private void InitializeComponent() { - this.PortSelector = new System.Windows.Forms.ComboBox(); - this.label1 = new System.Windows.Forms.Label(); - this.Send_btn = new System.Windows.Forms.Button(); - this.Connect_btn = new System.Windows.Forms.Button(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.InfoLabel = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.SpeedSelector = new System.Windows.Forms.ComboBox(); - this.SendContinuous_btn = new System.Windows.Forms.Button(); - this.IMU_label = new System.Windows.Forms.Label(); - this.TestWrite_btn = new System.Windows.Forms.Button(); this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabPage1 = new System.Windows.Forms.TabPage(); this.tabPage2 = new System.Windows.Forms.TabPage(); - this.ratePID_control = new TelemetryIO.RatePID(); this.monitorVars1 = new TelemetryIO.MonitorVars(); this.name_label = new System.Windows.Forms.Label(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.Connect_btn = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.SpeedSelector = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.PortSelector = new System.Windows.Forms.ComboBox(); + this.label3 = new System.Windows.Forms.Label(); + this.ratePID_control = new TelemetryIO.RatePID(); this.tabControl1.SuspendLayout(); this.tabPage1.SuspendLayout(); this.tabPage2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.groupBox1.SuspendLayout(); this.SuspendLayout(); // - // PortSelector - // - this.PortSelector.FormattingEnabled = true; - this.PortSelector.Location = new System.Drawing.Point(63, 12); - this.PortSelector.Name = "PortSelector"; - this.PortSelector.Size = new System.Drawing.Size(121, 21); - this.PortSelector.TabIndex = 0; - this.PortSelector.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PortSelector_RefreshItems); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.label1.Location = new System.Drawing.Point(16, 14); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(41, 17); - this.label1.TabIndex = 1; - this.label1.Text = "Порт"; - // - // Send_btn - // - this.Send_btn.Location = new System.Drawing.Point(118, 57); - this.Send_btn.Name = "Send_btn"; - this.Send_btn.Size = new System.Drawing.Size(66, 21); - this.Send_btn.TabIndex = 2; - this.Send_btn.Text = "Send"; - this.Send_btn.UseVisualStyleBackColor = true; - this.Send_btn.Click += new System.EventHandler(this.Send_btn_Click); - // - // Connect_btn - // - this.Connect_btn.Location = new System.Drawing.Point(19, 57); - this.Connect_btn.Name = "Connect_btn"; - this.Connect_btn.Size = new System.Drawing.Size(79, 21); - this.Connect_btn.TabIndex = 3; - this.Connect_btn.Text = "Подключить"; - this.Connect_btn.UseVisualStyleBackColor = true; - this.Connect_btn.Click += new System.EventHandler(this.Connect_btn_Click); - // // InfoLabel // this.InfoLabel.Location = new System.Drawing.Point(12, 793); @@ -96,52 +59,6 @@ this.InfoLabel.TabIndex = 4; this.InfoLabel.Text = "Ok"; // - // label2 - // - this.label2.AutoSize = true; - this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.label2.Location = new System.Drawing.Point(208, 14); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(69, 17); - this.label2.TabIndex = 6; - this.label2.Text = "Скорость"; - // - // SpeedSelector - // - this.SpeedSelector.FormattingEnabled = true; - this.SpeedSelector.Location = new System.Drawing.Point(283, 12); - this.SpeedSelector.Name = "SpeedSelector"; - this.SpeedSelector.Size = new System.Drawing.Size(121, 21); - this.SpeedSelector.TabIndex = 5; - // - // SendContinuous_btn - // - this.SendContinuous_btn.Location = new System.Drawing.Point(190, 57); - this.SendContinuous_btn.Name = "SendContinuous_btn"; - this.SendContinuous_btn.Size = new System.Drawing.Size(109, 21); - this.SendContinuous_btn.TabIndex = 7; - this.SendContinuous_btn.Text = "Send_Continuous"; - this.SendContinuous_btn.UseVisualStyleBackColor = true; - this.SendContinuous_btn.Click += new System.EventHandler(this.SendContinuous_btn_Click); - // - // IMU_label - // - this.IMU_label.Location = new System.Drawing.Point(496, 16); - this.IMU_label.Name = "IMU_label"; - this.IMU_label.Size = new System.Drawing.Size(208, 19); - this.IMU_label.TabIndex = 8; - this.IMU_label.Text = "label3"; - // - // TestWrite_btn - // - this.TestWrite_btn.Location = new System.Drawing.Point(318, 56); - this.TestWrite_btn.Name = "TestWrite_btn"; - this.TestWrite_btn.Size = new System.Drawing.Size(75, 23); - this.TestWrite_btn.TabIndex = 9; - this.TestWrite_btn.Text = "TestWrite"; - this.TestWrite_btn.UseVisualStyleBackColor = true; - this.TestWrite_btn.Click += new System.EventHandler(this.TestWrite_btn_Click); - // // tabControl1 // this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Bottom; @@ -177,16 +94,6 @@ this.tabPage2.Text = "Monitor"; this.tabPage2.UseVisualStyleBackColor = true; // - // ratePID_control - // - this.ratePID_control.BackColor = System.Drawing.Color.AntiqueWhite; - this.ratePID_control.bottom_label = null; - this.ratePID_control.Location = new System.Drawing.Point(6, 6); - this.ratePID_control.Name = "ratePID_control"; - this.ratePID_control.serial = null; - this.ratePID_control.Size = new System.Drawing.Size(1240, 600); - this.ratePID_control.TabIndex = 11; - // // monitorVars1 // this.monitorVars1.Location = new System.Drawing.Point(6, 6); @@ -198,57 +105,144 @@ // name_label // this.name_label.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.name_label.Location = new System.Drawing.Point(1203, 10); + this.name_label.Location = new System.Drawing.Point(402, 11); this.name_label.Name = "name_label"; this.name_label.Size = new System.Drawing.Size(148, 23); this.name_label.TabIndex = 11; this.name_label.Text = "name"; // + // pictureBox1 + // + this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); + this.pictureBox1.Location = new System.Drawing.Point(1287, 12); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(64, 64); + this.pictureBox1.TabIndex = 12; + this.pictureBox1.TabStop = false; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.Connect_btn); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.SpeedSelector); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Controls.Add(this.PortSelector); + this.groupBox1.Location = new System.Drawing.Point(12, 4); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(232, 100); + this.groupBox1.TabIndex = 13; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Подключение"; + // + // Connect_btn + // + this.Connect_btn.Location = new System.Drawing.Point(79, 71); + this.Connect_btn.Name = "Connect_btn"; + this.Connect_btn.Size = new System.Drawing.Size(121, 21); + this.Connect_btn.TabIndex = 9; + this.Connect_btn.Text = "Подключить"; + this.Connect_btn.UseVisualStyleBackColor = true; + this.Connect_btn.Click += new System.EventHandler(this.Connect_btn_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.label2.Location = new System.Drawing.Point(4, 46); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(69, 17); + this.label2.TabIndex = 8; + this.label2.Text = "Скорость"; + // + // SpeedSelector + // + this.SpeedSelector.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.SpeedSelector.FormattingEnabled = true; + this.SpeedSelector.Location = new System.Drawing.Point(79, 44); + this.SpeedSelector.Name = "SpeedSelector"; + this.SpeedSelector.Size = new System.Drawing.Size(121, 21); + this.SpeedSelector.TabIndex = 7; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.label1.Location = new System.Drawing.Point(7, 19); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 17); + this.label1.TabIndex = 3; + this.label1.Text = "Порт"; + // + // PortSelector + // + this.PortSelector.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.PortSelector.FormattingEnabled = true; + this.PortSelector.Location = new System.Drawing.Point(79, 18); + this.PortSelector.Name = "PortSelector"; + this.PortSelector.Size = new System.Drawing.Size(121, 21); + this.PortSelector.TabIndex = 2; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.label3.Location = new System.Drawing.Point(266, 12); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(130, 20); + this.label3.TabIndex = 14; + this.label3.Text = "Имя устройства"; + // + // ratePID_control + // + this.ratePID_control.BackColor = System.Drawing.Color.AntiqueWhite; + this.ratePID_control.bottom_label = null; + this.ratePID_control.Location = new System.Drawing.Point(6, 6); + this.ratePID_control.Name = "ratePID_control"; + this.ratePID_control.serial = null; + this.ratePID_control.Size = new System.Drawing.Size(1299, 642); + this.ratePID_control.TabIndex = 11; + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1363, 820); + this.Controls.Add(this.label3); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.pictureBox1); this.Controls.Add(this.name_label); this.Controls.Add(this.tabControl1); - this.Controls.Add(this.TestWrite_btn); - this.Controls.Add(this.IMU_label); - this.Controls.Add(this.SendContinuous_btn); - this.Controls.Add(this.label2); - this.Controls.Add(this.SpeedSelector); this.Controls.Add(this.InfoLabel); - this.Controls.Add(this.Connect_btn); - this.Controls.Add(this.Send_btn); - this.Controls.Add(this.label1); - this.Controls.Add(this.PortSelector); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "MainForm"; - this.Text = "Form1"; + this.Text = "TelemetryIO"; this.tabControl1.ResumeLayout(false); this.tabPage1.ResumeLayout(false); this.tabPage2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion - - private System.Windows.Forms.ComboBox PortSelector; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Button Send_btn; - private System.Windows.Forms.Button Connect_btn; private System.Windows.Forms.Label InfoLabel; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.ComboBox SpeedSelector; - private System.Windows.Forms.Button SendContinuous_btn; - private System.Windows.Forms.Label IMU_label; - private System.Windows.Forms.Button TestWrite_btn; private System.Windows.Forms.TabControl tabControl1; private System.Windows.Forms.TabPage tabPage1; private System.Windows.Forms.TabPage tabPage2; - private RatePID ratePID_control; private MonitorVars monitorVars1; private System.Windows.Forms.Label name_label; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button Connect_btn; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox SpeedSelector; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox PortSelector; + private System.Windows.Forms.Label label3; + private RatePID ratePID_control; } } diff --git a/TelemetryIO/MainForm.cs b/TelemetryIO/MainForm.cs index b03cc66..905144a 100644 --- a/TelemetryIO/MainForm.cs +++ b/TelemetryIO/MainForm.cs @@ -23,7 +23,7 @@ namespace TelemetryIO private System.Timers.Timer packageReceivingTimeout = new System.Timers.Timer(5); private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); private System.Timers.Timer packageTransferTimer = new System.Timers.Timer(50); - + private FormClosingEventArgs formArgs; public MainForm() { InitializeComponent(); @@ -33,17 +33,20 @@ namespace TelemetryIO SpeedSelector.Items.AddRange(speedItems); SpeedSelector.SelectedIndex = 3; - Send_btn.Enabled = false; - packageTransferTimer.AutoReset = true; - timer.Interval = 100; + timer.Interval = 500; timer.Start(); timer.Tick += Timer_Tick; - ratePID_control.SubscribeOnEvent(serial); monitorVars1.subscribeOnMonitoringItemsReceived(serial); ratePID_control.bottom_label = InfoLabel; serial.HandShakeOccurred += Serial_HandShakeOccurred; + serial.AnswerReceived += Serial_AnswerReceived; + } + + private void Serial_AnswerReceived(object sender, SerialEventArgs e) + { + if(e.Answer == "EXITAPP") base.OnFormClosing(formArgs); } private void Serial_HandShakeOccurred(object sender, EventArgs e) @@ -62,23 +65,12 @@ namespace TelemetryIO private void Timer_Tick(object sender, EventArgs e) { if (name_label.InvokeRequired) { - name_label.BeginInvoke(new Action(() => IMU_label.Text = Telemetry.Instance.name)); // Асинхронный вызов + name_label.BeginInvoke(new Action(() => name_label.Text = Telemetry.Instance.name)); // Асинхронный вызов } else { name_label.Text = Telemetry.Instance.name; } - UpdateLabel(serial.view_str); - } - - private void serialSend() - { - - } - - private void Send_btn_Click(object sender, EventArgs e) - { - serial.sendTest(); } private void Connect_btn_Click(object sender, EventArgs e) @@ -115,16 +107,13 @@ namespace TelemetryIO return; } b.Text = "Отключить"; - Send_btn.Enabled = true; } } else { serial.Close(); b.Text = "Подключить"; - Send_btn.Enabled = false; } - } private void PortSelector_RefreshItems(object sender, MouseEventArgs e) @@ -134,50 +123,10 @@ namespace TelemetryIO PortSelector.SelectedIndex = 0; } - - private void SendContinuous_btn_Click(object sender, EventArgs e) - { - serial.sendTestCont(); - /*Button b = sender as Button; - if (sendContinuousFlag == true) - { - sendContinuousFlag = false; - packageTransferTimer.Stop(); - - b.Text = "Stop_Sending"; - } - else - { - sendContinuousFlag = true; - send_queue.Add(prepareTelegram()); - packageTransferTimer.Start(); - b.Text = "Send_Continuous"; - }*/ - } - protected override void OnFormClosing(FormClosingEventArgs e) { - serial.Exit(); - base.OnFormClosing(e); - } - - public void UpdateLabel(string newText) - { - - if (IMU_label.InvokeRequired) - { - IMU_label.BeginInvoke(new Action(() => IMU_label.Text = newText)); // Асинхронный вызов - } - else - { - IMU_label.Text = newText; - } - } - - private void TestWrite_btn_Click(object sender, EventArgs e) - { - float[] f = {0, 1, 2, 3, 4, 5, 6, 7, 8}; - serial.sendTestWrite(f); + formArgs = e; + if(serial.isOpen)serial.requestExit(); } } } diff --git a/TelemetryIO/MainForm.resx b/TelemetryIO/MainForm.resx index 1af7de1..34cf8a0 100644 --- a/TelemetryIO/MainForm.resx +++ b/TelemetryIO/MainForm.resx @@ -117,4 +117,350 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 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 + 0ppQFP0Pxd+g80pnxg0AAAAASUVORK5CYII= + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAMMOAADDDgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEANQEBAPkBA + QGhAQECDQEBAkEBAQI9AQECBQEBAakBAQEVAQEAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBACEBA + QGFAQEC8QEBA+kBAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQNlAQECPQEBAPEBA + QAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABAQEADQEBAaEBAQOhAQED/QEBA/0BAQPpAQEDLQEBAnUBAQIBAQEBwQEBAcEBAQH5AQECYQEBAvkBA + QPFAQED/QEBA/0BAQP9AQEDYQEBAZUBAQAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABAQEAbQEBAwUBAQP9AQED/QEBAzEBAQGJAQEARAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABAQEADQEBAOEBAQIhAQEDlQEBA/0BAQP9AQEDdQEBAUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAkQEBA4UBAQP9AQEDlQEBAVEBAQAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBABEBAQFhAQEDTQEBA/0BA + QP9AQEClQEBADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAVQEBA4EBAQP9AQEDBQEBAFQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQEBABEBAQG1AQEDzQEBA/0BAQNRAQEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABQEBAukBA + QP9AQEDGQEBACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAJEBAQNJAQED/QEBA4UBAQB8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQEBAXEBAQP9AQEDpQEBAGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAPQEBAxUBA + QP9AQEDWQEBADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAQEBAA0BAQN9AQED/QEBAXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAEBAQA5AQEDTQEBA/0BAQKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQFJAQED/QEBA2UBAQAIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAJkBAQPZAQED+QEBAPQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQECpQEBA/0BA + QG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQECBQEBA/0BA + QLcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABAQEAEQEBA8EBAQP9AQEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAADgAAABMAAAAUAAAAEgAAAA4AAAAJAAAABAAA + AAAAAAAAQEBAEkBAQPVAQED+QEBAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAA09PT/38yGv9/Mhr/fzIa/9PT0//T09P/09PT/9PT0/9/Mhr/fzIa/38y + Gv/T09P/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAoAAAANAAAADwAAAA8AAAALAAAABQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANPT0//T09P/09PT/9PT0//T09P/09PT/9PT + 0//T09P/09PT/9PT0//T09P/09PT/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADT09P/09PT/9PT + 0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAANPT0//T09P/09PT/9PT0//T09P/09PT/9PT0//T09P/09PT/9PT + 0//T09P/09PT/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADT09P/09PT/9PT0//T09P/09PT/9PT + 0//T09P/09PT/9PT0//T09P/09PT/9PT0/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////////////////////////4Af///////8AAH///////AAAH//////4D/AP//////A//gP/ + ////4P//gf/////B///g/////8P///B/////h///+H////+H///8P////4////4/////D//4Bh////8f + /+ABHgD//h//wAAYAD/+H/+AABAAH/4f/4HwAAAP/A//B/ABxg/4B/8HwAHHB/gD/wACA4cHwAD/AAID + h4fAAP8ABgcDh8AA/wgOBgGHwAD/Dh4AAIfAAP8PHgAAB8AA/wccAfAHwAD/gxgh/g/AAP+AACD8D8AA + /8AAcAAfwAD/4AH4AD/AAP/gAfwAf8AA/8AA+AB/wAD/gADwAD/AAP+CMGAwH8AA/w44QfwfwAD+DjwD + +A/AAP4cPAfgD8AA/hwcAAEPwAD+GA4AAY/AAP4ABgQDj8AA/gAABwcPwAD+A4AHjw/AAP4P8AOPD8AA + /wPwQ44P4AH/AABAyB/gAf+AAOAAH+AB/8AB8AA/4AH/8Af8AH/gAf////4B/+AB////////4AH///// + ///gAf///////+AB////////4AH///////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + \ No newline at end of file diff --git a/TelemetryIO/Models/Telemetry.cs b/TelemetryIO/Models/Telemetry.cs index b23744f..198c5ae 100644 --- a/TelemetryIO/Models/Telemetry.cs +++ b/TelemetryIO/Models/Telemetry.cs @@ -16,6 +16,7 @@ namespace TelemetryIO.Models public string name = ""; public float[] raw_imu = new float[6]; public float[] quaternion = new float[4]; + public float[] battery = new float[4]; public float[] motor_act = new float[4]; public float[] motor_sp = new float[4]; public float[] pid0 = new float[9]; @@ -24,26 +25,28 @@ namespace TelemetryIO.Models public float[] pid3 = new float[9]; private Telemetry() { - dictMonitor.Add("rawAx", new VarAddress(0, 0)); - dictMonitor.Add("rawAy", new VarAddress(0, 1)); - dictMonitor.Add("rawAz", new VarAddress(0, 2)); - dictMonitor.Add("rawGx", new VarAddress(0, 3)); - dictMonitor.Add("rawGy", new VarAddress(0, 4)); - dictMonitor.Add("rawGz", new VarAddress(0, 5)); + dictMonitor.Add("rawAx", new VarAddress(RAW_IMU_ADDRESS, 0)); + dictMonitor.Add("rawAy", new VarAddress(RAW_IMU_ADDRESS, 1)); + dictMonitor.Add("rawAz", new VarAddress(RAW_IMU_ADDRESS, 2)); + dictMonitor.Add("rawGx", new VarAddress(RAW_IMU_ADDRESS, 3)); + dictMonitor.Add("rawGy", new VarAddress(RAW_IMU_ADDRESS, 4)); + dictMonitor.Add("rawGz", new VarAddress(RAW_IMU_ADDRESS, 5)); - dictMonitor.Add("Qw", new VarAddress(1, 0)); - dictMonitor.Add("Qx", new VarAddress(1, 1)); - dictMonitor.Add("Qy", new VarAddress(1, 2)); - dictMonitor.Add("Qz", new VarAddress(1, 3)); + dictMonitor.Add("Qw", new VarAddress(Q_ADDRESS, 0)); + dictMonitor.Add("Qx", new VarAddress(Q_ADDRESS, 1)); + dictMonitor.Add("Qy", new VarAddress(Q_ADDRESS, 2)); + dictMonitor.Add("Qz", new VarAddress(Q_ADDRESS, 3)); - dictMonitor.Add("motor0_Act", new VarAddress(100, 0)); - dictMonitor.Add("motor1_Act", new VarAddress(100, 1)); - dictMonitor.Add("motor2_Act", new VarAddress(100, 2)); - dictMonitor.Add("motor3_Act", new VarAddress(100, 3)); - dictMonitor.Add("motor4_Act", new VarAddress(100, 4)); - dictMonitor.Add("motor5_Act", new VarAddress(100, 5)); - dictMonitor.Add("motor6_Act", new VarAddress(100, 6)); - dictMonitor.Add("motor7_Act", new VarAddress(100, 7)); + dictMonitor.Add("Battery[V]", new VarAddress(BAT_ADDRESS, 0)); + + dictMonitor.Add("motor0_Act", new VarAddress(MOTORS_ACT_ADDRESS, 0)); + dictMonitor.Add("motor1_Act", new VarAddress(MOTORS_ACT_ADDRESS, 1)); + dictMonitor.Add("motor2_Act", new VarAddress(MOTORS_ACT_ADDRESS, 2)); + dictMonitor.Add("motor3_Act", new VarAddress(MOTORS_ACT_ADDRESS, 3)); + dictMonitor.Add("motor4_Act", new VarAddress(MOTORS_ACT_ADDRESS, 4)); + dictMonitor.Add("motor5_Act", new VarAddress(MOTORS_ACT_ADDRESS, 5)); + dictMonitor.Add("motor6_Act", new VarAddress(MOTORS_ACT_ADDRESS, 6)); + dictMonitor.Add("motor7_Act", new VarAddress(MOTORS_ACT_ADDRESS, 7)); } public VarAddress getVarAdress(string name) @@ -81,35 +84,43 @@ namespace TelemetryIO.Models if (slot != 9999) Debug.WriteLine(slot); switch (slot) { - case 0://RAW IMU + case RAW_IMU_ADDRESS://RAW IMU set_float(raw_imu, data, offset, len); break; - case 1://quaternion + case Q_ADDRESS://quaternion set_float(quaternion, data, offset, len); break; - case 100://motors act + case BAT_ADDRESS://battery + set_float(battery, data, offset, len); + break; + + case MOTORS_ACT_ADDRESS://motors act set_float(motor_act, data, offset, len); break; - case 1000: + case MOTORS_SP_ADDRESS://motors act + set_float(motor_sp, data, offset, len); + break; + + case PID0_ADDRESS: set_float(pid0, data, offset, len); break; - case 1001: + case PID1_ADDRESS: set_float(pid1, data, offset, len); break; - case 1002: + case PID2_ADDRESS: set_float(pid2, data, offset, len); break; - case 1003: + case PID3_ADDRESS: set_float(pid3, data, offset, len); break; - case 9999: + case NAME_ADDRESS: set_name(data); break; } @@ -132,6 +143,20 @@ namespace TelemetryIO.Models name = Encoding.ASCII.GetString(data, 0, 16); } + public const int RAW_IMU_ADDRESS = 0; + public const int Q_ADDRESS = 1; + + public const int BAT_ADDRESS = 50; + + public const int MOTORS_ACT_ADDRESS = 100; + public const int MOTORS_SP_ADDRESS = 101; + + public const int PID0_ADDRESS = 1000; + public const int PID1_ADDRESS = 1001; + public const int PID2_ADDRESS = 1002; + public const int PID3_ADDRESS = 1003; + + public const int NAME_ADDRESS = 9999; } public class VarAddress diff --git a/TelemetryIO/MonitorVars.Designer.cs b/TelemetryIO/MonitorVars.Designer.cs index 1fdf936..59953fe 100644 --- a/TelemetryIO/MonitorVars.Designer.cs +++ b/TelemetryIO/MonitorVars.Designer.cs @@ -29,102 +29,127 @@ private void InitializeComponent() { this.MainFormPlot = new ScottPlot.WinForms.FormsPlot(); - this.mon_test_label = new System.Windows.Forms.Label(); this.add_btn = new System.Windows.Forms.Button(); this.del_btn = new System.Windows.Forms.Button(); - this.monNames_label = new System.Windows.Forms.Label(); this.monitorItems_cb = new System.Windows.Forms.ComboBox(); this.monitorItems_lb = new System.Windows.Forms.ListBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.AutoScale_check = new System.Windows.Forms.CheckBox(); + this.StartStop_btn = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // MainFormPlot // this.MainFormPlot.DisplayScale = 0F; - this.MainFormPlot.Location = new System.Drawing.Point(238, 58); + this.MainFormPlot.Location = new System.Drawing.Point(238, 0); this.MainFormPlot.Name = "MainFormPlot"; - this.MainFormPlot.Size = new System.Drawing.Size(923, 539); + this.MainFormPlot.Size = new System.Drawing.Size(951, 597); this.MainFormPlot.TabIndex = 0; // - // mon_test_label - // - this.mon_test_label.AutoSize = true; - this.mon_test_label.Location = new System.Drawing.Point(3, 11); - this.mon_test_label.Name = "mon_test_label"; - this.mon_test_label.Size = new System.Drawing.Size(78, 13); - this.mon_test_label.TabIndex = 2; - this.mon_test_label.Text = "mon_test_label"; - // // add_btn // - this.add_btn.Location = new System.Drawing.Point(20, 88); + this.add_btn.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.add_btn.Location = new System.Drawing.Point(130, 3); this.add_btn.Name = "add_btn"; - this.add_btn.Size = new System.Drawing.Size(75, 23); + this.add_btn.Size = new System.Drawing.Size(87, 26); this.add_btn.TabIndex = 3; - this.add_btn.Text = "add_btn"; + this.add_btn.Text = "Добавить"; this.add_btn.UseVisualStyleBackColor = true; this.add_btn.Click += new System.EventHandler(this.add_btn_Click); // // del_btn // - this.del_btn.Location = new System.Drawing.Point(20, 135); + this.del_btn.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.del_btn.Location = new System.Drawing.Point(67, 439); this.del_btn.Name = "del_btn"; this.del_btn.Size = new System.Drawing.Size(75, 23); this.del_btn.TabIndex = 4; - this.del_btn.Text = "del_btn"; + this.del_btn.Text = "Удалить"; this.del_btn.UseVisualStyleBackColor = true; this.del_btn.Click += new System.EventHandler(this.del_btn_Click); // - // monNames_label - // - this.monNames_label.AutoSize = true; - this.monNames_label.Location = new System.Drawing.Point(597, 11); - this.monNames_label.Name = "monNames_label"; - this.monNames_label.Size = new System.Drawing.Size(35, 13); - this.monNames_label.TabIndex = 5; - this.monNames_label.Text = "label1"; - // // monitorItems_cb // + this.monitorItems_cb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.monitorItems_cb.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); this.monitorItems_cb.FormattingEnabled = true; - this.monitorItems_cb.Location = new System.Drawing.Point(20, 58); + this.monitorItems_cb.Location = new System.Drawing.Point(3, 3); this.monitorItems_cb.Name = "monitorItems_cb"; - this.monitorItems_cb.Size = new System.Drawing.Size(121, 21); + this.monitorItems_cb.Size = new System.Drawing.Size(121, 24); this.monitorItems_cb.TabIndex = 6; // // monitorItems_lb // + this.monitorItems_lb.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); this.monitorItems_lb.FormattingEnabled = true; - this.monitorItems_lb.Location = new System.Drawing.Point(20, 180); + this.monitorItems_lb.ItemHeight = 16; + this.monitorItems_lb.Location = new System.Drawing.Point(3, 52); this.monitorItems_lb.Name = "monitorItems_lb"; - this.monitorItems_lb.Size = new System.Drawing.Size(121, 316); + this.monitorItems_lb.Size = new System.Drawing.Size(214, 372); this.monitorItems_lb.TabIndex = 8; // + // groupBox1 + // + this.groupBox1.Controls.Add(this.AutoScale_check); + this.groupBox1.Controls.Add(this.StartStop_btn); + this.groupBox1.Location = new System.Drawing.Point(3, 480); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(214, 100); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Управление трендом"; + // + // AutoScale_check + // + this.AutoScale_check.AutoSize = true; + this.AutoScale_check.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.AutoScale_check.Location = new System.Drawing.Point(45, 67); + this.AutoScale_check.Name = "AutoScale_check"; + this.AutoScale_check.Size = new System.Drawing.Size(120, 21); + this.AutoScale_check.TabIndex = 12; + this.AutoScale_check.Text = "Авто масштаб"; + this.AutoScale_check.UseVisualStyleBackColor = true; + this.AutoScale_check.CheckedChanged += new System.EventHandler(this.AutoScale_check_CheckedChanged); + // + // StartStop_btn + // + this.StartStop_btn.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.StartStop_btn.Location = new System.Drawing.Point(51, 24); + this.StartStop_btn.Name = "StartStop_btn"; + this.StartStop_btn.Size = new System.Drawing.Size(108, 31); + this.StartStop_btn.TabIndex = 11; + this.StartStop_btn.Text = "Старт"; + this.StartStop_btn.UseVisualStyleBackColor = true; + this.StartStop_btn.Click += new System.EventHandler(this.StartStop_btn_Click); + // // MonitorVars // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.groupBox1); this.Controls.Add(this.monitorItems_lb); this.Controls.Add(this.monitorItems_cb); - this.Controls.Add(this.monNames_label); this.Controls.Add(this.del_btn); this.Controls.Add(this.add_btn); - this.Controls.Add(this.mon_test_label); this.Controls.Add(this.MainFormPlot); this.Name = "MonitorVars"; this.Size = new System.Drawing.Size(1240, 600); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); } #endregion private ScottPlot.WinForms.FormsPlot MainFormPlot; - private System.Windows.Forms.Label mon_test_label; private System.Windows.Forms.Button add_btn; private System.Windows.Forms.Button del_btn; - private System.Windows.Forms.Label monNames_label; private System.Windows.Forms.ComboBox monitorItems_cb; private System.Windows.Forms.ListBox monitorItems_lb; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.CheckBox AutoScale_check; + private System.Windows.Forms.Button StartStop_btn; } } diff --git a/TelemetryIO/MonitorVars.cs b/TelemetryIO/MonitorVars.cs index e481c8e..ba59838 100644 --- a/TelemetryIO/MonitorVars.cs +++ b/TelemetryIO/MonitorVars.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using TelemetryIO.Models; @@ -20,12 +22,16 @@ namespace TelemetryIO private List monitorNames = new List(); private List signals = new List(); + private List monItems = new List(); + private List[] plotContent = new List[32]; - private Timer updateTimer = new Timer(); + private System.Windows.Forms.Timer updateTimer = new System.Windows.Forms.Timer(); private float[] monitoring = new float[32]; private int test_index = 0; private bool isSubscribed = false; + private bool isMonitoring = true; + private bool isAutoScale = true; private string processingName = ""; private int processingIndex = -1; @@ -35,14 +41,12 @@ namespace TelemetryIO initMonitoringBuffer(); updateTimer.Interval = 100; - - MainFormPlot.Plot.Axes.AutoScale(); + AutoScale_check.Checked = isAutoScale; monitorItems_cb.Items.AddRange(Telemetry.Instance.getKeys()); monitorItems_cb.SelectedIndex = 0; updateTimer.Tick += UpdateTimer_Tick; updateTimer.Start(); - //MainFormPlot. } public void subscribeOnMonitoringItemsReceived(SerialHandler s) @@ -58,7 +62,7 @@ namespace TelemetryIO { if(e.Answer == "ADD") { - monitorNames.Add(processingName); + MonitorItem item = new MonitorItem(processingName, processingIndex); processingIndex++; if (monitorItems_lb.InvokeRequired) { @@ -68,14 +72,21 @@ namespace TelemetryIO { monitorItems_lb.Items.Add(processingName); } - monitorList.Add(new double[1024]); - MainFormPlot.Plot.Add.Signal(monitorList[monitorList.Count - 1]); - + + if (StartStop_btn.InvokeRequired) + { + StartStop_btn.Invoke(new Action(() => StartStop_btn.Enabled = true)); + } + else + { + StartStop_btn.Enabled = true; + } + + monItems.Add(item); } else if(e.Answer == "REMOVE") { - monitorNames.RemoveAt(processingIndex); - monitorList.RemoveAt(processingIndex); + monItems.RemoveAt(processingIndex); if (monitorItems_lb.InvokeRequired) { monitorItems_lb.Invoke(new Action(() => monitorItems_lb.Items.RemoveAt(processingIndex))); @@ -88,55 +99,89 @@ namespace TelemetryIO if (processingIndex >= 0) processingIndex--; }else if(e.Answer == "REMOVEALL") { - monitorNames.Clear(); - monitorList.Clear(); + monItems.Clear(); + if (monitorItems_lb.InvokeRequired) + { + monitorItems_lb.Invoke(new Action(() => monitorItems_lb.Items.Clear())); + } + else + { + monitorItems_lb.Items.Clear(); + } + if (StartStop_btn.InvokeRequired) + { + StartStop_btn.Invoke(new Action(() => + { + StartStop_btn.Text = "Старт"; + StartStop_btn.Enabled = false; + }) + ); + } + else + { + StartStop_btn.Text = "Старт"; + StartStop_btn.Enabled = false; + } + isMonitoring = false; + } + else if (e.Answer == "MONITORON") + { + if (StartStop_btn.InvokeRequired) + { + StartStop_btn.Invoke(new Action(() => StartStop_btn.Text = "Стоп")); + } + else StartStop_btn.Text = "Стоп"; + isMonitoring = true; + } + else if (e.Answer == "MONITOROFF") + { + if (StartStop_btn.InvokeRequired) + { + StartStop_btn.Invoke(new Action(() => StartStop_btn.Text = "Старт")); + } + else StartStop_btn.Text = "Старт"; + isMonitoring = false; } } private void Serial_MonitoringItemsReceived(object sender, MonitoringEventArgs e) { - for(int i = 0; i < monitorList.Count; i++) + for(int i = 0; i < monItems.Count; i++) { - ShiftLeft(monitorList[i]); - monitorList[i][monitorList[i].Length - 1] = e.Data[i]; + monItems[i].Insert(e.Data[i]); } - monitoring = new float[monitorList.Count]; - for (int i = 0; i < monitorList.Count; i++) + monitoring = new float[monItems.Count]; + for (int i = 0; i < monItems.Count; i++) { - monitoring[i] = (float)monitorList[i][monitorList[i].Length - 1]; + monitoring[i] = (float)monItems[i].Last; } } private void UpdateTimer_Tick(object sender, EventArgs e) { - if (mon_test_label.InvokeRequired) - { - mon_test_label.Invoke(new Action(() => mon_test_label.Text = string.Join(", ", monitoring))); - } - else - { - mon_test_label.Text = string.Join(", ", monitoring); - } - - if (monNames_label.InvokeRequired) - { - monNames_label.Invoke(new Action(() => monNames_label.Text = string.Join(", ", monitorNames))); - } - else monNames_label.Text = string.Join(", ", monitorNames); - - if (monitorList.Count > 0) + if (monItems.Count > 0) { MainFormPlot.Plot.Clear(); - for(int i = 0; i < monitorList.Count; i++) + for(int i = 0; i < monItems.Count; i++) { - var sig = MainFormPlot.Plot.Add.Signal(monitorList[i]); - sig.LegendText = monitorNames[i]; + var sig = MainFormPlot.Plot.Add.Signal(monItems[i].data); + sig.LegendText = monItems[i].name; + sig.Color = ScottPlot.Color.FromColor(monItems[i].color); + if (monitorItems_lb.InvokeRequired) + { + monitorItems_lb.Invoke(new Action(() => monitorItems_lb.Items[i] = monItems[i].name + "\t" + monItems[i].Last)); + } + else + { + monitorItems_lb.Items[i] = monItems[i].name + "\t" + monItems[i].Last; + } } MainFormPlot.Plot.Legend.IsVisible = true; MainFormPlot.Plot.Legend.Orientation = ScottPlot.Orientation.Horizontal; - MainFormPlot.Plot.Axes.AutoScale(); + if(isAutoScale) MainFormPlot.Plot.Axes.AutoScale(); MainFormPlot.Refresh(); + } } @@ -164,9 +209,93 @@ namespace TelemetryIO serial.RemoveMonitoringItem(processingIndex); } - private void ShiftLeft(double[] arr) + private void StartStop_btn_Click(object sender, EventArgs e) { - Buffer.BlockCopy(arr, sizeof(double), arr, 0, (arr.Length - 1)*sizeof(double)); + if(isMonitoring) + { + serial.stopMonitoring(); + } + else + { + serial.startMonitoring(); + } + } + + private void AutoScale_check_CheckedChanged(object sender, EventArgs e) + { + CheckBox cb = sender as CheckBox; + if (cb.Checked) isAutoScale = true; + else isAutoScale = false; + } + } + + public class MonitorItem + { + public double[] data = new double[2048]; + public System.Drawing.Color color = System.Drawing.Color.Red; + public string name = ""; + public int order = 0; + private static int col = 0; + private bool firstScan = true; + public int Length + { + get { return data.Length; } + } + + public double Last + { + get { return data[data.Length - 1]; } + } + + private System.Drawing.Color[] colors = + { + System.Drawing.Color.Red, + System.Drawing.Color.Green, + System.Drawing.Color.Blue, + System.Drawing.Color.Orange, + System.Drawing.Color.Orchid, + System.Drawing.Color.Purple, + System.Drawing.Color.Pink, + System.Drawing.Color.Black, + System.Drawing.Color.Gray, + System.Drawing.Color.SkyBlue, + System.Drawing.Color.Magenta, + System.Drawing.Color.DarkGreen, + System.Drawing.Color.LightGreen, + System.Drawing.Color.YellowGreen, + System.Drawing.Color.DarkRed, + }; + + private void init() + { + color = colors[col % 16]; + col++; + } + public MonitorItem() + { + init(); + } + + public MonitorItem(string name, int order) + { + this.name = name; + this.order = order; + init(); + } + + public void Insert(double d) + { + if (firstScan) + { + for(int i = 0; i < data.Length; i++) + { + data[i] = d; + } + firstScan = false; + return; + } + Buffer.BlockCopy(data, sizeof(double), data, 0, (data.Length - 1) * sizeof(double)); + data[data.Length - 1] = d; } } } diff --git a/TelemetryIO/RatePID.Designer.cs b/TelemetryIO/RatePID.Designer.cs index b45d772..2c89189 100644 --- a/TelemetryIO/RatePID.Designer.cs +++ b/TelemetryIO/RatePID.Designer.cs @@ -160,9 +160,10 @@ // // Save_btn // - this.Save_btn.Location = new System.Drawing.Point(1012, 562); + this.Save_btn.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.Save_btn.Location = new System.Drawing.Point(1097, 608); this.Save_btn.Name = "Save_btn"; - this.Save_btn.Size = new System.Drawing.Size(75, 23); + this.Save_btn.Size = new System.Drawing.Size(90, 30); this.Save_btn.TabIndex = 18; this.Save_btn.Text = "Сохранить"; this.Save_btn.UseVisualStyleBackColor = true; @@ -170,9 +171,10 @@ // // button1 // - this.button1.Location = new System.Drawing.Point(1107, 562); + this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.button1.Location = new System.Drawing.Point(1193, 608); this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.Size = new System.Drawing.Size(90, 30); this.button1.TabIndex = 19; this.button1.Text = "Отменить"; this.button1.UseVisualStyleBackColor = true; @@ -1167,7 +1169,7 @@ this.Controls.Add(this.button1); this.Controls.Add(this.Save_btn); this.Name = "RatePID"; - this.Size = new System.Drawing.Size(1200, 600); + this.Size = new System.Drawing.Size(1300, 650); this.tabControl1.ResumeLayout(false); this.tab_pid0.ResumeLayout(false); this.pid0_panel.ResumeLayout(false); diff --git a/TelemetryIO/SerialHandler.cs b/TelemetryIO/SerialHandler.cs index 89d40db..d1eb2ec 100644 --- a/TelemetryIO/SerialHandler.cs +++ b/TelemetryIO/SerialHandler.cs @@ -56,6 +56,8 @@ namespace TelemetryIO private bool isTimeout = false; private readonly int responseTimeout = 2000; private System.Timers.Timer timeout = new System.Timers.Timer(3000); + + private bool exitPending = false; public struct Telegram @@ -101,84 +103,101 @@ namespace TelemetryIO private void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; - - - while (sp.BytesToRead > 0) + try { - if (!sp.IsOpen) return; - byte b = (byte)sp.ReadByte(); + while (sp.BytesToRead > 0) + { + if (!sp.IsOpen) return; + byte b = (byte)sp.ReadByte(); - if (b == ESCAPE_END) - {//END BYTE IS RECEIVED - timeout.Stop(); - isTimeout = false; - byte[] unscape = EscapeSeqToBytes(rx_buf.ToArray()); - uint checksum = crc32(unscape, unscape.Length - 4); - uint re_checksum = DataSlots.bytes_to_uint(unscape, unscape.Length - 4); - if (re_checksum == checksum) - { - //Parse telegram - int cmd = DataSlots.bytes_to_int(unscape, 0); - int slot = DataSlots.bytes_to_int(unscape, 4); - int len = DataSlots.bytes_to_int(unscape, 8); - int offset = DataSlots.bytes_to_int(unscape, 12); - byte[] data = new byte[len]; - Array.Copy(unscape, 16, data, 0, len); + if (b == ESCAPE_END) + {//END BYTE IS RECEIVED + timeout.Stop(); + isTimeout = false; + byte[] unscape = EscapeSeqToBytes(rx_buf.ToArray()); + uint checksum = crc32(unscape, unscape.Length - 4); + uint re_checksum = DataSlots.bytes_to_uint(unscape, unscape.Length - 4); + if (re_checksum == checksum) + { + //Parse telegram + int cmd = DataSlots.bytes_to_int(unscape, 0); + int slot = DataSlots.bytes_to_int(unscape, 4); + int len = DataSlots.bytes_to_int(unscape, 8); + int offset = DataSlots.bytes_to_int(unscape, 12); + byte[] data = new byte[len]; + Array.Copy(unscape, 16, data, 0, len); - if (cmd == TELE_CMD_RD_ONCE) - { - telemetry.setSlot(slot, data, offset, len); - OnAnswerReceived(slot.ToString()); - //DataSlots.setSlot(slot, data, offset, len); - } - else if (cmd == TELE_CMD_RD_MON_ON) - {//READ MONITORING DATA - for(int i = 0; i < data.Length/4; i++) + if (cmd == TELE_CMD_RD_ONCE) { - monitor[i] = BitConverter.ToSingle(data, i*4); + telemetry.setSlot(slot, data, offset, len); + OnAnswerReceived(slot.ToString()); + //DataSlots.setSlot(slot, data, offset, len); } - OnMonitoringItemsReceived(monitor); - view_str = string.Join(", ", monitor.Select(x => "" + x).ToArray(), 0, data.Length/4); - } - else if (cmd == TELE_CMD_WR) - {//WRITTING OPERATION IS DONE WITH SUCCESS - if (data[0] == 'O' && data[1] == 'k') + else if (cmd == TELE_CMD_RD_MON_ON) + {//READ MONITORING DATA + for (int i = 0; i < data.Length / 4; i++) + { + monitor[i] = BitConverter.ToSingle(data, i * 4); + } + OnMonitoringItemsReceived(monitor); + OnAnswerReceived("MONITORON"); + view_str = string.Join(", ", monitor.Select(x => "" + x).ToArray(), 0, data.Length / 4); + } + else if (cmd == TELE_CMD_WR) + {//WRITTING OPERATION IS DONE WITH SUCCESS + if (data[0] == 'O' && data[1] == 'k') + { + Debug.Write("Data is written\n"); + OnAnswerReceived("Data is written"); + } + } + else if (cmd == TELE_CMD_HELLO) + {//HANDSHAKING ANSWER + telemetry.setSlot(9999, data, 0, 0); + view_str = Encoding.ASCII.GetString(data); + req_buffer.Clear(); + OnHandShakeOccurred(); + getPIDs(); + } + else if (cmd == TELE_CMD_RD_MON_ADD) { - Debug.Write("Data is written\n"); - OnAnswerReceived("Data is written"); + OnAnswerReceived("ADD"); + isMonitorEmpty = false; } - }else if(cmd == TELE_CMD_HELLO) - {//HANDSHAKING ANSWER - telemetry.setSlot(9999, data, 0, 0); - view_str = Encoding.ASCII.GetString(data); - req_buffer.Clear(); - OnHandShakeOccurred(); - getPIDs(); - }else if(cmd == TELE_CMD_RD_MON_ADD) - { - OnAnswerReceived("ADD"); - isMonitorEmpty = false; - } - else if(cmd == TELE_CMD_RD_MON_REMOVE) - { - OnAnswerReceived("REMOVE"); - }else if(cmd == TELE_CMD_RD_MON_REMOVEALL) - { - OnAnswerReceived("REMOVEALL"); - isMonitorEmpty = true; + else if (cmd == TELE_CMD_RD_MON_REMOVE) + { + OnAnswerReceived("REMOVE"); + } + else if (cmd == TELE_CMD_RD_MON_REMOVEALL) + { + if (exitPending) + { + com_port.Close(); + OnAnswerReceived("EXITAPP"); + } + else OnAnswerReceived("REMOVEALL"); + } + else if (cmd == TELE_CMD_RD_MON_OFF) + { + OnAnswerReceived("MONITOROFF"); + } + Debug.WriteLine($"cmd = {cmd}"); + waitingForResponse = false; + sendNextRequest(); } } - waitingForResponse = false; - sendNextRequest(); - } - else if (b == ESCAPE_BEGIN) - {//START BYTE IS RECEIVED - rx_buf.Clear(); - } - else - {//FILLING BUFFER - rx_buf.Add(b); + else if (b == ESCAPE_BEGIN) + {//START BYTE IS RECEIVED + rx_buf.Clear(); + } + else + {//FILLING BUFFER + rx_buf.Add(b); + } } + }catch(Exception ex) + { + Debug.WriteLine(ex.Message); } } @@ -202,6 +221,7 @@ namespace TelemetryIO isTimeout = true; req_buffer.Clear(); this.Close(); + if(exitPending) OnAnswerReceived("EXITAPP"); } } } @@ -213,11 +233,10 @@ namespace TelemetryIO com_port.Close(); } - public void Exit() + public void requestExit() { RemoveMonitoringItems(); - while (isMonitorEmpty || isTimeout) ; - if(!isTimeout)Close(); + exitPending = true; } public void putRequest(byte[] request) @@ -292,6 +311,11 @@ namespace TelemetryIO putRequest(prepareTelegram(TELE_CMD_RD_MON_REMOVEALL, 0, new byte[0], 0)); } + public void saveFloats(float[] data) + { + prepareTelegram(TELE_CMD_WR, 1000, data, 0); + } + byte crc8(byte[] data, int length) { byte crc = 0x00; // Initial value