diff --git a/GroundStation/App.config b/GroundStation/App.config index e7dc8b7..c893f7b 100644 --- a/GroundStation/App.config +++ b/GroundStation/App.config @@ -1,84 +1,39 @@ - + - -
+ +
- + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0 - + + + + - \ No newline at end of file + diff --git a/GroundStation/FileWrite.cs b/GroundStation/FileWrite.cs new file mode 100644 index 0000000..7f51b23 --- /dev/null +++ b/GroundStation/FileWrite.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Text; +using System.Windows.Forms; + +namespace GroundStation +{ + class FileWrite + { + private readonly FileStream fs; + public FileWrite() + { + if (fs == null) + fs = new FileStream("data.dat", FileMode.OpenOrCreate, FileAccess.Write); + } + public void Write_Double_Pair_Data(double a, double b) + { + string stra = a.ToString("#0.0000"); + string strb = b.ToString("#0.0000"); + string str = stra + " " + strb + "\r\n"; + byte[] data = Encoding.UTF8.GetBytes(str); + try + { + fs.Write(data, 0, data.Length); + } + catch (Exception) { } + } + public void Write_File() + { + try + { + fs.Flush(); + fs.Close(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + } +} diff --git a/GroundStation/Filter.cs b/GroundStation/Filter.cs new file mode 100644 index 0000000..828d34d --- /dev/null +++ b/GroundStation/Filter.cs @@ -0,0 +1,34 @@ +namespace GroundStation +{ + class Filter + { + private readonly double[] IIRdelay = new double[2]; + private readonly double[] MoveSave = new double[8]; + private double UnitDelay; + public double IIR_LowPassFilter(double DataIn) + { + IIRdelay[0] = DataIn + 0.76295 * IIRdelay[1] - 0.283438 * IIRdelay[2]; + double DataOut = 0.129 * IIRdelay[0] + 0.258 * IIRdelay[1] + 0.129 * IIRdelay[2]; + IIRdelay[2] = IIRdelay[1]; + IIRdelay[1] = IIRdelay[0]; + return DataOut; + } + public double Moving_Average(double DataIn) + { + double sum = DataIn; + for (int i = 0; i < 7; i++) + { + MoveSave[i] = MoveSave[i + 1]; + sum += MoveSave[i]; + } + MoveSave[7] = DataIn; + return sum / 8.0; + } + public double OneOrder_Filter(double DataIn) + { + double DataOut = DataIn + 0.25 * UnitDelay; + UnitDelay = DataOut; + return DataOut * 0.75; + } + } +} diff --git a/GroundStation/Form1.Designer.cs b/GroundStation/Form1.Designer.cs index e46a2f6..f971025 100644 --- a/GroundStation/Form1.Designer.cs +++ b/GroundStation/Form1.Designer.cs @@ -63,7 +63,6 @@ private void InitializeComponent() this.lblCtrlPit = new System.Windows.Forms.Label(); this.lblCtrlRol = new System.Windows.Forms.Label(); this.lblCtrlYaw = new System.Windows.Forms.Label(); - this.btnOpen2 = new System.Windows.Forms.Button(); this.cbxMotor = new System.Windows.Forms.CheckBox(); this.label14 = new System.Windows.Forms.Label(); this.cbxBaudRate2 = new System.Windows.Forms.ComboBox(); @@ -110,8 +109,11 @@ private void InitializeComponent() this.vScrollThr = new System.Windows.Forms.VScrollBar(); this.hScrollRol = new System.Windows.Forms.HScrollBar(); this.hScrollYaw = new System.Windows.Forms.HScrollBar(); + this.btnOpen2 = new System.Windows.Forms.Button(); this.btnCtrl = new System.Windows.Forms.Button(); this.tabPage3 = new System.Windows.Forms.TabPage(); + this.tbxNotepad = new System.Windows.Forms.TextBox(); + this.cbxFileWrite = new System.Windows.Forms.CheckBox(); this.label17 = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this.label8 = new System.Windows.Forms.Label(); @@ -134,6 +136,7 @@ private void InitializeComponent() this.tbxRolParam3 = new System.Windows.Forms.TextBox(); this.tbxRolParam1 = new System.Windows.Forms.TextBox(); this.tabPage4 = new System.Windows.Forms.TabPage(); + this.cbxDisplay = new System.Windows.Forms.CheckBox(); this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart(); this.tmrSendUser = new System.Windows.Forms.Timer(this.components); this.lblVersion = new System.Windows.Forms.Label(); @@ -142,22 +145,20 @@ private void InitializeComponent() this.btnClearBuf = new System.Windows.Forms.Button(); this.btnReCnt = new System.Windows.Forms.Button(); this.tmrCtrl = new System.Windows.Forms.Timer(this.components); - this.btnOpen1 = new System.Windows.Forms.Button(); this.tmrPortRcv = new System.Windows.Forms.Timer(this.components); this.serialPort2 = new System.IO.Ports.SerialPort(this.components); + this.imgBitErr = new System.Windows.Forms.PictureBox(); + this.btnOpen1 = new System.Windows.Forms.Button(); + this.label7 = new System.Windows.Forms.Label(); this.tabControl1.SuspendLayout(); this.tabPage1.SuspendLayout(); this.tabPage2.SuspendLayout(); this.tabPage3.SuspendLayout(); this.tabPage4.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.imgBitErr)).BeginInit(); this.SuspendLayout(); // - // serialPort1 - // - this.serialPort1.ReadBufferSize = 1024; - this.serialPort1.WriteBufferSize = 128; - // // cbxPort1 // this.cbxPort1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; @@ -242,7 +243,7 @@ private void InitializeComponent() this.tbxInterval.Size = new System.Drawing.Size(92, 25); this.tbxInterval.TabIndex = 7; this.tbxInterval.Text = "1000"; - this.tbxInterval.TextChanged += new System.EventHandler(this.textBox4_TextChanged); + this.tbxInterval.TextChanged += new System.EventHandler(this.tbxInterval_TextChanged); // // btnSend1 // @@ -252,7 +253,7 @@ private void InitializeComponent() this.btnSend1.TabIndex = 11; this.btnSend1.Text = "发送"; this.btnSend1.UseVisualStyleBackColor = true; - this.btnSend1.Click += new System.EventHandler(this.btnSend1_Click); + this.btnSend1.Click += new System.EventHandler(this.btnSend_Click); // // btnSend3 // @@ -262,7 +263,7 @@ private void InitializeComponent() this.btnSend3.TabIndex = 11; this.btnSend3.Text = "发送"; this.btnSend3.UseVisualStyleBackColor = true; - this.btnSend3.Click += new System.EventHandler(this.btnSend3_Click); + this.btnSend3.Click += new System.EventHandler(this.btnSend_Click); // // tmrPortChk // @@ -378,7 +379,7 @@ private void InitializeComponent() this.btnSend2.TabIndex = 11; this.btnSend2.Text = "发送"; this.btnSend2.UseVisualStyleBackColor = true; - this.btnSend2.Click += new System.EventHandler(this.btnSend2_Click); + this.btnSend2.Click += new System.EventHandler(this.btnSend_Click); // // tabPage2 // @@ -389,7 +390,6 @@ private void InitializeComponent() this.tabPage2.Controls.Add(this.lblCtrlPit); this.tabPage2.Controls.Add(this.lblCtrlRol); this.tabPage2.Controls.Add(this.lblCtrlYaw); - this.tabPage2.Controls.Add(this.btnOpen2); this.tabPage2.Controls.Add(this.cbxMotor); this.tabPage2.Controls.Add(this.label14); this.tabPage2.Controls.Add(this.cbxBaudRate2); @@ -436,11 +436,12 @@ private void InitializeComponent() this.tabPage2.Controls.Add(this.vScrollThr); this.tabPage2.Controls.Add(this.hScrollRol); this.tabPage2.Controls.Add(this.hScrollYaw); + this.tabPage2.Controls.Add(this.btnOpen2); this.tabPage2.Controls.Add(this.btnCtrl); this.tabPage2.Location = new System.Drawing.Point(4, 25); this.tabPage2.Name = "tabPage2"; this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(1071, 622); + this.tabPage2.Size = new System.Drawing.Size(1230, 622); this.tabPage2.TabIndex = 1; this.tabPage2.Text = "飞行控制"; this.tabPage2.UseVisualStyleBackColor = true; @@ -511,19 +512,6 @@ private void InitializeComponent() this.lblCtrlYaw.TabIndex = 21; this.lblCtrlYaw.Text = "500"; // - // btnOpen2 - // - this.btnOpen2.Image = global::GroundStation.Properties.Resources.ledoff; - this.btnOpen2.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnOpen2.Location = new System.Drawing.Point(1065, 174); - this.btnOpen2.Name = "btnOpen2"; - this.btnOpen2.Size = new System.Drawing.Size(140, 40); - this.btnOpen2.TabIndex = 2; - this.btnOpen2.Text = "打开连接"; - this.btnOpen2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.btnOpen2.UseVisualStyleBackColor = true; - this.btnOpen2.Click += new System.EventHandler(this.btnOpen2_Click); - // // cbxMotor // this.cbxMotor.AutoSize = true; @@ -1006,6 +994,19 @@ private void InitializeComponent() this.hScrollYaw.TabIndex = 2; this.hScrollYaw.Value = 50; // + // btnOpen2 + // + this.btnOpen2.Image = global::GroundStation.Properties.Resources.ledoff; + this.btnOpen2.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnOpen2.Location = new System.Drawing.Point(1065, 174); + this.btnOpen2.Name = "btnOpen2"; + this.btnOpen2.Size = new System.Drawing.Size(140, 40); + this.btnOpen2.TabIndex = 2; + this.btnOpen2.Text = "打开连接"; + this.btnOpen2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.btnOpen2.UseVisualStyleBackColor = true; + this.btnOpen2.Click += new System.EventHandler(this.btnOpen2_Click); + // // btnCtrl // this.btnCtrl.Image = global::GroundStation.Properties.Resources.ledoff; @@ -1022,6 +1023,8 @@ private void InitializeComponent() // tabPage3 // this.tabPage3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.tabPage3.Controls.Add(this.tbxNotepad); + this.tabPage3.Controls.Add(this.cbxFileWrite); this.tabPage3.Controls.Add(this.label17); this.tabPage3.Controls.Add(this.label9); this.tabPage3.Controls.Add(this.label8); @@ -1045,11 +1048,31 @@ private void InitializeComponent() this.tabPage3.Controls.Add(this.tbxRolParam1); this.tabPage3.Location = new System.Drawing.Point(4, 25); this.tabPage3.Name = "tabPage3"; - this.tabPage3.Size = new System.Drawing.Size(1071, 622); + this.tabPage3.Size = new System.Drawing.Size(1230, 622); this.tabPage3.TabIndex = 2; this.tabPage3.Text = "参数设置"; this.tabPage3.UseVisualStyleBackColor = true; // + // tbxNotepad + // + this.tbxNotepad.Location = new System.Drawing.Point(652, 3); + this.tbxNotepad.Multiline = true; + this.tbxNotepad.Name = "tbxNotepad"; + this.tbxNotepad.Size = new System.Drawing.Size(565, 599); + this.tbxNotepad.TabIndex = 19; + // + // cbxFileWrite + // + this.cbxFileWrite.AutoSize = true; + this.cbxFileWrite.Font = new System.Drawing.Font("宋体", 13.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.cbxFileWrite.Location = new System.Drawing.Point(7, 591); + this.cbxFileWrite.Name = "cbxFileWrite"; + this.cbxFileWrite.Size = new System.Drawing.Size(128, 28); + this.cbxFileWrite.TabIndex = 18; + this.cbxFileWrite.Text = "写入数据"; + this.cbxFileWrite.UseVisualStyleBackColor = true; + this.cbxFileWrite.CheckedChanged += new System.EventHandler(this.cbxFileWrite_CheckedChanged); + // // label17 // this.label17.AutoSize = true; @@ -1085,7 +1108,7 @@ private void InitializeComponent() this.btnReadYaw.Location = new System.Drawing.Point(179, 364); this.btnReadYaw.Name = "btnReadYaw"; this.btnReadYaw.Size = new System.Drawing.Size(123, 41); - this.btnReadYaw.TabIndex = 9; + this.btnReadYaw.TabIndex = 16; this.btnReadYaw.Text = "读取参数"; this.btnReadYaw.UseVisualStyleBackColor = true; this.btnReadYaw.Click += new System.EventHandler(this.btnRead_Click); @@ -1095,7 +1118,7 @@ private void InitializeComponent() this.btnReadPit.Location = new System.Drawing.Point(179, 188); this.btnReadPit.Name = "btnReadPit"; this.btnReadPit.Size = new System.Drawing.Size(123, 41); - this.btnReadPit.TabIndex = 9; + this.btnReadPit.TabIndex = 10; this.btnReadPit.Text = "读取参数"; this.btnReadPit.UseVisualStyleBackColor = true; this.btnReadPit.Click += new System.EventHandler(this.btnRead_Click); @@ -1105,7 +1128,7 @@ private void InitializeComponent() this.btnReadRol.Location = new System.Drawing.Point(179, 25); this.btnReadRol.Name = "btnReadRol"; this.btnReadRol.Size = new System.Drawing.Size(123, 41); - this.btnReadRol.TabIndex = 7; + this.btnReadRol.TabIndex = 4; this.btnReadRol.Text = "读取参数"; this.btnReadRol.UseVisualStyleBackColor = true; this.btnReadRol.Click += new System.EventHandler(this.btnRead_Click); @@ -1115,7 +1138,7 @@ private void InitializeComponent() this.btnWriteYaw.Location = new System.Drawing.Point(179, 411); this.btnWriteYaw.Name = "btnWriteYaw"; this.btnWriteYaw.Size = new System.Drawing.Size(123, 41); - this.btnWriteYaw.TabIndex = 8; + this.btnWriteYaw.TabIndex = 17; this.btnWriteYaw.Text = "写入参数"; this.btnWriteYaw.UseVisualStyleBackColor = true; this.btnWriteYaw.Click += new System.EventHandler(this.btnWrite_Click); @@ -1125,7 +1148,7 @@ private void InitializeComponent() this.btnWritePit.Location = new System.Drawing.Point(179, 235); this.btnWritePit.Name = "btnWritePit"; this.btnWritePit.Size = new System.Drawing.Size(123, 41); - this.btnWritePit.TabIndex = 8; + this.btnWritePit.TabIndex = 11; this.btnWritePit.Text = "写入参数"; this.btnWritePit.UseVisualStyleBackColor = true; this.btnWritePit.Click += new System.EventHandler(this.btnWrite_Click); @@ -1135,14 +1158,14 @@ private void InitializeComponent() this.tbxYawParam2.Location = new System.Drawing.Point(50, 383); this.tbxYawParam2.Name = "tbxYawParam2"; this.tbxYawParam2.Size = new System.Drawing.Size(100, 25); - this.tbxYawParam2.TabIndex = 5; + this.tbxYawParam2.TabIndex = 13; // // btnWriteRol // this.btnWriteRol.Location = new System.Drawing.Point(179, 72); this.btnWriteRol.Name = "btnWriteRol"; this.btnWriteRol.Size = new System.Drawing.Size(123, 41); - this.btnWriteRol.TabIndex = 6; + this.btnWriteRol.TabIndex = 5; this.btnWriteRol.Text = "写入参数"; this.btnWriteRol.UseVisualStyleBackColor = true; this.btnWriteRol.Click += new System.EventHandler(this.btnWrite_Click); @@ -1152,42 +1175,42 @@ private void InitializeComponent() this.tbxYawParam4.Location = new System.Drawing.Point(50, 445); this.tbxYawParam4.Name = "tbxYawParam4"; this.tbxYawParam4.Size = new System.Drawing.Size(100, 25); - this.tbxYawParam4.TabIndex = 7; + this.tbxYawParam4.TabIndex = 15; // // tbxPitParam2 // this.tbxPitParam2.Location = new System.Drawing.Point(50, 207); this.tbxPitParam2.Name = "tbxPitParam2"; this.tbxPitParam2.Size = new System.Drawing.Size(100, 25); - this.tbxPitParam2.TabIndex = 5; + this.tbxPitParam2.TabIndex = 7; // // tbxYawParam3 // this.tbxYawParam3.Location = new System.Drawing.Point(50, 414); this.tbxYawParam3.Name = "tbxYawParam3"; this.tbxYawParam3.Size = new System.Drawing.Size(100, 25); - this.tbxYawParam3.TabIndex = 6; + this.tbxYawParam3.TabIndex = 14; // // tbxPitParam4 // this.tbxPitParam4.Location = new System.Drawing.Point(50, 269); this.tbxPitParam4.Name = "tbxPitParam4"; this.tbxPitParam4.Size = new System.Drawing.Size(100, 25); - this.tbxPitParam4.TabIndex = 7; + this.tbxPitParam4.TabIndex = 9; // // tbxPitParam3 // this.tbxPitParam3.Location = new System.Drawing.Point(50, 238); this.tbxPitParam3.Name = "tbxPitParam3"; this.tbxPitParam3.Size = new System.Drawing.Size(100, 25); - this.tbxPitParam3.TabIndex = 6; + this.tbxPitParam3.TabIndex = 8; // // tbxYawParam1 // this.tbxYawParam1.Location = new System.Drawing.Point(50, 352); this.tbxYawParam1.Name = "tbxYawParam1"; this.tbxYawParam1.Size = new System.Drawing.Size(100, 25); - this.tbxYawParam1.TabIndex = 4; + this.tbxYawParam1.TabIndex = 12; // // tbxRolParam2 // @@ -1201,7 +1224,7 @@ private void InitializeComponent() this.tbxPitParam1.Location = new System.Drawing.Point(50, 176); this.tbxPitParam1.Name = "tbxPitParam1"; this.tbxPitParam1.Size = new System.Drawing.Size(100, 25); - this.tbxPitParam1.TabIndex = 4; + this.tbxPitParam1.TabIndex = 6; // // tbxRolParam4 // @@ -1226,6 +1249,7 @@ private void InitializeComponent() // // tabPage4 // + this.tabPage4.Controls.Add(this.cbxDisplay); this.tabPage4.Controls.Add(this.chart1); this.tabPage4.Location = new System.Drawing.Point(4, 25); this.tabPage4.Name = "tabPage4"; @@ -1234,8 +1258,23 @@ private void InitializeComponent() this.tabPage4.Text = "波形显示"; this.tabPage4.UseVisualStyleBackColor = true; // + // cbxDisplay + // + this.cbxDisplay.AutoSize = true; + this.cbxDisplay.Location = new System.Drawing.Point(1138, 600); + this.cbxDisplay.Name = "cbxDisplay"; + this.cbxDisplay.Size = new System.Drawing.Size(89, 19); + this.cbxDisplay.TabIndex = 1; + this.cbxDisplay.Text = "开始显示"; + this.cbxDisplay.UseVisualStyleBackColor = true; + // // chart1 // + chartArea1.AxisX.Interval = 25D; + chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.Gainsboro; + chartArea1.AxisX.Maximum = 500D; + chartArea1.AxisX.Minimum = 0D; + chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.Gainsboro; chartArea1.Name = "ChartArea1"; this.chart1.ChartAreas.Add(chartArea1); legend1.Name = "Legend1"; @@ -1267,7 +1306,7 @@ private void InitializeComponent() // labelTxCnt // this.labelTxCnt.AutoSize = true; - this.labelTxCnt.Location = new System.Drawing.Point(598, 669); + this.labelTxCnt.Location = new System.Drawing.Point(553, 669); this.labelTxCnt.Name = "labelTxCnt"; this.labelTxCnt.Size = new System.Drawing.Size(39, 15); this.labelTxCnt.TabIndex = 14; @@ -1276,7 +1315,7 @@ private void InitializeComponent() // labelRxCnt // this.labelRxCnt.AutoSize = true; - this.labelRxCnt.Location = new System.Drawing.Point(598, 694); + this.labelRxCnt.Location = new System.Drawing.Point(553, 694); this.labelRxCnt.Name = "labelRxCnt"; this.labelRxCnt.Size = new System.Drawing.Size(39, 15); this.labelRxCnt.TabIndex = 14; @@ -1284,7 +1323,7 @@ private void InitializeComponent() // // btnClearBuf // - this.btnClearBuf.Location = new System.Drawing.Point(370, 669); + this.btnClearBuf.Location = new System.Drawing.Point(325, 669); this.btnClearBuf.Name = "btnClearBuf"; this.btnClearBuf.Size = new System.Drawing.Size(115, 40); this.btnClearBuf.TabIndex = 3; @@ -1294,7 +1333,7 @@ private void InitializeComponent() // // btnReCnt // - this.btnReCnt.Location = new System.Drawing.Point(491, 669); + this.btnReCnt.Location = new System.Drawing.Point(446, 669); this.btnReCnt.Name = "btnReCnt"; this.btnReCnt.Size = new System.Drawing.Size(101, 40); this.btnReCnt.TabIndex = 4; @@ -1307,6 +1346,20 @@ private void InitializeComponent() this.tmrCtrl.Enabled = true; this.tmrCtrl.Tick += new System.EventHandler(this.tmrCtrl_Tick); // + // tmrPortRcv + // + this.tmrPortRcv.Interval = 10; + this.tmrPortRcv.Tick += new System.EventHandler(this.tmrPortRcv_Tick); + // + // imgBitErr + // + this.imgBitErr.Image = global::GroundStation.Properties.Resources.error; + this.imgBitErr.Location = new System.Drawing.Point(662, 670); + this.imgBitErr.Name = "imgBitErr"; + this.imgBitErr.Size = new System.Drawing.Size(40, 40); + this.imgBitErr.TabIndex = 15; + this.imgBitErr.TabStop = false; + // // btnOpen1 // this.btnOpen1.Image = global::GroundStation.Properties.Resources.ledoff; @@ -1320,16 +1373,23 @@ private void InitializeComponent() this.btnOpen1.UseVisualStyleBackColor = true; this.btnOpen1.Click += new System.EventHandler(this.btnOpen1_Click); // - // tmrPortRcv + // label7 // - this.tmrPortRcv.Interval = 10; - this.tmrPortRcv.Tick += new System.EventHandler(this.tmrPortRcv_Tick); + this.label7.AutoSize = true; + this.label7.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label7.Location = new System.Drawing.Point(712, 682); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(37, 15); + this.label7.TabIndex = 16; + this.label7.Text = "误码"; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1262, 721); + this.Controls.Add(this.label7); + this.Controls.Add(this.imgBitErr); this.Controls.Add(this.btnReCnt); this.Controls.Add(this.btnClearBuf); this.Controls.Add(this.labelRxCnt); @@ -1359,7 +1419,9 @@ private void InitializeComponent() this.tabPage3.ResumeLayout(false); this.tabPage3.PerformLayout(); this.tabPage4.ResumeLayout(false); + this.tabPage4.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.chart1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.imgBitErr)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -1479,6 +1541,11 @@ private void InitializeComponent() private System.Windows.Forms.TextBox tbxYawParam1; private System.Windows.Forms.Button btnAccCali; private System.Windows.Forms.Button btnGyroCali; + private System.Windows.Forms.CheckBox cbxDisplay; + private System.Windows.Forms.CheckBox cbxFileWrite; + private System.Windows.Forms.TextBox tbxNotepad; + private System.Windows.Forms.PictureBox imgBitErr; + private System.Windows.Forms.Label label7; } } diff --git a/GroundStation/Form1.base.cs b/GroundStation/Form1.base.cs index c9c36f4..a261345 100644 --- a/GroundStation/Form1.base.cs +++ b/GroundStation/Form1.base.cs @@ -2,6 +2,14 @@ using System.Windows.Forms; /**************文件说明********************** 基本收发 +事件: +btnSend_Click +textBox4_TextChanged +tmrSendUser_Tick +cbxAutoSend_CheckedChanged +函数: +Base_Text_Receive +Tab0_Text_Send ********************************************/ namespace GroundStation @@ -9,20 +17,16 @@ namespace GroundStation partial class Form1 { /*发送按钮*/ - private void btnSend1_Click(object sender, EventArgs e) + private void btnSend_Click(object sender, EventArgs e) { - if (serialPort1.IsOpen) - Tab0_Text_Send(tbxTx1, cbxHexSend1); - } - private void btnSend2_Click(object sender, EventArgs e) - { - if (serialPort1.IsOpen) - Tab0_Text_Send(tbxTx2, cbxHexSend2); - } - private void btnSend3_Click(object sender, EventArgs e) - { - if (serialPort1.IsOpen) - Tab0_Text_Send(tbxTx3, cbxHexSend3); + if (!serialPort1.IsOpen) return; + switch (((Button)sender).Name) + { + case "btnSend1": Tab0_Text_Send(tbxTx1, cbxHexSend1); break; + case "btnSend2": Tab0_Text_Send(tbxTx2, cbxHexSend2); break; + case "btnSend3": Tab0_Text_Send(tbxTx3, cbxHexSend3); break; + default: break; + } } private void Base_Text_Receive() { @@ -104,14 +108,17 @@ private void Tab0_Text_Send(TextBox box, CheckBox cbxHex) labelTxCnt.Text = $"Tx:{TxCount}"; } /*定时发送复选框*/ - private void textBox4_TextChanged(object sender, EventArgs e) + private void tbxInterval_TextChanged(object sender, EventArgs e) { cbxAutoSend.Checked = false; } /*定时发送*/ private void tmrSendUser_Tick(object sender, EventArgs e) { - Tab0_Text_Send(tbxTx1, cbxHexSend1); + if (tabControl1.SelectedIndex == 0) + Tab0_Text_Send(tbxTx1, cbxHexSend1); + else + cbxAutoSend.Checked = false; } /*发送间隔设置文本框*/ private void cbxAutoSend_CheckedChanged(object sender, EventArgs e) @@ -119,7 +126,11 @@ private void cbxAutoSend_CheckedChanged(object sender, EventArgs e) if (cbxAutoSend.Checked) { tmrSendUser.Enabled = true; - tmrSendUser.Interval = Convert.ToInt32(tbxInterval.Text); + try + { + tmrSendUser.Interval = Convert.ToInt32(tbxInterval.Text); + } + catch (Exception) { } } else tmrSendUser.Enabled = false; diff --git a/GroundStation/Form1.chart.cs b/GroundStation/Form1.chart.cs index fc93f7d..5531cb7 100644 --- a/GroundStation/Form1.chart.cs +++ b/GroundStation/Form1.chart.cs @@ -6,86 +6,88 @@ using System.Windows.Forms.DataVisualization.Charting; /**************文件说明********************** 波形显示 +事件: +cbxData_CheckedChanged +函数: ChartInit Chart_Update Chart_Display Chart_Clear -cbxData_CheckedChanged ********************************************/ namespace GroundStation { partial class Form1 { - private byte DataLen = 100; - private Queue[] DataQueue = new Queue[8]; - CheckBox[] cbxData = new CheckBox[8]; + private const int DataLen = 500; + private readonly Queue[] DataQueue = new Queue[8]; + private readonly CheckBox[] cbxChart = new CheckBox[8]; - /*********************** - 图表初始化 - **********************/ + /*图表初始化*/ private void ChartInit() { Color[] DataColor = new Color[] - {Color.Red,Color.Blue,Color.Green,Color.Orange,Color.Purple,Color.Silver,Color.Pink,Color.Cyan}; + {Color.Red,Color.Blue,Color.Green,Color.Orange,Color.Purple,Color.Black,Color.Pink,Color.Cyan}; chart1.Series.Clear(); - stat.ChartFirst = true; - chart1.ChartAreas[0].AxisX.Interval = 5; - chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Silver; - chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Silver; Series[] series = new Series[8]; for (int i = 0; i < 8; i++) { - cbxData[i] = new CheckBox(); - cbxData[i].Location = new Point(6 + i * 70, 475); - cbxData[i].Name = $"cbxData{i}"; - cbxData[i].Text = $"DATA{i}"; - cbxData[i].Size = new Size(65, 20); - cbxData[i].ForeColor = DataColor[i]; - cbxData[i].TabIndex = i; - cbxData[i].CheckedChanged += cbxData_CheckedChanged; - tabPage4.Controls.Add(cbxData[i]); + cbxChart[i] = new CheckBox(); + cbxChart[i].Location = new Point(6 + i * 70, 475); + cbxChart[i].Name = $"cbxData{i}"; + cbxChart[i].Text = $"DATA{i}"; + cbxChart[i].Size = new Size(65, 20); + cbxChart[i].ForeColor = DataColor[i]; + cbxChart[i].TabIndex = i; + tabPage4.Controls.Add(cbxChart[i]); DataQueue[i] = new Queue(DataLen); chart1.Series.Add(new Series()); chart1.Series[i].Color = DataColor[i]; chart1.Series[i].ChartType = SeriesChartType.Line; } } - private void cbxData_CheckedChanged(object sender, EventArgs e) - { - Chart_Clear(); - } - /*********************** - 图表更新 - **********************/ - private void Chart_Update(double data, int LineLabel) + + /*向图表的队列中添加数据*/ + private void Chart_AddPoints(double data, int LineLabel) { + if (!cbxDisplay.Checked) return; if (DataQueue[LineLabel].Count >= DataLen) DataQueue[LineLabel].Dequeue(); DataQueue[LineLabel].Enqueue(data); - chart1.Series[LineLabel].Points.Clear(); - for (int i = 0; i < DataQueue[LineLabel].Count; i++) - { - if (stat.ChartFirst) - { - chart1.ChartAreas[0].AxisY.Maximum = data; - chart1.ChartAreas[0].AxisY.Minimum = data - 0.01; - stat.ChartFirst = false; - } - if (data > chart1.ChartAreas[0].AxisY.Maximum) - chart1.ChartAreas[0].AxisY.Maximum = data; - else if (data < chart1.ChartAreas[0].AxisY.Minimum) - chart1.ChartAreas[0].AxisY.Minimum = data; - chart1.Series[LineLabel].Points.AddXY(i + 1, DataQueue[LineLabel].ElementAt(i)); - } } - private void Chart_Display() + + /*向下位机发送显示指令并更新图表*/ + private void Chart_Update() { if (!serialPort1.IsOpen) return; + if (!cbxDisplay.Checked) return; byte channel = 0; + double temp, max = -1e6, min = 1e6; for (int i = 0; i < 8; i++) - if (cbxData[i].Checked) + { + //通知下位机获取哪个通道的数据 + if (cbxChart[i].Checked) channel |= (byte)(1 << i); + else continue; + //获取图表的最大值和最小值 + if (DataQueue[i].Count == 0) continue; + temp = DataQueue[i].Max(); + max = temp > max ? temp : max; + temp = DataQueue[i].Min(); + min = temp < min ? temp : min; + } + chart1.ChartAreas[0].AxisY.Maximum = max + 0.001; + chart1.ChartAreas[0].AxisY.Minimum = min - 0.001; + //更新图表 + for (int i = 0; i < 8; i++) + { + chart1.Series[i].Points.Clear(); + if (!cbxChart[i].Checked) continue; + if (DataQueue[i].Count == 0) continue; + for (int j = 0; j < DataQueue[i].Count; j++) + chart1.Series[i].Points.AddXY(j + 1, DataQueue[i].ElementAt(j)); + } + //发送指令 if (channel != 0) { byte DataAdd = ptcl1.Send_Req(0xC3, channel, SerialPort1_Send); @@ -93,9 +95,8 @@ private void Chart_Display() labelTxCnt.Text = $"Tx:{TxCount}"; } } - /*********************** - 清除缓存 - **********************/ + + /*清除缓存*/ private void Chart_Clear() { int cnt; @@ -106,7 +107,6 @@ private void Chart_Clear() DataQueue[i].Dequeue(); chart1.Series[i].Points.Clear(); } - stat.ChartFirst = true; } } } diff --git a/GroundStation/Form1.cs b/GroundStation/Form1.cs index 8a519ac..f97193c 100644 --- a/GroundStation/Form1.cs +++ b/GroundStation/Form1.cs @@ -10,7 +10,6 @@ btnOpen1_Click btnOpen2_Click tmrPortChk_Tick -tabControl1_SelectedIndexChanged btnClearBuf_Click btnReCnt_Click 函数: @@ -24,12 +23,12 @@ namespace GroundStation { public partial class Form1 : Form { - string[] LastPorts = { }; - const string version = "Ground Station V1.01"; - long TxCount = 0, RxCount = 0; - Protocol ptcl1 = new Protocol(); - Protocol ptcl2 = new Protocol(); - bool sp1Open, sp2Open; + private string[] LastPorts = { }; + private const string version = "Ground Station V1.04"; + private long TxCount = 0, RxCount = 0; + private readonly Protocol ptcl1 = new Protocol(); + private readonly Protocol ptcl2 = new Protocol(); + private bool sp1Open, sp2Open; public Form1() { InitializeComponent(); @@ -39,6 +38,10 @@ private void Form1_Load(object sender, EventArgs e) lblVersion.Text = version; ChartInit(); Form1_Init(); + rc[0] = new Filter(); + rc[1] = new Filter(); + rc[2] = new Filter(); + rc[3] = new Filter(); } /*开闭主串口按钮*/ private void btnOpen1_Click(object sender, EventArgs e) @@ -60,7 +63,7 @@ private void btnOpen1_Click(object sender, EventArgs e) } catch (Exception ex) { - lblVersion.Text = "串口打开失败! " + ex.Message; + lblVersion.Text = "串口打开失败!" + ex.Message; } } /*开闭外部输入串口按钮*/ @@ -83,7 +86,7 @@ private void btnOpen2_Click(object sender, EventArgs e) } catch (Exception ex) { - lblVersion.Text = "串口打开失败! " + ex.Message; + lblVersion.Text = "串口打开失败!" + ex.Message; } } /*定时每秒检测端口状况*/ diff --git a/GroundStation/Form1.ctrl.cs b/GroundStation/Form1.ctrl.cs index ee34252..33f59ef 100644 --- a/GroundStation/Form1.ctrl.cs +++ b/GroundStation/Form1.ctrl.cs @@ -5,7 +5,7 @@ 飞行控制,包括接收并处理下位机消息,向下位机发送指令 事件: btnCtrl_Click -btnPassword_Click +btnFlightMode_Click 函数: CtrlPanel_Update CtrlMsg_Send @@ -15,9 +15,9 @@ namespace GroundStation { partial class Form1 { - private byte ErrCnt = 20, ErrRcvCnt = 0; - GlobalStatus stat; - private int[] RCdata = { 500, 500, 0, 500 }; + private byte ErrCnt = 20, ErrRcvCnt = 10; + private GlobalStatus stat; + private readonly int[] RCdata = { 500, 500, 0, 500 }; /*发送遥控信号按钮,按下后开始发送控制信号*/ private void btnCtrl_Click(object sender, EventArgs e) @@ -39,6 +39,7 @@ private void btnCtrl_Click(object sender, EventArgs e) /*飞行模式相关按钮:锁定解锁,模式切换*/ private void btnFlightMode_Click(object sender, EventArgs e) { + if (!serialPort1.IsOpen) return; switch (((Button)sender).Name) { case "btnUnLock": @@ -98,7 +99,7 @@ private void CtrlPanel_Update() else { RCdata[0] = 10 * (100 - hScrollRol.Value); - RCdata[1] = 10 * vScrollPit.Value; + RCdata[1] = 10 * (100 - vScrollPit.Value); RCdata[2] = 10 * (100 - vScrollThr.Value); RCdata[3] = 10 * (100 - hScrollYaw.Value); lblCtrlRol.Text = (10 * (100 - hScrollRol.Value)).ToString(); @@ -111,7 +112,6 @@ private void CtrlPanel_Update() /*定时发送任务*/ private void CtrlMsg_Send() { - Key_Change(); //控制按键检测 if (!serialPort1.IsOpen) return; //显示下位机状态信息 byte SendByte = 0; diff --git a/GroundStation/Form1.init.cs b/GroundStation/Form1.init.cs index e6586fa..670a964 100644 --- a/GroundStation/Form1.init.cs +++ b/GroundStation/Form1.init.cs @@ -23,6 +23,7 @@ private void Form1_Init() cbxBaudRate1.Text = Properties.Settings.Default.cbxBaudRateStr; cbxBaudRate2.Text = Properties.Settings.Default.cbxBaudRate2Str; tbxInterval.Text = Properties.Settings.Default.tbxIntervalStr; + tbxNotepad.Text = Properties.Settings.Default.tbxNotepadstr; } /*窗口关闭保存软件设置*/ private void Form1_FormClosing(object sender, FormClosingEventArgs e) @@ -34,7 +35,8 @@ private void Form1_FormClosing(object sender, FormClosingEventArgs e) Properties.Settings.Default.cbxBaudRateStr = cbxBaudRate1.Text; Properties.Settings.Default.cbxBaudRate2Str = cbxBaudRate2.Text; Properties.Settings.Default.tbxIntervalStr = tbxInterval.Text; - Properties.Settings.Default.Save(); + Properties.Settings.Default.tbxNotepadstr = tbxNotepad.Text; + Properties.Settings.Default.Save(); } } } diff --git a/GroundStation/Form1.key.cs b/GroundStation/Form1.key.cs index c56bd61..6fba73e 100644 --- a/GroundStation/Form1.key.cs +++ b/GroundStation/Form1.key.cs @@ -1,6 +1,11 @@ using System.Windows.Forms; /**************ļ˵********************** пƽؼ̿ +¼: +Form1_KeyUp +Form1_KeyDown +: +Key_Change ********************************************/ namespace GroundStation @@ -32,7 +37,6 @@ private void Key_Change() } private void Form1_KeyUp(object sender, KeyEventArgs e) { - if (tabControl1.SelectedIndex != 1) return; Keys CtrlKey = e.KeyCode; if (CtrlKey == Keys.J) KeyState &= 0xFE; @@ -53,7 +57,6 @@ private void Form1_KeyUp(object sender, KeyEventArgs e) } private void Form1_KeyDown(object sender, KeyEventArgs e) { - if (tabControl1.SelectedIndex != 1) return; Keys CtrlKey = e.KeyCode; if (CtrlKey == Keys.J) KeyState |= 0x01; diff --git a/GroundStation/Form1.param.cs b/GroundStation/Form1.param.cs index 6b3c2ae..2c8fa11 100644 --- a/GroundStation/Form1.param.cs +++ b/GroundStation/Form1.param.cs @@ -11,6 +11,7 @@ namespace GroundStation { partial class Form1 { + private FileWrite dataFile; /*读取控制器参数*/ private void btnRead_Click(object sender, EventArgs e) { @@ -60,5 +61,19 @@ private void btnWrite_Click(object sender, EventArgs e) } catch (Exception) { } } + private void cbxFileWrite_CheckedChanged(object sender, EventArgs e) + { + if (cbxFileWrite.Checked) + { + dataFile = new FileWrite(); + TxCount += ptcl1.Send_Req(0xC4, 0x03, SerialPort1_Send); + } + else + { + TxCount += ptcl1.Send_Req(0xC4, 0, SerialPort1_Send); + dataFile.Write_File(); + } + labelTxCnt.Text = $"Tx:{TxCount}"; + } } } diff --git a/GroundStation/Form1.txrx.cs b/GroundStation/Form1.txrx.cs index 39b0a0c..c0b71fa 100644 --- a/GroundStation/Form1.txrx.cs +++ b/GroundStation/Form1.txrx.cs @@ -15,34 +15,27 @@ namespace GroundStation { partial class Form1 { - /*********************** - 为串口发送加上异常处理 - **********************/ + private readonly Filter[] rc = new Filter[4]; + /*为串口发送加上异常处理*/ private void SerialPort1_Send(byte[] buffer, int count) { try { serialPort1.Write(buffer, 0, count); } - catch (Exception) + catch (Exception ex) { SerialPort1_Close(); - }; + lblVersion.Text = "串口发送失败!" + ex.Message; + } } /*定时100ms更新与发送任务*/ private void tmrCtrl_Tick(object sender, EventArgs e) { - switch (tabControl1.SelectedIndex) - { - case 1: - CtrlPanel_Update(); - CtrlMsg_Send(); - break; - case 3: - Chart_Display(); - break; - default: break; - } + Key_Change(); //控制按键检测 + CtrlPanel_Update(); + CtrlMsg_Send(); + Chart_Update(); } /*定时10ms处理串口接收缓冲RxStr*/ private void tmrPortRcv_Tick(object sender, EventArgs e) @@ -75,11 +68,15 @@ private void tmrPortRcv_Tick(object sender, EventArgs e) } DataAdd1++; if (state == 0) + { Data_Receive_Precess(ptcl1); + imgBitErr.Image = Properties.Resources.correct; + } else if (state == 2) { lblCtrl.Text = "失控"; lblCtrl.ForeColor = Color.Red; + imgBitErr.Image = Properties.Resources.error; } } RxCount += DataAdd1; @@ -100,17 +97,20 @@ private void tmrPortRcv_Tick(object sender, EventArgs e) } DataAdd2++; if (state == 0) + { Data_Receive_Precess(ptcl2); + imgBitErr.Image = Properties.Resources.correct; + } + else if (state == 2) + imgBitErr.Image = Properties.Resources.error; } RxCount += DataAdd2; labelRxCnt.Text = $"Rx:{RxCount}"; } - /*********************** - 根据功能字进一步处理 - **********************/ + /*根据功能字进一步处理*/ private void Data_Receive_Precess(Protocol pt) { - if (pt.FcnWord == FuncByte.ctrlOut) + if (pt.FcnByte == FuncByte.ctrlOut) ErrRcvCnt = 0; else ErrCnt = 0; @@ -123,7 +123,7 @@ private void Data_Receive_Precess(Protocol pt) sdata[4] = (short)((RxTemp[8] << 8) | RxTemp[9]); sdata[5] = (short)((RxTemp[10] << 8) | RxTemp[11]); double[] ddata = new double[4]; - switch (pt.FcnWord) + switch (pt.FcnByte) { case FuncByte.stat: if ((RxTemp[0] & 0x01) == 0x01) @@ -182,16 +182,16 @@ private void Data_Receive_Precess(Protocol pt) lblQ3.Text = ddata[3].ToString("#0.0000"); break; case FuncByte.rolCtrl: - tbxRolParam1.Text = sdata[0].ToString(); - tbxRolParam2.Text = sdata[1].ToString(); - tbxRolParam3.Text = sdata[2].ToString(); - tbxRolParam4.Text = sdata[3].ToString(); + tbxRolParam1.Text = sdata[0].ToString(); + tbxRolParam2.Text = sdata[1].ToString(); + tbxRolParam3.Text = sdata[2].ToString(); + tbxRolParam4.Text = sdata[3].ToString(); break; case FuncByte.pitCtrl: - tbxPitParam1.Text = sdata[0].ToString(); - tbxPitParam2.Text = sdata[1].ToString(); - tbxPitParam3.Text = sdata[2].ToString(); - tbxPitParam4.Text = sdata[3].ToString(); + tbxPitParam1.Text = sdata[0].ToString(); + tbxPitParam2.Text = sdata[1].ToString(); + tbxPitParam3.Text = sdata[2].ToString(); + tbxPitParam4.Text = sdata[3].ToString(); break; case FuncByte.yawCtrl: tbxYawParam1.Text = sdata[0].ToString(); @@ -205,8 +205,8 @@ private void Data_Receive_Precess(Protocol pt) ddata[2] = sdata[2] / 100.0; ddata[3] = sdata[3] / 100.0; for (int i = 0; i < 4; i++) - if (cbxData[i].Checked) - Chart_Update(ddata[i], i); + if (cbxChart[i].Checked) + Chart_AddPoints(ddata[i], i); break; case FuncByte.chart2: ddata[0] = sdata[0] / 100.0; @@ -214,19 +214,25 @@ private void Data_Receive_Precess(Protocol pt) ddata[2] = sdata[2] / 100.0; ddata[3] = sdata[3] / 100.0; for (int i = 4; i < 8; i++) - if (cbxData[i].Checked) - Chart_Update(ddata[i - 4], i); + if (cbxChart[i].Checked) + Chart_AddPoints(ddata[i - 4], i); break; case FuncByte.ctrlOut: - RCdata[0] = Limit(sdata[0], 0, 1000); - RCdata[1] = Limit(sdata[1], 0, 1000); - RCdata[2] = Limit(sdata[2], 0, 1000); - RCdata[3] = Limit(sdata[3], 0, 1000); + RCdata[0] = Limit((int)rc[0].OneOrder_Filter(sdata[0]), 0, 1000); + RCdata[1] = Limit((int)rc[1].OneOrder_Filter(sdata[1]), 0, 1000); + RCdata[2] = Limit((int)rc[2].OneOrder_Filter(sdata[2]), 0, 1000); + RCdata[3] = Limit((int)rc[3].OneOrder_Filter(sdata[3]), 0, 1000); + break; + case FuncByte.highspeed: + ddata[0] = sdata[0] * 0.0076293945; + ddata[1] = sdata[1] * 0.0076293945; + if (dataFile != null) + dataFile.Write_Double_Pair_Data(ddata[0], ddata[1]); break; default: break; } } - private int Limit(int num, int min, int max) + private static int Limit(int num, int min, int max) { return num <= min ? (min) : (num >= max ? max : num); } diff --git a/GroundStation/GroundStation.csproj b/GroundStation/GroundStation.csproj index ce07657..a0c21d0 100644 --- a/GroundStation/GroundStation.csproj +++ b/GroundStation/GroundStation.csproj @@ -9,10 +9,11 @@ Properties GroundStation GroundStation - v4.5.2 + v4.6 512 true false + publish\ true Disk @@ -50,6 +51,7 @@ GroundStation.ico + true @@ -69,6 +71,8 @@ + + Form @@ -136,6 +140,8 @@ + + diff --git a/GroundStation/GroundStation.csproj.user b/GroundStation/GroundStation.csproj.user new file mode 100644 index 0000000..95a1d1a --- /dev/null +++ b/GroundStation/GroundStation.csproj.user @@ -0,0 +1,13 @@ + + + + publish\ + + + + + + zh-CN + false + + \ No newline at end of file diff --git a/GroundStation/Properties/AssemblyInfo.cs b/GroundStation/Properties/AssemblyInfo.cs index f947d6e..9280c4f 100644 --- a/GroundStation/Properties/AssemblyInfo.cs +++ b/GroundStation/Properties/AssemblyInfo.cs @@ -5,12 +5,12 @@ // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 -[assembly: AssemblyTitle("WindowsFormsApplication2")] +[assembly: AssemblyTitle("GroundStation")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WindowsFormsApplication2")] -[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyCompany("Zhang Hangning")] +[assembly: AssemblyProduct("GroundStation")] +[assembly: AssemblyCopyright("Copyright xd15zhn © 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/GroundStation/Properties/Resources.Designer.cs b/GroundStation/Properties/Resources.Designer.cs index 42d041d..9e2ee72 100644 --- a/GroundStation/Properties/Resources.Designer.cs +++ b/GroundStation/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace GroundStation.Properties { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -47,7 +47,7 @@ internal Resources() { } /// - /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性 /// 重写当前线程的 CurrentUICulture 属性。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] @@ -60,6 +60,26 @@ internal Resources() { } } + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap correct { + get { + object obj = ResourceManager.GetObject("correct", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap error { + get { + object obj = ResourceManager.GetObject("error", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// diff --git a/GroundStation/Properties/Resources.resx b/GroundStation/Properties/Resources.resx index 69ee430..aa0b164 100644 --- a/GroundStation/Properties/Resources.resx +++ b/GroundStation/Properties/Resources.resx @@ -118,6 +118,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\correct.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\ledoff.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/GroundStation/Properties/Settings.Designer.cs b/GroundStation/Properties/Settings.Designer.cs index 5835fa6..2db7133 100644 --- a/GroundStation/Properties/Settings.Designer.cs +++ b/GroundStation/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace GroundStation.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -106,5 +106,17 @@ public string cbxBaudRate2Str { this["cbxBaudRate2Str"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string tbxNotepadstr { + get { + return ((string)(this["tbxNotepadstr"])); + } + set { + this["tbxNotepadstr"] = value; + } + } } } diff --git a/GroundStation/Properties/Settings.settings b/GroundStation/Properties/Settings.settings index fab4990..68ab237 100644 --- a/GroundStation/Properties/Settings.settings +++ b/GroundStation/Properties/Settings.settings @@ -23,5 +23,8 @@ + + + \ No newline at end of file diff --git a/GroundStation/Resources/correct.png b/GroundStation/Resources/correct.png new file mode 100644 index 0000000..c9d59d7 Binary files /dev/null and b/GroundStation/Resources/correct.png differ diff --git a/GroundStation/Resources/error.png b/GroundStation/Resources/error.png new file mode 100644 index 0000000..f38f460 Binary files /dev/null and b/GroundStation/Resources/error.png differ diff --git a/GroundStation/allStructs.cs b/GroundStation/allStructs.cs index d13dc4e..66ac8a6 100644 --- a/GroundStation/allStructs.cs +++ b/GroundStation/allStructs.cs @@ -2,10 +2,9 @@ { struct GlobalStatus { - public bool RmCtrl; //是否向下位机发送控制命令 - public bool inCtrl; //下位机控制中 + public bool RmCtrl; //是否向下位机发送控制命令 + public bool inCtrl; //下位机控制中 public bool CtrlRcving; //正在接收外部控制信号 - public bool ChartFirst; //接收的是第一个数,初始化Y轴最大值和最小值 } struct FuncByte { @@ -21,5 +20,6 @@ struct FuncByte public const byte ctrlOut = 0xAA; public const byte chart1 = 0xB1; public const byte chart2 = 0xB2; + public const byte highspeed = 0x40; } } \ No newline at end of file diff --git a/GroundStation/protocol.cs b/GroundStation/protocol.cs index 5b27979..e818203 100644 --- a/GroundStation/protocol.cs +++ b/GroundStation/protocol.cs @@ -13,62 +13,74 @@ namespace GroundStation class Protocol { public byte[] DataReceived = new byte[12]; //来自下位机的有效数据 - public byte FcnWord = 0, LenWord = 0; - private byte[] DataToSend = new byte[12]; - private byte RxState = 0, sum = 0, p = 0; - /*********************** - 对从串口收到的数据进行预处理并将有效数据保存至RxTemp - **********************/ + public byte FcnByte = 0; + private byte LenByte = 0; + private readonly byte[] DataToSend = new byte[12]; + private byte RxState = 0, CheckSum = 0, cnt = 0; + /*对从串口收到的数据进行预处理并将有效数据保存至RxTemp*/ + /*返回值:0,收到完整的数据帧;1,数据帧未接收完成;2,接收数据帧出错*/ public byte Byte_Receive(byte RxData) { switch (RxState) { - case 0: + case 0: //帧头校验 if (RxData == '>') { - sum = RxData; + CheckSum = RxData; RxState = 1; } + else if (RxData == '@') + { + FcnByte = CheckSum = RxData; + RxState = 0x11; + } + else + return 2; //数据帧出错 break; - case 1: - sum += RxData; - FcnWord = RxData; + case 1: //功能字校验与保存 + CheckSum += RxData; + FcnByte = RxData; RxState = 2; break; - case 2: + case 2: //数据长度校验与保存 if (RxData <= 12) { - sum += RxData; - LenWord = RxData; + CheckSum += RxData; + LenByte = RxData; RxState = 3; } else { - sum = 0; + CheckSum = 0; RxState = 0; + return 2; //数据帧出错 } break; case 3: //临时保存待用数据 - sum += RxData; - DataReceived[p++] = RxData; - if (p >= LenWord) - RxState = 4; - else if (p >= 12) - RxState = 5; + CheckSum += RxData; + DataReceived[cnt++] = RxData; + if (cnt >= LenByte) + RxState = 0x0A; + break; + case 0x11: //临时保存待用数据 + CheckSum += RxData; + DataReceived[cnt++] = RxData; + if (cnt >= 4) + RxState = 0x0A; break; - case 4: //匹配校验和 + case 0x0A: RxState = 0; - p = 0; - if (sum == RxData) //收到了正确的数据帧 - return 0; + cnt = 0; + if (CheckSum == RxData) + return 0; //收到了正确的数据帧 else - return 2; + return 2; //数据帧出错 default: - p = 0; + cnt = 0; RxState = 0; - break; + return 2; //数据帧出错 } - return 1; + return 1; //数据帧尚未接收完成 } /*********************** 发送解锁帧 @@ -90,7 +102,7 @@ public byte Send_Cmd(byte state, Action SerialWrite) **********************/ public byte Send_S16_Data(int[] data, byte len, byte fcn, Action SerialWrite) { - byte i, cnt = 0, checksum = 0; + byte i, cnt = 0, sum = 0; DataToSend[cnt++] = 0x3C; DataToSend[cnt++] = fcn; DataToSend[cnt++] = (byte)(len * 2); @@ -100,8 +112,8 @@ public byte Send_S16_Data(int[] data, byte len, byte fcn, Action Se DataToSend[cnt++] = (byte)(data[i] % 256); } for (i = 0; i < cnt; i++) - checksum += DataToSend[i]; - DataToSend[cnt++] = checksum; + sum += DataToSend[i]; + DataToSend[cnt++] = sum; SerialWrite(DataToSend, cnt); return cnt; } @@ -110,15 +122,15 @@ public byte Send_S16_Data(int[] data, byte len, byte fcn, Action Se **********************/ public byte Send_U8_Data(byte[] data, byte len, byte fcn, Action SerialWrite) { - byte i, cnt = 0, checksum = 0; + byte i, cnt = 0, sum = 0; DataToSend[cnt++] = 0x3C; DataToSend[cnt++] = fcn; DataToSend[cnt++] = len; for (i = 0; i < len; i++) DataToSend[cnt++] = data[i]; for (i = 0; i < cnt; i++) - checksum += DataToSend[i]; - DataToSend[cnt++] = checksum; + sum += DataToSend[i]; + DataToSend[cnt++] = sum; SerialWrite(DataToSend, cnt); return cnt; } diff --git a/image/GS_base.png b/image/GS_base.png new file mode 100644 index 0000000..9fc1a4c Binary files /dev/null and b/image/GS_base.png differ diff --git a/image/GS_chart.png b/image/GS_chart.png new file mode 100644 index 0000000..7bb627e Binary files /dev/null and b/image/GS_chart.png differ diff --git a/image/GS_ctrl.png b/image/GS_ctrl.png new file mode 100644 index 0000000..44442e1 Binary files /dev/null and b/image/GS_ctrl.png differ diff --git a/image/GS_param.png b/image/GS_param.png new file mode 100644 index 0000000..edab82f Binary files /dev/null and b/image/GS_param.png differ diff --git a/logo.jpg b/logo.jpg deleted file mode 100644 index a746c9d..0000000 Binary files a/logo.jpg and /dev/null differ diff --git a/readme.md b/readme.md index 4401aaf..b18d678 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,7 @@ -# 西电航协微型四轴ADRC版本地面站 +# 西电航协地面站PC端 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/090e9b44b3934c0483ee238f9ae0fdff)](https://app.codacy.com/gh/xdu-aero-association/GroundStation?utm_source=github.com&utm_medium=referral&utm_content=xdu-aero-association/GroundStation&utm_campaign=Badge_Grade_Dashboard) -![logo](https://github.com/xdu-aero-association/GroundStation/raw/master/logo.jpg) - ## Status ![stars](https://img.shields.io/github/stars/xdu-aero-association/GroundStation.svg) ![forks](https://img.shields.io/github/forks/xdu-aero-association/GroundStation.svg) ![tag](https://img.shields.io/github/tag/xdu-aero-association/GroundStation.svg) ![release](https://img.shields.io/github/release/xdu-aero-association/GroundStation.svg) ![issues](https://img.shields.io/github/issues/xdu-aero-association/GroundStation.svg) @@ -12,62 +10,71 @@ 这是西电航协微型四轴飞行器ADRC版本飞控端的上位机源代码,该版本与PID版本串口通讯协议不同,因此不适用于PID版本的代码。 -这是一个[Visual Studio 2019](https://visualstudio.microsoft.com/zh-hans/vs/)工程,打开最新版Visual Studio 2019导入工程文件或双击sln工程文件即可打开该工程源码。 +这是一个[Visual Studio 2019](https://visualstudio.microsoft.com/zh-hans/vs/) 工程,打开最新版Visual Studio 2019导入工程文件或双击sln工程文件即可打开该工程源码。 -该项目目前出于待完成阶段,非制作人员勿克隆master分支源码 +该项目已经基本完成,正在持续维护中。 修改代码的时候,请在master分支下面新建一个特性分支,在该特性分支下进行代码的修改然后通过该分支执行pull request操作。确认无误后再合并至主分支。 bug相关和建议请移步至issue栏目 -## 使用说明 +# 使用说明 + +c#上位机 + +版本 v1.04 有基本收发、飞行控制、参数设置、波形显示4个标签。 可自动识别可用端口号。 -[飞行器控制示例](https://github.com/xdu-aero-association/Drone_Master_ADRC) +部分内容关闭重启后不会丢失。 + +[飞行器控制示例](https://github.com/xd15zhn/drone) ### 基本收发 +![基本收发](./image/GS_base.png) + 3个发送窗口独立。第一个支持定时发送。前两个为多行,第三个为单行。 +3个发送窗口的内容在关闭重启后不会丢失。 + ### 飞行控制 -发送切换模式指令时同步发送锁定指令。 +![飞行控制](./image/GS_ctrl.png) -有2种方法可以进行飞行控制。 +飞机解锁流程: -第一种是在切换到'飞行控制'标签下用键盘WSAD和IKJL进行飞行控制; +打开主串口->传感器校准(可选)->打开外部输入串口(可选)->将油门通道拨到底->点击"开始发送“->点击"解锁“ -第二种是符合协议的外部串口输入,可使用处理器将遥控器接收机的PWM信号转换成串口数据通过'飞行控制'标签下的串口输入。 +发送切换模式指令时同步发送锁定指令。 +有2种方法可以进行飞行控制。第一种是用键盘WSAD和IKJL进行飞行控制; +第二种是符合协议的外部串口输入,可使用处理器将遥控器接收机的PWM信号转换成串口数据通过'飞行控制'标签下的串口输入。 第二种方法优先于第一种。 -点击"建立控制链路"按钮开始以100ms间隔发送遥控帧,如果收到正确的帧则飞行状态显示"控制中"。 +### 参数设置 -锁定/解锁与飞行模式切换均需要正确的密码。 +![参数设置](./image/GS_param.png) -解锁前需要建立控制链路。 +一般地,控制器参数传输值是参数真实值的1000倍(一般为0.几至几),状态参数传输值是参数真实值的100倍(一般为几至几十)。 -发送切换模式指令时同步发送锁定指令。 - -### 参数设置 +右边为文本框,可自由输入,关闭重启后不会丢失。 -参数名称为自定义,重启软件所有名称不会丢失。 +写入参数后建议重新读取以检查是否成功写入。 -点击读取参数按钮会将从下位机收到的参数读取至文本框中,点击写入参数会将从下位机收到的参数展示到旁边。 - -一般地,控制器参数传输值是参数真实值的1000倍(一般为0.几至几),状态参数传输值是参数真实值的100倍(一般为几至几十), -其它参数保持原值。 +左下角写入文件用于接收高速数据并直接将数据写入文件。 ### 波形显示 -波形显示的数据与'参数设置'标签中的状态参数相同。 +![波形显示](./image/GS_chart.png) + +注意右下角"开始显示"复选框。 更改选择显示的数据会清空并重新显示。 -## 协议 +# 协议 协议说明: @@ -93,6 +100,7 @@ SUM等于从该数据帧第一字节开始,也就是帧头开始,至该帧 |遥控命令|3E |AA |08 |s16×4 |SUM |遥控器4个通道的控制信号| |波形1 |3E |B1 |08 |s16×4 |SUM |波形显示通道1~4| |波形2 |3E |B2 |08 |s16×4 |SUM |波形显示通道5~8| +|系统辨识|40 |- |- |s16×2 |SUM |系统辨识所用输入与输出数据| |- |BIT7|BIT6|BIT5 |BIT4|BIT3|BIT2|BIT1|BIT0| |- |- |- |- |- |- |- |- |- | @@ -102,18 +110,21 @@ SUM等于从该数据帧第一字节开始,也就是帧头开始,至该帧 注:功能字AA为外部遥控信号输入,来自于与其它数据帧不同的串口。 +40数据帧用于发送高速高精度数据,没有功能和长度字节 + ### 地面站->飞控 |帧名称 |帧头|功能字|长度|数据 |校验|备注| |- |- |- |- |- |- |- | |状态 |3C |01 |01 |u8×1 |SUM |指令(stat)| -|遥控 |3C |08 |08 |s16×4|SUM |遥控器4个通道的控制信号| +|遥控 |3C |08 |08 |s16×4|SUM |发送遥控器4个通道的控制信号| |ROL参数|3C |A1 |08 |s16×8|SUM |写入ROL通道控制器参数×1000| |PIT参数|3C |A2 |08 |s16×8|SUM |写入PIT通道控制器参数×1000| |YAW参数|3C |A3 |08 |s16×8|SUM |写入YAW和THR通道控制器参数×1000| |读参数1|3C |C1 |01 |u8×1 |SUM |请求读取飞行参数(req1)| |读参数2|3C |C2 |01 |u8×1 |SUM |请求校准传感器与读取控制器参数(req2)| |读参数3|3C |C3 |01 |u8×1 |SUM |请求读取参数用于显示波形(req3)| +|读参数4|3C |C4 |01 |u8×1 |SUM |请求读取系统辨识所用数据(reg4)| |- |BIT7 |BIT6 |BIT5 |BIT4 |BIT3 |BIT2 |BIT1 |BIT0 | |- |- |- |- |- |- |- |- |- | @@ -121,23 +132,26 @@ SUM等于从该数据帧第一字节开始,也就是帧头开始,至该帧 |req1|- |- |四元数|油门 |遥控 |传感器|姿态 |状态 | |req2|陀螺仪校准|加计校准|- |- |- |Y参数 |P参数|R参数| |req3|- |- |- |- |- |- |- |- | +|req4|- |- |- |- |- |- |位置1|位置0| -示例: 3C 01 01 01 3F 表示请求解锁 +示例: 3C 01 01 41 7F 表示请求解锁并设置为姿态模式 -注: +注:stat的BIT7和BIT6为10时设置为速度模式,为01时设置为姿态模式,其它情况无效。 -stat的BIT7和BIT6为10时设置为速度模式,为01时设置为姿态模式,其它情况无效。 +# 开发人员须知。 -req3用于波形显示。 +### 飞行控制 -## 地面站收发具体内容 +点击"开始发送"按钮开始以100ms间隔发送遥控帧。 -开发人员须知。 +### 版本更新 -## 其它注意事项 +* 更改波形显示颜色。 -* 使用蓝牙串口时存在部分延迟卡顿等问题 +* 更改图表刷新方法使数据更新与图表刷新异步,避免卡顿。 -## BUG +# 其它注意事项 -* 使用蓝牙串口时存在部分延迟卡顿等问题 +* 使用蓝牙串口时存在部分延迟卡顿等问题,因此强烈建议在使用结束后, +先断开串口或直接关闭地面站,然后再断开下位机电源。 +使用USB转TTL模块则不用考虑此问题。