Subversion Repositories Projects

Rev

Rev 2250 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2250 Rev 2254
1
///============================================================================
1
///============================================================================
2
/// MKLiveView 
2
/// MKLiveView 
3
/// Copyright © 2016 Steph
3
/// Copyright © 2016 Steph
4
/// 
4
/// 
5
///This file is part of MKLiveView.
5
///This file is part of MKLiveView.
6
///
6
///
7
///MKLiveView is free software: you can redistribute it and/or modify
7
///MKLiveView is free software: you can redistribute it and/or modify
8
///it under the terms of the GNU General Public License as published by
8
///it under the terms of the GNU General Public License as published by
9
///the Free Software Foundation, either version 3 of the License, or
9
///the Free Software Foundation, either version 3 of the License, or
10
///(at your option) any later version.
10
///(at your option) any later version.
11
///
11
///
12
///MKLiveView is distributed in the hope that it will be useful,
12
///MKLiveView is distributed in the hope that it will be useful,
13
///but WITHOUT ANY WARRANTY; without even the implied warranty of
13
///but WITHOUT ANY WARRANTY; without even the implied warranty of
14
///MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
///MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
///GNU General Public License for more details.
15
///GNU General Public License for more details.
16
///
16
///
17
///You should have received a copy of the GNU General Public License
17
///You should have received a copy of the GNU General Public License
18
///along with cssRcon.  If not, see <http://www.gnu.org/licenses/>.
18
///along with cssRcon.  If not, see <http://www.gnu.org/licenses/>.
19
///
19
///
20
///============================================================================
20
///============================================================================
21
///Credits:
21
///Credits:
22
///Chootair (http://www.codeproject.com/script/Membership/View.aspx?mid=3941737)
22
///Chootair (http://www.codeproject.com/script/Membership/View.aspx?mid=3941737)
23
///for his "C# Avionic Instrument Controls" (http://www.codeproject.com/Articles/27411/C-Avionic-Instrument-Controls)
23
///for his "C# Avionic Instrument Controls" (http://www.codeproject.com/Articles/27411/C-Avionic-Instrument-Controls)
24
///I used some of his code for displaying the compass 
24
///I used some of his code for displaying the compass 
25
///
25
///
26
///Tom Pyke (http://tom.pycke.be)
26
///Tom Pyke (http://tom.pycke.be)
27
///for his "Artifical horizon" (http://tom.pycke.be/mav/100/artificial-horizon)
27
///for his "Artifical horizon" (http://tom.pycke.be/mav/100/artificial-horizon)
28
///Great job!
28
///Great job!
29
///
29
///
30
/// and last but most of all to JOHN C. MACDONALD at Ira A. Fulton College of Engineering and Technology
30
/// and last but most of all to JOHN C. MACDONALD at Ira A. Fulton College of Engineering and Technology
31
/// for his MIKROKOPTER SERIAL CONTROL TUTORIAL (http://hdl.lib.byu.edu/1877/2747)
31
/// for his MIKROKOPTER SERIAL CONTROL TUTORIAL (http://hdl.lib.byu.edu/1877/2747)
32
/// and the sourcode (http://hdl.lib.byu.edu/1877/2748)
32
/// and the sourcode (http://hdl.lib.byu.edu/1877/2748)
33
/// By his work I finally managed to get the communication with the Mikrokopter controllers to run
33
/// By his work I finally managed to get the communication with the Mikrokopter controllers to run
34
/// Some of his code was used in this programm like the SimpelSerialPort class (with some changes)
34
/// Some of his code was used in this programm like the SimpelSerialPort class (with some changes)
35
/// and the FilghtControllerMessage class
35
/// and the FilghtControllerMessage class
36
/// 
36
/// 
37
///============================================================================
37
///============================================================================
38
 
38
 
39
using System;
39
using System;
40
using System.Data;
40
using System.Data;
41
using System.Drawing;
41
using System.Drawing;
42
using System.Text;
42
using System.Text;
43
using System.Windows.Forms;
43
using System.Windows.Forms;
44
using System.IO;
44
using System.IO;
45
using System.Threading;
45
using System.Threading;
46
using System.Diagnostics;
46
using System.Diagnostics;
47
using System.Runtime.InteropServices;
47
using System.Runtime.InteropServices;
48
 
48
 
49
namespace MKLiveView
49
namespace MKLiveView
50
{
50
{
51
    public partial class MainForm : Form
51
    public partial class MainForm : Form
52
    {
52
    {
53
        String[] NC_Error = new string[44]
53
        String[] NC_Error = new string[44]
54
        {
54
        {
55
            "No Error",
55
            "No Error",
56
            "FC not compatible" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A1_.22FC_not_compatible_.22",
56
            "FC not compatible" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A1_.22FC_not_compatible_.22",
57
            "MK3Mag not compatible" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A2_.22MK3Mag_not_compatible_.22",
57
            "MK3Mag not compatible" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A2_.22MK3Mag_not_compatible_.22",
58
            "no FC communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A3_.22no_FC_communication_.22",
58
            "no FC communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A3_.22no_FC_communication_.22",
59
            "no compass communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A4_.22no_compass_communication_.22",
59
            "no compass communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A4_.22no_compass_communication_.22",
60
            "no GPS communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A5_.22no_GPS_communication_.22",
60
            "no GPS communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A5_.22no_GPS_communication_.22",
61
            "bad compass value" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A6_.22bad_compass_value.22",
61
            "bad compass value" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A6_.22bad_compass_value.22",
62
            "RC Signal lost" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A7_.22RC_Signal_lost_.22",
62
            "RC Signal lost" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A7_.22RC_Signal_lost_.22",
63
            "FC spi rx error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A8_.22FC_spi_rx_error_.22",
63
            "FC spi rx error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A8_.22FC_spi_rx_error_.22",
64
            "ERR: no NC communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A9:_.22ERR:_no_NC_communication.22",
64
            "ERR: no NC communication" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A9:_.22ERR:_no_NC_communication.22",
65
            "ERR: FC Nick Gyro" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A10_.22ERR:_FC_Nick_Gyro.22",
65
            "ERR: FC Nick Gyro" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A10_.22ERR:_FC_Nick_Gyro.22",
66
            "ERR: FC Roll Gyro" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A11_.22ERR:_FC_Roll_Gyro.22",
66
            "ERR: FC Roll Gyro" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A11_.22ERR:_FC_Roll_Gyro.22",
67
            "ERR: FC Yaw Gyro" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A12_.22ERR:_FC_Yaw_Gyro.22",
67
            "ERR: FC Yaw Gyro" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A12_.22ERR:_FC_Yaw_Gyro.22",
68
            "ERR: FC Nick ACC" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A13_.22ERR:_FC_Nick_ACC.22",
68
            "ERR: FC Nick ACC" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A13_.22ERR:_FC_Nick_ACC.22",
69
            "ERR: FC Roll ACC" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A14_.22ERR:_FC_Roll_ACC.22",
69
            "ERR: FC Roll ACC" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A14_.22ERR:_FC_Roll_ACC.22",
70
            "ERR: FC Z-ACC" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A15_.22ERR:_FC_Z-ACC.22",
70
            "ERR: FC Z-ACC" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A15_.22ERR:_FC_Z-ACC.22",
71
            "ERR: Pressure sensor" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A16_.22ERR:_Pressure_sensor.22",
71
            "ERR: Pressure sensor" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A16_.22ERR:_Pressure_sensor.22",
72
            "ERR: FC I2C" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A17_.22ERR:_FC_I2C.22",
72
            "ERR: FC I2C" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A17_.22ERR:_FC_I2C.22",
73
            "ERR: Bl Missing" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A18_.22ERR:_Bl_Missing.22",
73
            "ERR: Bl Missing" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A18_.22ERR:_Bl_Missing.22",
74
            "Mixer Error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A19_.22Mixer_Error.22",
74
            "Mixer Error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A19_.22Mixer_Error.22",
75
            "FC: Carefree Error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A20_.22FC:_Carefree_Error.22",
75
            "FC: Carefree Error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A20_.22FC:_Carefree_Error.22",
76
            "ERR: GPS lost" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A21_.22ERR:_GPS_lost.22",
76
            "ERR: GPS lost" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A21_.22ERR:_GPS_lost.22",
77
            "ERR: Magnet Error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A22_.22ERR:_Magnet_Error.22",
77
            "ERR: Magnet Error" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A22_.22ERR:_Magnet_Error.22",
78
            "Motor restart" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A23_.22Motor_restart.22",
78
            "Motor restart" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A23_.22Motor_restart.22",
79
            "BL Limitation" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A24_.22BL_Limitation.22",
79
            "BL Limitation" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A24_.22BL_Limitation.22",
80
            "Waypoint range" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A25_.22Waypoint_range.22",
80
            "Waypoint range" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A25_.22Waypoint_range.22",
81
            "ERR:No SD-Card" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A26_.22ERR:No_SD-Card.22",
81
            "ERR:No SD-Card" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A26_.22ERR:No_SD-Card.22",
82
            "ERR:SD Logging aborted" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A27_.22ERR:SD_Logging_aborted.22",
82
            "ERR:SD Logging aborted" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A27_.22ERR:SD_Logging_aborted.22",
83
            "ERR:Flying range!" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A28_.22ERR:Flying_range.21.22",
83
            "ERR:Flying range!" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A28_.22ERR:Flying_range.21.22",
84
            "ERR:Max Altitude" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A29_.22ERR:Max_Altitude.22",
84
            "ERR:Max Altitude" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A29_.22ERR:Max_Altitude.22",
85
            "No GPS Fix" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A30_.22No_GPS_Fix.22",
85
            "No GPS Fix" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A30_.22No_GPS_Fix.22",
86
            "compass not calibrated" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A31_.22compass_not_calibrated.22",
86
            "compass not calibrated" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A31_.22compass_not_calibrated.22",
87
            "ERR:BL selftest" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A32_.22ERR:BL_selftest.22",
87
            "ERR:BL selftest" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A32_.22ERR:BL_selftest.22",
88
            "no ext. compass" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A33_.22no_ext._compass.22",
88
            "no ext. compass" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A33_.22no_ext._compass.22",
89
            "compass sensor" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A34_.22compass_sensor.22",
89
            "compass sensor" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A34_.22compass_sensor.22",
90
            "FAILSAFE pos.!" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A35_.22FAILSAFE_pos..21__.22",
90
            "FAILSAFE pos.!" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A35_.22FAILSAFE_pos..21__.22",
91
            "ERR:Redundancy" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A36_.22ERR:Redundancy__.22",
91
            "ERR:Redundancy" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A36_.22ERR:Redundancy__.22",
92
            "Redundancy test" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A37_.22Redundancy_test_.22",
92
            "Redundancy test" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A37_.22Redundancy_test_.22",
93
            "GPS Update rate" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A38_.22GPS_Update_rate.22",
93
            "GPS Update rate" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A38_.22GPS_Update_rate.22",
94
            "ERR:Canbus" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A39_.22ERR:Canbus.22",
94
            "ERR:Canbus" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A39_.22ERR:Canbus.22",
95
            "ERR: 5V RC-Supply" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A40_.22ERR:_5V_RC-Supply.22",
95
            "ERR: 5V RC-Supply" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A40_.22ERR:_5V_RC-Supply.22",
96
            "ERR:Power-Supply" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A41_.22ERR:Power-Supply.22",
96
            "ERR:Power-Supply" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A41_.22ERR:Power-Supply.22",
97
            "ACC not calibr." + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A42_.22ACC_not_calibr..22",
97
            "ACC not calibr." + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A42_.22ACC_not_calibr..22",
98
            "ERR:Parachute!" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A43_.22ERR:Parachute.21.22"
98
            "ERR:Parachute!" + Environment.NewLine + "http://wiki.mikrokopter.de/ErrorCodes#A43_.22ERR:Parachute.21.22"
99
        };
99
        };
100
 
100
 
101
        [FlagsAttribute]
101
        [FlagsAttribute]
102
        enum NC_HWError0 : short
102
        enum NC_HWError0 : short
103
        {
103
        {
104
            None = 0,
104
            None = 0,
105
            SPI_RX = 1,
105
            SPI_RX = 1,
106
            COMPASS_RX = 2,
106
            COMPASS_RX = 2,
107
            FC_INCOMPATIBLE = 4,
107
            FC_INCOMPATIBLE = 4,
108
            COMPASS_INCOMPATIBLE = 8,
108
            COMPASS_INCOMPATIBLE = 8,
109
            GPS_RX = 16,
109
            GPS_RX = 16,
110
            COMPASS_VALUE = 32
110
            COMPASS_VALUE = 32
111
        };
111
        };
112
        [FlagsAttribute]
112
        [FlagsAttribute]
113
        enum FC_HWError0 : short
113
        enum FC_HWError0 : short
114
        {
114
        {
115
            None = 0,
115
            None = 0,
116
            GYRO_NICK = 1,
116
            GYRO_NICK = 1,
117
            GYRO_ROLL = 2,
117
            GYRO_ROLL = 2,
118
            GYRO_YAW = 4,
118
            GYRO_YAW = 4,
119
            ACC_NICK = 8,
119
            ACC_NICK = 8,
120
            ACC_ROLL = 16,
120
            ACC_ROLL = 16,
121
            ACC_TOP = 32,
121
            ACC_TOP = 32,
122
            PRESSURE = 64,
122
            PRESSURE = 64,
123
            CAREFREE = 128
123
            CAREFREE = 128
124
        };
124
        };
125
        [FlagsAttribute]
125
        [FlagsAttribute]
126
        enum FC_HWError1 : short
126
        enum FC_HWError1 : short
127
        {
127
        {
128
            None = 0,
128
            None = 0,
129
            I2C = 1,
129
            I2C = 1,
130
            BL_MISSING = 2,
130
            BL_MISSING = 2,
131
            SPI_RX = 4,
131
            SPI_RX = 4,
132
            PPM = 8,
132
            PPM = 8,
133
            MIXER = 16,
133
            MIXER = 16,
134
            RC_VOLTAGE = 32,
134
            RC_VOLTAGE = 32,
135
            ACC_NOT_CAL = 64,
135
            ACC_NOT_CAL = 64,
136
            RES3 = 128
136
            RES3 = 128
137
        };
137
        };
138
        public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
138
        public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
139
        // Various colors for logging info
139
        // Various colors for logging info
140
        private Color[] LogMsgTypeColor = { Color.FromArgb(43, 145, 175), Color.Green, Color.Black, Color.Orange, Color.Red };
140
        private Color[] LogMsgTypeColor = { Color.FromArgb(43, 145, 175), Color.Green, Color.Black, Color.Orange, Color.Red };
141
 
141
 
142
        string[] sAnalogLabel = new string[32];
142
        string[] sAnalogLabel = new string[32];
143
        string[] sAnalogData = new string[32];
143
        string[] sAnalogData = new string[32];
144
        bool bReadContinously = false;
144
        bool bReadContinously = false;
145
        bool check_HWError = false;
145
        bool check_HWError = false;
146
        bool _bCBInit = true;
146
        bool _bCBInit = true;
147
        bool _init = true;
147
        bool _init = true;
148
        bool _debugDataAutorefresh = true;
148
        bool _debugDataAutorefresh = true;
149
        bool _navCtrlDataAutorefresh = true;
149
        bool _navCtrlDataAutorefresh = true;
150
        bool _blctrlDataAutorefresh = true;
150
        bool _blctrlDataAutorefresh = true;
151
        bool _OSDAutorefresh = true;
151
        bool _OSDAutorefresh = true;
-
 
152
        bool _bErrorLog = false;
152
        int crcError = 0;
153
        int crcError = 0;
153
        int iLableIndex = 0;
154
        int iLableIndex = 0;
154
        string filePath = Directory.GetCurrentDirectory();
155
        string filePath = Directory.GetCurrentDirectory();
155
        string fileName = "NCLabelTexts.txt";
156
        string fileName = "NCLabelTexts.txt";
156
        int _iCtrlAct = 0;
157
        int _iCtrlAct = 0;
157
        int _iLifeCounter = 0;
158
        int _iLifeCounter = 0;
158
        int iOSDPage = 0;
159
        int iOSDPage = 0;
159
        int iOSDMax = 0;
160
        int iOSDMax = 0;
160
        /// <summary>
161
        /// <summary>
161
        /// interval for sending debugdata (multiplied by 10ms)
162
        /// interval for sending debugdata (multiplied by 10ms)
162
        /// </summary>
163
        /// </summary>
163
        byte debugInterval = 25; //(=> 250ms)
164
        byte debugInterval = 25; //(=> 250ms)
164
        /// <summary>
165
        /// <summary>
165
        /// interval for sending BL-CTRL status (multiplied by 10ms)
166
        /// interval for sending BL-CTRL status (multiplied by 10ms)
166
        /// </summary>
167
        /// </summary>
167
        byte blctrlInterval = 45;
168
        byte blctrlInterval = 45;
168
        /// <summary>
169
        /// <summary>
169
        /// interval for sending NAV-CTRL status (multiplied by 10ms)
170
        /// interval for sending NAV-CTRL status (multiplied by 10ms)
170
        /// </summary>
171
        /// </summary>
171
        byte navctrlInterval = 80;
172
        byte navctrlInterval = 80;
172
        /// <summary>
173
        /// <summary>
173
        /// interval for sending OSD page update (multiplied by 10ms)
174
        /// interval for sending OSD page update (multiplied by 10ms)
174
        /// </summary>
175
        /// </summary>
175
        byte OSDInterval = 85;
176
        byte OSDInterval = 85;
176
        /// <summary>
177
        /// <summary>
177
        /// datatable for the debug data array - displayed on settings tabpage in datagridview
178
        /// datatable for the debug data array - displayed on settings tabpage in datagridview
178
        /// </summary>
179
        /// </summary>
179
        DataTable dtAnalog = new DataTable();
180
        DataTable dtAnalog = new DataTable();
180
 
-
 
-
 
181
        /// <summary>
-
 
182
        /// datatable for motordata (current,temp)
-
 
183
        /// </summary>
181
        DataTable dtMotors1 = new DataTable();
184
        DataTable dtMotors1 = new DataTable();
182
        DataTable dtMotors2 = new DataTable();
185
        DataTable dtMotors2 = new DataTable();
183
 
186
 
184
        public MainForm()
187
        public MainForm()
185
        {
188
        {
186
            InitializeComponent();
189
            InitializeComponent();
187
            _readIni();
190
            _readIni();
188
            dtAnalog.Columns.Add("ID");
191
            dtAnalog.Columns.Add("ID");
189
            dtAnalog.Columns.Add("Value");
192
            dtAnalog.Columns.Add("Value");
190
            dataGridView1.DataSource = dtAnalog;
193
            dataGridView1.DataSource = dtAnalog;
191
            dtMotors1.Columns.Add("#");
194
            dtMotors1.Columns.Add("#");
192
            dtMotors1.Columns.Add("Current");
195
            dtMotors1.Columns.Add("Current");
193
            dtMotors1.Columns.Add("Temp");
196
            dtMotors1.Columns.Add("Temp");
194
            dtMotors2.Columns.Add("#");
197
            dtMotors2.Columns.Add("#");
195
            dtMotors2.Columns.Add("Current");
198
            dtMotors2.Columns.Add("Current");
196
            dtMotors2.Columns.Add("Temp");
199
            dtMotors2.Columns.Add("Temp");
197
            dgvMotors1.DataSource = dtMotors1;
200
            dgvMotors1.DataSource = dtMotors1;
198
            dgvMotors2.DataSource = dtMotors2;
201
            dgvMotors2.DataSource = dtMotors2;
199
            _initDTMotors();
202
            _initDTMotors();
200
            dgvMotors1.Columns[0].Width = 24;
203
            dgvMotors1.Columns[0].Width = 24;
201
            dgvMotors1.Columns[1].Width = 74;
204
            dgvMotors1.Columns[1].Width = 74;
202
            dgvMotors1.Columns[2].Width = 74;
205
            dgvMotors1.Columns[2].Width = 74;
203
            dgvMotors2.Columns[0].Width = 24;
206
            dgvMotors2.Columns[0].Width = 24;
204
            dgvMotors2.Columns[1].Width = 74;
207
            dgvMotors2.Columns[1].Width = 74;
205
            dgvMotors2.Columns[2].Width = 74;
208
            dgvMotors2.Columns[2].Width = 74;
206
            simpleSerialPort.PortClosed += SimpleSerialPort_PortClosed;
209
            simpleSerialPort.PortClosed += SimpleSerialPort_PortClosed;
207
            simpleSerialPort.PortOpened += SimpleSerialPort_PortOpened;
210
            simpleSerialPort.PortOpened += SimpleSerialPort_PortOpened;
208
            simpleSerialPort.DataReceived += processMessage;
211
            simpleSerialPort.DataReceived += processMessage;
209
            chkbAutoBL.Checked = _blctrlDataAutorefresh;
212
            chkbAutoBL.Checked = _blctrlDataAutorefresh;
210
            chkbAutoDbg.Checked = _debugDataAutorefresh;
213
            chkbAutoDbg.Checked = _debugDataAutorefresh;
211
            chkbAutoNav.Checked = _navCtrlDataAutorefresh;
214
            chkbAutoNav.Checked = _navCtrlDataAutorefresh;
212
            chkbAutoOSD.Checked = _OSDAutorefresh;
215
            chkbAutoOSD.Checked = _OSDAutorefresh;
213
            labelTimingDebug.Text = (debugInterval * 10).ToString();
216
            labelTimingDebug.Text = (debugInterval * 10).ToString();
214
            labelTimingBLCTRL.Text = (blctrlInterval * 10).ToString();
217
            labelTimingBLCTRL.Text = (blctrlInterval * 10).ToString();
215
            labelTimingNAV.Text = (navctrlInterval * 10).ToString();
218
            labelTimingNAV.Text = (navctrlInterval * 10).ToString();
216
            labelTimingOSD.Text = (OSDInterval * 10).ToString();
219
            labelTimingOSD.Text = (OSDInterval * 10).ToString();
217
            tabControl1.TabPages.Remove(tabPageTesting);
220
            tabControl1.TabPages.Remove(tabPageTesting);
218
        }
221
        }
219
        #region events
222
        #region events
220
        private void MainForm_Shown(object sender, EventArgs e)
223
        private void MainForm_Shown(object sender, EventArgs e)
221
        {
224
        {
222
            _loadLabelNames();
225
            _loadLabelNames();
223
            _init = false;
226
            _init = false;
224
            splitContainer1.SplitterDistance = 514;
227
            splitContainer1.SplitterDistance = 514;
225
        }
228
        }
226
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
229
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
227
        {
230
        {
228
            _writeIni();
231
            _writeIni();
229
        }
232
        }
230
        private void SimpleSerialPort_PortOpened()
233
        private void SimpleSerialPort_PortOpened()
231
        {
234
        {
232
            btnConn.Invoke((Action)(() => btnConn.BackColor = Color.FromArgb(192, 255, 192)));
235
            btnConn.Invoke((Action)(() => btnConn.BackColor = Color.FromArgb(192, 255, 192)));
233
            btnConn.Invoke((Action)(() => btnConn.Text = "close" + Environment.NewLine + "serial port"));
236
            btnConn.Invoke((Action)(() => btnConn.Text = "close" + Environment.NewLine + "serial port"));
234
            _getVersion();
237
            _getVersion();
235
            Thread.Sleep(100);
238
            Thread.Sleep(100);
236
            _OSDMenue(0);
239
            _OSDMenue(0);
237
           // _readCont(true);
240
           // _readCont(true);
238
        }
241
        }
239
        private void SimpleSerialPort_PortClosed()
242
        private void SimpleSerialPort_PortClosed()
240
        {
243
        {
241
            btnConn.Invoke((Action)(() => btnConn.BackColor = Color.FromArgb(224, 224, 224)));
244
            btnConn.Invoke((Action)(() => btnConn.BackColor = Color.FromArgb(224, 224, 224)));
242
            btnConn.Invoke((Action)(() => btnConn.Text = "open" + Environment.NewLine + "serial port"));
245
            btnConn.Invoke((Action)(() => btnConn.Text = "open" + Environment.NewLine + "serial port"));
243
            _readCont(false);
246
            _readCont(false);
244
        }
247
        }
245
        /// <summary>
248
        /// <summary>
246
        /// timer for refreshing subscription of subscribed data
249
        /// timer for refreshing subscription of subscribed data
247
        /// query lifecounter for connection failure
250
        /// query lifecounter for connection failure
248
        /// </summary>
251
        /// </summary>
249
        private void timer1_Tick(object sender, EventArgs e)
252
        private void timer1_Tick(object sender, EventArgs e)
250
        {
253
        {
251
            if(bReadContinously)
254
            if(bReadContinously)
252
            {
255
            {
253
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
256
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
254
 
257
 
255
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
258
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
256
               
259
               
257
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
260
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
258
                check_HWError = true;
261
                check_HWError = true;
259
                _getVersion();
262
                _getVersion();
260
                Thread.Sleep(10);
263
                Thread.Sleep(10);
261
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); }
264
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); }
262
                if (_iLifeCounter > 0)
265
                if (_iLifeCounter > 0)
263
                {
266
                {
264
                    lblLifeCounter.BackColor = Color.FromArgb(0, 224, 0);
267
                    lblLifeCounter.BackColor = Color.FromArgb(0, 224, 0);
265
                    _iLifeCounter = 0;
268
                    _iLifeCounter = 0;
266
                }
269
                }
267
                else
270
                else
268
                {
271
                {
269
                    Log(LogMsgType.Error, "No communication to NC/FC!");
272
                    Log(LogMsgType.Error, "No communication to NC/FC!");
270
                    lblLifeCounter.BackColor = Color.FromArgb(224, 0, 0);
273
                    lblLifeCounter.BackColor = Color.FromArgb(224, 0, 0);
271
                }
274
                }
272
            }
275
            }
273
        }
276
        }
274
        private void cbOSD_SelectedIndexChanged(object sender, EventArgs e)
277
        private void cbOSD_SelectedIndexChanged(object sender, EventArgs e)
275
        {
278
        {
276
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
279
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
277
                _OSDMenue(cbOSD.SelectedIndex);
280
                _OSDMenue(cbOSD.SelectedIndex);
278
        }
281
        }
279
        private void chkbAutoDbg_CheckedChanged(object sender, EventArgs e)
282
        private void chkbAutoDbg_CheckedChanged(object sender, EventArgs e)
280
        {
283
        {
281
            if(!_init) _debugDataAutorefresh = chkbAutoDbg.Checked;
284
            if(!_init) _debugDataAutorefresh = chkbAutoDbg.Checked;
282
        }
285
        }
283
        private void chkbAutoNav_CheckedChanged(object sender, EventArgs e)
286
        private void chkbAutoNav_CheckedChanged(object sender, EventArgs e)
284
        {
287
        {
285
            if (!_init) _navCtrlDataAutorefresh = chkbAutoNav.Checked;
288
            if (!_init) _navCtrlDataAutorefresh = chkbAutoNav.Checked;
286
        }
289
        }
287
        private void chkbAutoBL_CheckedChanged(object sender, EventArgs e)
290
        private void chkbAutoBL_CheckedChanged(object sender, EventArgs e)
288
        {
291
        {
289
            if (!_init) _blctrlDataAutorefresh = chkbAutoBL.Checked;
292
            if (!_init) _blctrlDataAutorefresh = chkbAutoBL.Checked;
290
        }
293
        }
291
        private void chkbAutoOSD_CheckedChanged(object sender, EventArgs e)
294
        private void chkbAutoOSD_CheckedChanged(object sender, EventArgs e)
292
        {
295
        {
293
            if (!_init) _OSDAutorefresh = chkbAutoOSD.Checked;
296
            if (!_init) _OSDAutorefresh = chkbAutoOSD.Checked;
294
        }
297
        }
295
        private void cbTimingDebug_SelectedIndexChanged(object sender, EventArgs e)
298
        private void cbTimingDebug_SelectedIndexChanged(object sender, EventArgs e)
296
        {
299
        {
297
            if (cbTimingDebug.SelectedIndex > -1)
300
            if (cbTimingDebug.SelectedIndex > -1)
298
            {
301
            {
299
                debugInterval = (byte)(Convert.ToInt16(cbTimingDebug.SelectedItem) / 10);
302
                debugInterval = (byte)(Convert.ToInt16(cbTimingDebug.SelectedItem) / 10);
300
                labelTimingDebug.Text = (debugInterval * 10).ToString();
303
                labelTimingDebug.Text = (debugInterval * 10).ToString();
301
            }
304
            }
302
        }
305
        }
303
        private void cbTimingNAV_SelectedIndexChanged(object sender, EventArgs e)
306
        private void cbTimingNAV_SelectedIndexChanged(object sender, EventArgs e)
304
        {
307
        {
305
            if (cbTimingNAV.SelectedIndex > -1)
308
            if (cbTimingNAV.SelectedIndex > -1)
306
            {
309
            {
307
                navctrlInterval = (byte)(Convert.ToInt16(cbTimingNAV.SelectedItem) / 10);
310
                navctrlInterval = (byte)(Convert.ToInt16(cbTimingNAV.SelectedItem) / 10);
308
                labelTimingNAV.Text = (navctrlInterval * 10).ToString();
311
                labelTimingNAV.Text = (navctrlInterval * 10).ToString();
309
            }
312
            }
310
        }
313
        }
311
        private void cbTimingBLCTRL_SelectedIndexChanged(object sender, EventArgs e)
314
        private void cbTimingBLCTRL_SelectedIndexChanged(object sender, EventArgs e)
312
        {
315
        {
313
            if (cbTimingBLCTRL.SelectedIndex > -1)
316
            if (cbTimingBLCTRL.SelectedIndex > -1)
314
            {
317
            {
315
                blctrlInterval = (byte)(Convert.ToInt16(cbTimingBLCTRL.SelectedItem) / 10);
318
                blctrlInterval = (byte)(Convert.ToInt16(cbTimingBLCTRL.SelectedItem) / 10);
316
                labelTimingBLCTRL.Text = (blctrlInterval * 10).ToString();
319
                labelTimingBLCTRL.Text = (blctrlInterval * 10).ToString();
317
            }
320
            }
318
        }
321
        }
319
        private void cbTimingOSD_SelectedIndexChanged(object sender, EventArgs e)
322
        private void cbTimingOSD_SelectedIndexChanged(object sender, EventArgs e)
320
        {
323
        {
321
            if (cbTimingOSD.SelectedIndex > -1)
324
            if (cbTimingOSD.SelectedIndex > -1)
322
            {
325
            {
323
                OSDInterval = (byte)(Convert.ToInt16(cbTimingOSD.SelectedItem) / 10);
326
                OSDInterval = (byte)(Convert.ToInt16(cbTimingOSD.SelectedItem) / 10);
324
                labelTimingOSD.Text = (OSDInterval * 10).ToString();
327
                labelTimingOSD.Text = (OSDInterval * 10).ToString();
325
            }
328
            }
326
        }
329
        }
-
 
330
        private void rtfError_LinkClicked(object sender, LinkClickedEventArgs e)
-
 
331
        {
-
 
332
            System.Diagnostics.Process.Start(e.LinkText);
-
 
333
        }
327
        #endregion events
334
        #endregion events
328
 
335
 
329
        /// <summary> Log data to the terminal window. </summary>
336
        /// <summary> Log data to the terminal window. </summary>
330
        /// <param name="msgtype"> The type of message to be written. </param>
337
        /// <param name="msgtype"> The type of message to be written. </param>
331
        /// <param name="msg"> The string containing the message to be shown. </param>
338
        /// <param name="msg"> The string containing the message to be shown. </param>
332
        private void Log(LogMsgType msgtype, string msg)
339
        private void Log(LogMsgType msgtype, string msg)
333
        {
340
        {
334
            rtfTerminal.Invoke(new EventHandler(delegate
341
            rtfTerminal.Invoke(new EventHandler(delegate
335
            {
342
            {
336
                if (rtfTerminal.Lines.Length >= 1000)   //Wenn Terminal mehr als 1000 Zeilen hat
343
                if (rtfTerminal.Lines.Length >= 1000)   //Wenn Terminal mehr als 1000 Zeilen hat
337
                    rtfTerminal.Select(42, (500 * 129));     //500 löschen
344
                    rtfTerminal.Select(42, (500 * 129));     //500 löschen
338
                rtfTerminal.Select(rtfTerminal.Text.Length, 0);
345
                rtfTerminal.Select(rtfTerminal.Text.Length, 0);
339
                rtfTerminal.SelectedText = string.Empty;
346
                rtfTerminal.SelectedText = string.Empty;
340
                rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont, FontStyle.Regular);
347
                rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont, FontStyle.Regular);
341
                rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
348
                rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
342
                rtfTerminal.AppendText(msg + Environment.NewLine);
349
                rtfTerminal.AppendText(msg + Environment.NewLine);
343
                rtfTerminal.ScrollToCaret();
350
                rtfTerminal.ScrollToCaret();
344
            }));
351
            }));
345
        }
352
        }
346
        /// <summary> display the OSD text in 4 lines à 20 chars </summary>
353
        /// <summary> display the OSD text in 4 lines à 20 chars </summary>
347
        /// <param name="msgtype"> The type of message to be written. </param>
354
        /// <param name="msgtype"> The type of message to be written. </param>
348
        /// <param name="msg"> The string containing the message to be shown. </param>
355
        /// <param name="msg"> The string containing the message to be shown. </param>
349
        private void OSD(LogMsgType msgtype, string msg)
356
        private void OSD(LogMsgType msgtype, string msg)
350
        {
357
        {
351
            rtfOSD.Invoke(new EventHandler(delegate
358
            rtfOSD.Invoke(new EventHandler(delegate
352
            {
359
            {
353
                if (rtfOSD.Lines.Length > 4)
360
                if (rtfOSD.Lines.Length > 4)
354
                    rtfOSD.Clear();
361
                    rtfOSD.Clear();
355
                rtfOSD.Select(rtfOSD.Text.Length,0);
362
                rtfOSD.Select(rtfOSD.Text.Length,0);
356
                rtfOSD.SelectedText = string.Empty;
363
                rtfOSD.SelectedText = string.Empty;
357
                rtfOSD.SelectionFont = new Font(rtfOSD.SelectionFont, FontStyle.Regular);
364
                rtfOSD.SelectionFont = new Font(rtfOSD.SelectionFont, FontStyle.Regular);
358
                rtfOSD.SelectionColor = LogMsgTypeColor[(int)msgtype];
365
                rtfOSD.SelectionColor = LogMsgTypeColor[(int)msgtype];
359
                rtfOSD.AppendText(msg + Environment.NewLine);
366
                rtfOSD.AppendText(msg + Environment.NewLine);
360
                if (rtfOSD.Text.IndexOf("ERR") > 0)
367
                if (rtfOSD.Text.IndexOf("ERR") > 0)
361
                {
368
                {
362
                    rtfOSD.Select(rtfOSD.Text.IndexOf("ERR"), 40);
369
                    rtfOSD.Select(rtfOSD.Text.IndexOf("ERR"), 40);
363
                    rtfOSD.SelectionColor = LogMsgTypeColor[(int)LogMsgType.Error];
370
                    rtfOSD.SelectionColor = LogMsgTypeColor[(int)LogMsgType.Error];
364
                }
371
                }
365
            }));
372
            }));
366
        }
373
        }
367
        private void ErrorLog(LogMsgType msgtype, string msg)
374
        private void ErrorLog(LogMsgType msgtype, string msg)
368
        {
375
        {
369
            rtfError.Invoke(new EventHandler(delegate
376
            rtfError.Invoke(new EventHandler(delegate
370
            {
377
            {
371
                if (rtfError.Lines.Length > 4)
378
                if (rtfError.Lines.Length > 4)
372
                    rtfError.Clear();
379
                    rtfError.Clear();
373
                rtfError.Focus();
380
                rtfError.Focus();
374
                rtfError.Select(rtfError.Text.Length, 0);
381
                rtfError.Select(rtfError.Text.Length, 0);
375
                rtfError.SelectedText = string.Empty;
382
                rtfError.SelectedText = string.Empty;
376
                rtfError.SelectionFont = new Font(rtfError.SelectionFont, FontStyle.Regular);
383
                rtfError.SelectionFont = new Font(rtfError.SelectionFont, FontStyle.Regular);
377
                rtfError.SelectionColor = LogMsgTypeColor[(int)msgtype];
384
                rtfError.SelectionColor = LogMsgTypeColor[(int)msgtype];
378
                rtfError.AppendText(msg + Environment.NewLine);
385
                rtfError.AppendText(msg + Environment.NewLine);
379
               
386
               
380
            }));
387
            }));
-
 
388
            _bErrorLog = true;
381
        }
389
        }
382
 
390
 
383
        #region functions        
391
        #region functions        
384
 
392
 
385
        #region processing received data
393
        #region processing received data
386
        /// <summary> Processing the messages and displaying them in the according form controls 
394
        /// <summary> Processing the messages and displaying them in the according form controls 
387
        /// function called by simpleSerialPort.DataReceived event
395
        /// function called by simpleSerialPort.DataReceived event
388
        /// </summary>
396
        /// </summary>
389
        /// <param name="message"> message bytearray recieved by SimpleSerialPort class </param>
397
        /// <param name="message"> message bytearray recieved by SimpleSerialPort class </param>
390
        private void processMessage(byte[] message)
398
        private void processMessage(byte[] message)
391
        {
399
        {
392
            if (message.Length > 0)
400
            if (message.Length > 0)
393
            {
401
            {
394
                _iLifeCounter++;
402
                _iLifeCounter++;
395
                //Log(LogMsgType.Incoming, BitConverter.ToString(message));
403
                //Log(LogMsgType.Incoming, BitConverter.ToString(message));
396
                //Log(LogMsgType.Incoming, message.Length.ToString());
404
                //Log(LogMsgType.Incoming, message.Length.ToString());
397
                string s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, message.Length));
405
                string s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, message.Length));
398
                char cmdID;
406
                char cmdID;
399
                byte adr;
407
                byte adr;
400
                byte[] data;
408
                byte[] data;
401
                if (message[0] != '#')
409
                if (message[0] != '#')
402
                    Log(LogMsgType.Normal, s.Trim('\0', '\n','\r'));
410
                    Log(LogMsgType.Normal, s.Trim('\0', '\n','\r'));
403
                //Debug.Print(s);
411
                //Debug.Print(s);
404
                else
412
                else
405
                {
413
                {
406
                    FlightControllerMessage.ParseMessage(message, out cmdID, out adr, out data);
414
                    FlightControllerMessage.ParseMessage(message, out cmdID, out adr, out data);
407
 
415
 
408
                    if (adr == 255) { crcError++; }
416
                    if (adr == 255) { crcError++; }
409
                    else crcError = 0;
417
                    else crcError = 0;
410
                    lblCRCErr.Invoke((Action)(() => lblCRCErr.Text = crcError.ToString()));
418
                    lblCRCErr.Invoke((Action)(() => lblCRCErr.Text = crcError.ToString()));
411
                    //display the active controller (FC / NC) 
419
                    //display the active controller (FC / NC) 
412
                    if (adr > 0 && adr < 3 && adr != _iCtrlAct) //adr < 3: temporary workaround cause when I've connected the FC alone it always switches between mk3mag & FC every second...???
420
                    if (adr > 0 && adr < 3 && adr != _iCtrlAct) //adr < 3: temporary workaround cause when I've connected the FC alone it always switches between mk3mag & FC every second...???
413
                    {
421
                    {
414
                        _iCtrlAct = adr;
422
                        _iCtrlAct = adr;
415
                        switch (adr)
423
                        switch (adr)
416
                        {
424
                        {
417
                            case 1:
425
                            case 1:
418
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "FC"));
426
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "FC"));
419
                                lblNCCtrl.Invoke((Action)(() => lblNCCtrl.Text = "FC"));
427
                                lblNCCtrl.Invoke((Action)(() => lblNCCtrl.Text = "FC"));
420
                                _setFieldsNA(); //display fields NA for FC 
428
                                _setFieldsNA(); //display fields NA for FC 
421
                                break;
429
                                break;
422
                            case 2:
430
                            case 2:
423
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "NC"));
431
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "NC"));
424
                                lblNCCtrl.Invoke((Action)(() => lblNCCtrl.Text = "NC"));
432
                                lblNCCtrl.Invoke((Action)(() => lblNCCtrl.Text = "NC"));
425
                                break;
433
                                break;
426
                            case 3:
434
                            case 3:
427
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "MK3MAG"));
435
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "MK3MAG"));
428
                                break;
436
                                break;
429
                            case 4:
437
                            case 4:
430
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "BL-CTRL"));
438
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "BL-CTRL"));
431
                                break;
439
                                break;
432
                            default:
440
                            default:
433
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "...."));
441
                                lblCtrl.Invoke((Action)(() => lblCtrl.Text = "...."));
434
                                break;
442
                                break;
435
                        }
443
                        }
436
                        _loadLabelNames();
444
                        _loadLabelNames();
437
                    }
445
                    }
438
                   // else
446
                   // else
439
                   //     Debug.Print("Address == 0?");
447
                   //     Debug.Print("Address == 0?");
440
 
448
 
441
                    if (data != null && data.Length > 0)
449
                    if (data != null && data.Length > 0)
442
                    {
450
                    {
443
                        s = new string(ASCIIEncoding.ASCII.GetChars(data, 1, data.Length - 1));
451
                        s = new string(ASCIIEncoding.ASCII.GetChars(data, 1, data.Length - 1));
444
                        s = s.Trim('\0', '\n');
452
                        s = s.Trim('\0', '\n');
445
 
453
 
446
                        switch (cmdID)
454
                        switch (cmdID)
447
                        {
455
                        {
448
                            case 'A': //Label names
456
                            case 'A': //Label names
449
                                _processLabelNames(s);
457
                                _processLabelNames(s);
450
                                break;
458
                                break;
451
 
459
 
452
                            case 'D': //Debug data
460
                            case 'D': //Debug data
453
                                _processDebugVals(adr,data);
461
                                _processDebugVals(adr,data);
454
                                break;
462
                                break;
455
 
463
 
456
                            case 'V': //Version
464
                            case 'V': //Version
457
                                _processVersion(adr, data);
465
                                _processVersion(adr, data);
458
                                break;
466
                                break;
459
 
467
 
460
                            case 'K'://BL-CTRL data
468
                            case 'K'://BL-CTRL data
461
                                _processBLCtrl(data);
469
                                _processBLCtrl(data);
462
                                break;
470
                                break;
463
 
471
 
464
                            case 'O': //NC Data
472
                            case 'O': //NC Data
465
                                _processNCData(data);
473
                                _processNCData(data);
466
                                break;
474
                                break;
467
 
475
 
468
                            case 'E': //NC error-string
476
                            case 'E': //NC error-string
469
                                ErrorLog(LogMsgType.Error, "NC Error: " + s);
477
                                ErrorLog(LogMsgType.Error, "NC Error: " + s);
470
                                break;
478
                                break;
471
 
479
 
472
                            case 'L': //OSD Menue (called by pagenumber)
480
                            case 'L': //OSD Menue (called by pagenumber)
473
                                _processOSDSingle(data);
481
                                _processOSDSingle(data);
474
                                break;
482
                                break;
475
 
483
 
476
                            case 'H': //OSD Menue (with autoupdate - called by Key)
484
                            case 'H': //OSD Menue (with autoupdate - called by Key)
477
                                _processOSDAuto(data);
485
                                _processOSDAuto(data);
478
                                break;
486
                                break;
479
 
487
 
480
                            //default:
488
                            //default:
481
                            //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
489
                            //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
482
                            //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
490
                            //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
483
                            //    break;
491
                            //    break;
484
                        }
492
                        }
485
                    }
493
                    }
486
                    //else
494
                    //else
487
                    //{
495
                    //{
488
                    //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
496
                    //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
489
                    //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
497
                    //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
490
                    //}
498
                    //}
491
                }
499
                }
492
            }
500
            }
493
        }
501
        }
494
        /// <summary>
502
        /// <summary>
495
        /// Analog label names 'A'
503
        /// Analog label names 'A'
496
        /// each label name is returned as a single string 
504
        /// each label name is returned as a single string 
497
        /// and added to string array sAnalogLabel[]
505
        /// and added to string array sAnalogLabel[]
498
        /// and the datatable dtAnalog
506
        /// and the datatable dtAnalog
499
        /// </summary>
507
        /// </summary>
500
        /// <param name="s">the label name</param>
508
        /// <param name="s">the label name</param>
501
        void _processLabelNames(string s)
509
        void _processLabelNames(string s)
502
        {
510
        {
503
            if (iLableIndex < 32)
511
            if (iLableIndex < 32)
504
            {
512
            {
505
                sAnalogLabel[iLableIndex] = s;
513
                sAnalogLabel[iLableIndex] = s;
506
                if (dtAnalog.Rows.Count < 32)
514
                if (dtAnalog.Rows.Count < 32)
507
                    dtAnalog.Rows.Add(s, "");
515
                    dtAnalog.Rows.Add(s, "");
508
                else
516
                else
509
                    dtAnalog.Rows[iLableIndex].SetField(0, s);
517
                    dtAnalog.Rows[iLableIndex].SetField(0, s);
510
 
518
 
511
                _getAnalogLabels(iLableIndex + 1);
519
                _getAnalogLabels(iLableIndex + 1);
512
            }
520
            }
513
            Debug.Print(s);
521
            Debug.Print(s);
514
        }
522
        }
515
        /// <summary>
523
        /// <summary>
516
        /// Debug values 'D'
524
        /// Debug values 'D'
517
        /// </summary>
525
        /// </summary>
518
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
526
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
519
        /// <param name="data">the received byte array to process</param>
527
        /// <param name="data">the received byte array to process</param>
520
        void _processDebugVals(byte adr,byte[] data)
528
        void _processDebugVals(byte adr,byte[] data)
521
        {
529
        {
522
            if (data.Length == 66)
530
            if (data.Length == 66)
523
            {
531
            {
524
                int[] iAnalogData = new int[32];
532
                int[] iAnalogData = new int[32];
525
 
533
 
526
                int index = 0;
534
                int index = 0;
527
                Int16 i16 = 0;
535
                Int16 i16 = 0;
528
                double dTemp = 0;
536
                double dTemp = 0;
529
                for (int i = 2; i < 66; i += 2)
537
                for (int i = 2; i < 66; i += 2)
530
                {
538
                {
531
                    i16 = data[i + 1];
539
                    i16 = data[i + 1];
532
                    i16 = (Int16)(i16 << 8);
540
                    i16 = (Int16)(i16 << 8);
533
                    iAnalogData[index] = data[i] + i16;
541
                    iAnalogData[index] = data[i] + i16;
534
                    sAnalogData[index] = (data[i] + i16).ToString();
542
                    sAnalogData[index] = (data[i] + i16).ToString();
535
                    dtAnalog.Rows[index].SetField(1, sAnalogData[index]);
543
                    dtAnalog.Rows[index].SetField(1, sAnalogData[index]);
536
 
544
 
537
                    if (adr == 2) //NC
545
                    if (adr == 2) //NC
538
                    {
546
                    {
539
                        switch (index)
547
                        switch (index)
540
                        {
548
                        {
541
                            case 0: //pitch (German: nick)
549
                            case 0: //pitch (German: nick)
542
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.pitch_angle = ((double)iAnalogData[index] / (double)10)));
550
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.pitch_angle = ((double)iAnalogData[index] / (double)10)));
543
                                lblNCPitch.Invoke((Action)(() => lblNCPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
551
                                lblNCPitch.Invoke((Action)(() => lblNCPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
544
                                break;
552
                                break;
545
                            case 1: //roll
553
                            case 1: //roll
546
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.roll_angle = ((double)iAnalogData[index] / (double)10)));
554
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.roll_angle = ((double)iAnalogData[index] / (double)10)));
547
                                lblNCRoll.Invoke((Action)(() => lblNCRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
555
                                lblNCRoll.Invoke((Action)(() => lblNCRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
548
                                break;
556
                                break;
549
                            case 4: //altitude
557
                            case 4: //altitude
550
                                lblNCAlt.Invoke((Action)(() => lblNCAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m")));
558
                                lblNCAlt.Invoke((Action)(() => lblNCAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m")));
551
                                break;
559
                                break;
552
                            case 7: //Voltage
560
                            case 7: //Voltage
553
                                lblNCVolt.Invoke((Action)(() => lblNCVolt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 V")));
561
                                lblNCVolt.Invoke((Action)(() => lblNCVolt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 V")));
554
                                break;
562
                                break;
555
                            case 8: // Current
563
                            case 8: // Current
556
                                lblNCCur.Invoke((Action)(() => lblNCCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A")));
564
                                lblNCCur.Invoke((Action)(() => lblNCCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A")));
557
                                break;
565
                                break;
558
                            case 10: //heading
566
                            case 10: //heading
559
                                lblNCCompass.Invoke((Action)(() => lblNCCompass.Text = sAnalogData[index] + "°"));
567
                                lblNCCompass.Invoke((Action)(() => lblNCCompass.Text = sAnalogData[index] + "°"));
560
                                headingIndicator1.Invoke((Action)(() => headingIndicator1.SetHeadingIndicatorParameters(iAnalogData[index])));
568
                                headingIndicator1.Invoke((Action)(() => headingIndicator1.SetHeadingIndicatorParameters(iAnalogData[index])));
561
                                break;
569
                                break;
562
                            case 12: // SPI error
570
                            case 12: // SPI error
563
                                lblNCSPI.Invoke((Action)(() => lblNCSPI.Text = sAnalogData[index]));
571
                                lblNCSPI.Invoke((Action)(() => lblNCSPI.Text = sAnalogData[index]));
564
                                break;
572
                                break;
565
                            case 14: //i2c error
573
                            case 14: //i2c error
566
                                lblNCI2C.Invoke((Action)(() => lblNCI2C.Text = sAnalogData[index]));
574
                                lblNCI2C.Invoke((Action)(() => lblNCI2C.Text = sAnalogData[index]));
567
                                break;
575
                                break;
568
                            case 20: //Earthmagnet field
576
                            case 20: //Earthmagnet field
569
                                lblNCMF.Invoke((Action)(() => lblNCMF.Text = sAnalogData[index] + "%"));
577
                                lblNCMF.Invoke((Action)(() => lblNCMF.Text = sAnalogData[index] + "%"));
570
                                break;
578
                                break;
571
                            case 21: //GroundSpeed
579
                            case 21: //GroundSpeed
572
                                lblNCGSpeed.Invoke((Action)(() => lblNCGSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
580
                                lblNCGSpeed.Invoke((Action)(() => lblNCGSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
573
                                break;
581
                                break;
574
                            case 28: //Distance East from saved home position -> calculate distance with distance N + height
582
                            case 28: //Distance East from saved home position -> calculate distance with distance N + height
575
                                dTemp = Math.Pow((double)iAnalogData[index], 2) + Math.Pow((double)iAnalogData[index - 1], 2);
583
                                dTemp = Math.Pow((double)iAnalogData[index], 2) + Math.Pow((double)iAnalogData[index - 1], 2);
576
                                dTemp = Math.Sqrt(dTemp) / (double)10; //'flat' distance from HP with N/E
584
                                dTemp = Math.Sqrt(dTemp) / (double)10; //'flat' distance from HP with N/E
577
                                                                       //  lblNCDist.Invoke((Action)(() => lblNCDist.Text = dTemp.ToString("0.00")));
585
                                                                       //  lblNCDist.Invoke((Action)(() => lblNCDist.Text = dTemp.ToString("0.00")));
578
                                dTemp = Math.Pow(dTemp, 2) + Math.Pow(((double)iAnalogData[4] / (double)10), 2); //adding 'height' into calculation
586
                                dTemp = Math.Pow(dTemp, 2) + Math.Pow(((double)iAnalogData[4] / (double)10), 2); //adding 'height' into calculation
579
                                dTemp = Math.Sqrt(dTemp);
587
                                dTemp = Math.Sqrt(dTemp) / (double)10;
580
                                lblNCDistHP.Invoke((Action)(() => lblNCDistHP.Text = dTemp.ToString("0 m")));
588
                                lblNCDistHP.Invoke((Action)(() => lblNCDistHP.Text = dTemp.ToString("0.0 m")));
581
                                break;
589
                                break;
582
                            case 31: //Sats used
590
                            case 31: //Sats used
583
                                lblNCSat.Invoke((Action)(() => lblNCSat.Text = sAnalogData[index]));
591
                                lblNCSat.Invoke((Action)(() => lblNCSat.Text = sAnalogData[index]));
584
                                break;
592
                                break;
585
                        }
593
                        }
586
                    }
594
                    }
587
                    if (adr == 1) //FC
595
                    if (adr == 1) //FC
588
                    {
596
                    {
589
                        switch (index)
597
                        switch (index)
590
                        {
598
                        {
591
                            case 0: //pitch (German: nick)
599
                            case 0: //pitch (German: nick)
592
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.pitch_angle = ((double)iAnalogData[index] / (double)10)));
600
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.pitch_angle = ((double)iAnalogData[index] / (double)10)));
593
                                lblNCPitch.Invoke((Action)(() => lblNCPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
601
                                lblNCPitch.Invoke((Action)(() => lblNCPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
594
                                break;
602
                                break;
595
                            case 1: //roll
603
                            case 1: //roll
596
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.roll_angle = ((double)iAnalogData[index] / (double)10)));
604
                                artificialHorizon1.Invoke((Action)(() => artificialHorizon1.roll_angle = ((double)iAnalogData[index] / (double)10)));
597
                                lblNCRoll.Invoke((Action)(() => lblNCRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
605
                                lblNCRoll.Invoke((Action)(() => lblNCRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
598
                                break;
606
                                break;
599
                            case 5: //altitude
607
                            case 5: //altitude
600
                                lblNCAlt.Invoke((Action)(() => lblNCAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m")));
608
                                lblNCAlt.Invoke((Action)(() => lblNCAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m")));
601
                                break;
609
                                break;
602
                            case 8: //heading
610
                            case 8: //heading
603
                                lblNCCompass.Invoke((Action)(() => lblNCCompass.Text = sAnalogData[index] + "°"));
611
                                lblNCCompass.Invoke((Action)(() => lblNCCompass.Text = sAnalogData[index] + "°"));
604
                                headingIndicator1.Invoke((Action)(() => headingIndicator1.SetHeadingIndicatorParameters(iAnalogData[index])));
612
                                headingIndicator1.Invoke((Action)(() => headingIndicator1.SetHeadingIndicatorParameters(iAnalogData[index])));
605
                                break;
613
                                break;
606
                            case 9: //Voltage
614
                            case 9: //Voltage
607
                                lblNCVolt.Invoke((Action)(() => lblNCVolt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 V")));
615
                                lblNCVolt.Invoke((Action)(() => lblNCVolt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 V")));
608
                                break;
616
                                break;
609
                            case 10: //Receiver quality
617
                            case 10: //Receiver quality
610
                                lblNCRC.Invoke((Action)(() => lblNCRC.Text = sAnalogData[index]));
618
                                lblNCRC.Invoke((Action)(() => lblNCRC.Text = sAnalogData[index]));
611
                                break;
619
                                break;
612
                            case 22: // Current
620
                            case 22: // Current
613
                                lblNCCur.Invoke((Action)(() => lblNCCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A")));
621
                                lblNCCur.Invoke((Action)(() => lblNCCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A")));
614
                                break;
622
                                break;
615
                            case 23: //capacity used
623
                            case 23: //capacity used
616
                                lblNCCap.Invoke((Action)(() => lblNCCap.Text = (iAnalogData[index]).ToString("0 mAh")));
624
                                lblNCCap.Invoke((Action)(() => lblNCCap.Text = (iAnalogData[index]).ToString("0 mAh")));
617
                                break;
625
                                break;
618
                            case 27: // SPI error
626
                            case 27: // SPI error
619
                                lblNCSPI.Invoke((Action)(() => lblNCSPI.Text = sAnalogData[index]));
627
                                lblNCSPI.Invoke((Action)(() => lblNCSPI.Text = sAnalogData[index]));
620
                                break;
628
                                break;
621
                            case 28: //i2c error
629
                            case 28: //i2c error
622
                                lblNCI2C.Invoke((Action)(() => lblNCI2C.Text = sAnalogData[index]));
630
                                lblNCI2C.Invoke((Action)(() => lblNCI2C.Text = sAnalogData[index]));
623
                                break;
631
                                break;
624
                        }
632
                        }
625
                    }
633
                    }
626
                    index++;
634
                    index++;
627
                }
635
                }
628
            }
636
            }
629
            else
637
            else
630
                Debug.Print("wrong data-length (66): " + data.Length.ToString());
638
                Debug.Print("wrong data-length (66): " + data.Length.ToString());
631
        }
639
        }
632
        /// <summary>
640
        /// <summary>
633
        /// Version string 'V'
641
        /// Version string 'V'
634
        /// </summary>
642
        /// </summary>
635
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
643
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
636
        /// <param name="data">the received byte array to process</param>
644
        /// <param name="data">the received byte array to process</param>
637
        void _processVersion(byte adr,byte[] data)
645
        void _processVersion(byte adr,byte[] data)
638
        {
646
        {
639
            if (data.Length == 12)
647
            if (data.Length == 12)
640
            {
648
            {
641
                if (!check_HWError)
649
                if (!check_HWError)
642
                {
650
                {
643
                    string[] sVersionStruct = new string[10] { "SWMajor: ", "SWMinor: ", "ProtoMajor: ", "LabelTextCRC: ", "SWPatch: ", "HardwareError 1: ", "HardwareError 2: ", "HWMajor: ", "BL_Firmware: ", "Flags: " };
651
                    string[] sVersionStruct = new string[10] { "SWMajor: ", "SWMinor: ", "ProtoMajor: ", "LabelTextCRC: ", "SWPatch: ", "HardwareError 1: ", "HardwareError 2: ", "HWMajor: ", "BL_Firmware: ", "Flags: " };
644
                    string sVersion = "";
652
                    string sVersion = "";
645
                    //sbyte[] signed = Array.ConvertAll(data, b => unchecked((sbyte)b));
653
                    //sbyte[] signed = Array.ConvertAll(data, b => unchecked((sbyte)b));
646
                    Log(LogMsgType.Warning, (adr == 1 ? "FC-" : "NC-") + "Version: ");
654
                    Log(LogMsgType.Warning, (adr == 1 ? "FC-" : "NC-") + "Version: ");
647
                    sVersion = "HW V" + (data[7] / 10).ToString() + "." + (data[7] % 10).ToString();
655
                    sVersion = "HW V" + (data[7] / 10).ToString() + "." + (data[7] % 10).ToString();
648
                    Log(LogMsgType.Incoming, sVersion);
656
                    Log(LogMsgType.Incoming, sVersion);
649
                    sVersion = "SW V" + (data[0]).ToString() + "." + (data[1]).ToString() + ((char)(data[4] + 'a')).ToString();
657
                    sVersion = "SW V" + (data[0]).ToString() + "." + (data[1]).ToString() + ((char)(data[4] + 'a')).ToString();
650
                    Log(LogMsgType.Incoming, sVersion);
658
                    Log(LogMsgType.Incoming, sVersion);
651
                    Log(LogMsgType.Incoming, "BL-Firmware: V" + (data[8] / 100).ToString() + "." + (data[8] % 100).ToString());
659
                    Log(LogMsgType.Incoming, "BL-Firmware: V" + (data[8] / 100).ToString() + "." + (data[8] % 100).ToString());
652
                }
660
                }
653
                if (data[5] > 0) //error0 
661
                if (data[5] > 0) //error0 
654
                {
662
                {
655
                    if (adr == 1)
663
                    if (adr == 1)
656
                        ErrorLog(LogMsgType.Error, "FC - HW-Error " + data[5].ToString() + ": " + ((FC_HWError0)data[5]).ToString());
664
                        ErrorLog(LogMsgType.Error, "FC - HW-Error " + data[5].ToString() + ": " + ((FC_HWError0)data[5]).ToString());
657
                    if (adr == 2)
665
                    if (adr == 2)
658
                        ErrorLog(LogMsgType.Error, "NC - HW-Error " + data[5].ToString() + ": " + ((NC_HWError0)data[5]).ToString());
666
                        ErrorLog(LogMsgType.Error, "NC - HW-Error " + data[5].ToString() + ": " + ((NC_HWError0)data[5]).ToString());
659
                }
667
                }
660
                if (data[6] > 0) //error1 
668
                if (data[6] > 0) //error1 
661
                {
669
                {
662
                    if (adr == 1)
670
                    if (adr == 1)
663
                        ErrorLog(LogMsgType.Error, "FC - HW-Error " + data[6].ToString() + ": " + ((FC_HWError1)data[6]).ToString());
671
                        ErrorLog(LogMsgType.Error, "FC - HW-Error " + data[6].ToString() + ": " + ((FC_HWError1)data[6]).ToString());
664
                    if (adr == 2)
672
                    if (adr == 2)
665
                        ErrorLog(LogMsgType.Error, "NC - Unknown HW-ERROR: " + data[6].ToString()); //@moment NC has only one error field
673
                        ErrorLog(LogMsgType.Error, "NC - Unknown HW-ERROR: " + data[6].ToString()); //@moment NC has only one error field
666
                }
674
                }
-
 
675
                if((data[5] + data[6] == 0) && _bErrorLog)
-
 
676
                    _clearErrorLog(adr==1 ? "FC - HW-Error" : "FC - HW-Error");
667
 
677
 
668
            }
678
            }
669
            check_HWError = false;
679
            check_HWError = false;
670
        }
680
        }
671
        /// <summary>
681
        /// <summary>
672
        /// BL-Ctrl data 'K'
682
        /// BL-Ctrl data 'K'
673
        /// for FC you have to use a customized firmware
683
        /// for FC you have to use a customized firmware
674
        /// </summary>
684
        /// </summary>
675
        /// <param name="data">the received byte array to process</param>
685
        /// <param name="data">the received byte array to process</param>
676
        void _processBLCtrl(byte[] data)
686
        void _processBLCtrl(byte[] data)
677
        {
687
        {
678
            if (data.Length % 6 == 0) //data.Length up to 96 (16 motors x 6 byte data) --> new datastruct in FC -> not standard!
688
            if (data.Length % 6 == 0) //data.Length up to 96 (16 motors x 6 byte data) --> new datastruct in FC -> not standard!
679
            {
689
            {
680
                bool bAvailable = false;
690
                bool bAvailable = false;
681
                for (int i = 0; i < data.Length && data[i] < 8; i += 6) // data[i] < 8 --> at moment there are 8 display fields for motors
691
                for (int i = 0; i < data.Length && data[i] < 8; i += 6) // data[i] < 8 --> at moment there are 8 display fields for motors
682
                {
692
                {
683
 
693
 
684
                    if ((data[i + 4] & 128) == 128) //Status bit at pos 7 = 128 dec -- if true, motor is available
694
                    if ((data[i + 4] & 128) == 128) //Status bit at pos 7 = 128 dec -- if true, motor is available
685
                        bAvailable = true;
695
                        bAvailable = true;
686
                    else
696
                    else
687
                        bAvailable = false;
697
                        bAvailable = false;
688
 
698
 
689
                    if (data[i] < 4)
699
                    if (data[i] < 4)
690
                    {
700
                    {
691
                        if (bAvailable)
701
                        if (bAvailable)
692
                        {
702
                        {
693
                            dtMotors1.Rows[data[i]].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
703
                            dtMotors1.Rows[data[i]].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
694
                            dtMotors1.Rows[data[i]].SetField(2, data[i + 2].ToString("0 °C"));
704
                            dtMotors1.Rows[data[i]].SetField(2, data[i + 2].ToString("0 °C"));
695
                        }
705
                        }
696
                        else
706
                        else
697
                        {
707
                        {
698
                            dtMotors1.Rows[data[i]].SetField(1, "NA");
708
                            dtMotors1.Rows[data[i]].SetField(1, "NA");
699
                            dtMotors1.Rows[data[i]].SetField(2, "NA");
709
                            dtMotors1.Rows[data[i]].SetField(2, "NA");
700
                        }
710
                        }
701
                    }
711
                    }
702
                    if (data[i] > 3 && data[i] < 8)
712
                    if (data[i] > 3 && data[i] < 8)
703
                    {
713
                    {
704
                        if (bAvailable)
714
                        if (bAvailable)
705
                        {
715
                        {
706
                            dtMotors2.Rows[data[i] - 4].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
716
                            dtMotors2.Rows[data[i] - 4].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
707
                            dtMotors2.Rows[data[i] - 4].SetField(2, data[i + 2].ToString("0 °C"));
717
                            dtMotors2.Rows[data[i] - 4].SetField(2, data[i + 2].ToString("0 °C"));
708
                        }
718
                        }
709
                        else
719
                        else
710
                        {
720
                        {
711
                            dtMotors2.Rows[data[i] - 4].SetField(1, "NA");
721
                            dtMotors2.Rows[data[i] - 4].SetField(1, "NA");
712
                            dtMotors2.Rows[data[i] - 4].SetField(2, "NA");
722
                            dtMotors2.Rows[data[i] - 4].SetField(2, "NA");
713
                        }
723
                        }
714
                    }
724
                    }
715
                }
725
                }
716
            }
726
            }
717
 
727
 
718
        }
728
        }
719
        /// <summary>
729
        /// <summary>
720
        /// Navi-Ctrl data 'O'
730
        /// Navi-Ctrl data 'O'
721
        /// GPS-Position, capacatiy, flying time...
731
        /// GPS-Position, capacatiy, flying time...
722
        /// </summary>
732
        /// </summary>
723
        /// <param name="data">the received byte array to process</param>
733
        /// <param name="data">the received byte array to process</param>
724
        void _processNCData(byte[] data)
734
        void _processNCData(byte[] data)
725
        {
735
        {
726
            int i_32, i_16, iVal;
736
            int i_32, i_16, iVal;
727
            double d;
737
            double d;
728
            i_32 = data[4];
738
            i_32 = data[4];
729
            iVal = i_32 << 24;
739
            iVal = i_32 << 24;
730
            i_32 = data[3];
740
            i_32 = data[3];
731
            iVal += i_32 << 16;
741
            iVal += i_32 << 16;
732
            i_32 = data[2];
742
            i_32 = data[2];
733
            iVal += i_32 << 8;
743
            iVal += i_32 << 8;
734
            iVal += data[1];
744
            iVal += data[1];
735
            d = (double)iVal / Math.Pow(10, 7);
745
            d = (double)iVal / Math.Pow(10, 7);
736
            lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = d.ToString("0.######°"))); //GPS-Position: Longitude in decimal degree
746
            lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = d.ToString("0.######°"))); //GPS-Position: Longitude in decimal degree
737
            //lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = _convertDegree(d))); //GPS-Position: Longitude in minutes, seconds
747
            //lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = _convertDegree(d))); //GPS-Position: Longitude in minutes, seconds
738
 
748
 
739
            i_32 = data[8];
749
            i_32 = data[8];
740
            iVal = i_32 << 24;
750
            iVal = i_32 << 24;
741
            i_32 = data[7];
751
            i_32 = data[7];
742
            iVal += i_32 << 16;
752
            iVal += i_32 << 16;
743
            i_32 = data[6];
753
            i_32 = data[6];
744
            iVal += i_32 << 8;
754
            iVal += i_32 << 8;
745
            iVal += data[5];
755
            iVal += data[5];
746
            d = (double)iVal / Math.Pow(10, 7);
756
            d = (double)iVal / Math.Pow(10, 7);
747
            lblNCGPSLat.Invoke((Action)(() => lblNCGPSLat.Text = d.ToString("0.######°"))); //GPS-Position: Latitude in decimal degree
757
            lblNCGPSLat.Invoke((Action)(() => lblNCGPSLat.Text = d.ToString("0.######°"))); //GPS-Position: Latitude in decimal degree
748
            //lblNCGPSLat.Invoke((Action)(() => lblNCGPSLat.Text = _convertDegree(d))); //GPS-Position: Latitude in minutes, seconds
758
                                                                                            //lblNCGPSLat.Invoke((Action)(() => lblNCGPSLat.Text = _convertDegree(d))); //GPS-Position: Latitude in minutes, seconds
-
 
759
 
-
 
760
            i_16 = data[28];
-
 
761
            i_16 = (Int16)(i_16 << 8);
-
 
762
            iVal = data[27] + i_16;
-
 
763
            lblNCDistWP.Invoke((Action)(() => lblNCDistWP.Text = ((double)iVal/ (double)10).ToString("0.0 m"))); //Distance to next WP
-
 
764
 
-
 
765
            i_16 = data[45];
-
 
766
            i_16 = (Int16)(i_16 << 8);
-
 
767
            iVal = data[44] + i_16;
-
 
768
            lblNCDistHP1.Invoke((Action)(() => lblNCDistHP1.Text = ((double)iVal/ (double)10).ToString("0.0 m"))); //Distance to next WP
-
 
769
 
-
 
770
            lblNCWPIndex.Invoke((Action)(() => lblNCWPIndex.Text = data[48].ToString())); //Waypoint index
-
 
771
            lblNCWPCount.Invoke((Action)(() => lblNCWPCount.Text = data[49].ToString())); //Waypoints count
749
 
772
 
750
            i_16 = data[81];
773
            i_16 = data[81];
751
            i_16 = (Int16)(i_16 << 8);
774
            i_16 = (Int16)(i_16 << 8);
752
            iVal = data[80] + i_16;
775
            iVal = data[80] + i_16;
753
            lblNCCap.Invoke((Action)(() => lblNCCap.Text = iVal.ToString() + " mAh")); //Capacity used
776
            lblNCCap.Invoke((Action)(() => lblNCCap.Text = iVal.ToString() + " mAh")); //Capacity used
754
 
777
 
755
            i_16 = data[56];
778
            i_16 = data[56];
756
            i_16 = (Int16)(i_16 << 8);
779
            i_16 = (Int16)(i_16 << 8);
757
            iVal = data[55] + i_16;
780
            iVal = data[55] + i_16;
758
            TimeSpan t = TimeSpan.FromSeconds(iVal);
781
            TimeSpan t = TimeSpan.FromSeconds(iVal);
759
            string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
782
            string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
760
            lblNCFlTime.Invoke((Action)(() => lblNCFlTime.Text = Text.ToString())); //Flying time
783
            lblNCFlTime.Invoke((Action)(() => lblNCFlTime.Text = Text.ToString())); //Flying time
761
 
784
 
762
            lblNCRC.Invoke((Action)(() => lblNCRC.Text = data[66].ToString())); //RC quality
785
            lblNCRC.Invoke((Action)(() => lblNCRC.Text = data[66].ToString())); //RC quality
763
            lblNCErrNmbr.Invoke((Action)(() => lblNCErrNmbr.Text = data[69].ToString()));   //NC Errornumber
786
            lblNCErrNmbr.Invoke((Action)(() => lblNCErrNmbr.Text = data[69].ToString()));   //NC Errornumber
764
            //if (data[69] > 0)
787
            //if (data[69] > 0)
765
            //    _readNCError();
788
            //    _readNCError();
766
            //break;
789
            //break;
767
            if (data[69] > 0 & data[69] < 44)
790
            if (data[69] > 0 & data[69] < 44)
768
                ErrorLog(LogMsgType.Error, "NC Error [" + data[69].ToString() + "]: " + NC_Error[data[69]]);
791
                ErrorLog(LogMsgType.Error, "NC Error [" + data[69].ToString() + "]: " + NC_Error[data[69]]);
-
 
792
            else
-
 
793
                if(_bErrorLog) _clearErrorLog("NC Error");
769
 
794
 
770
        }
795
        }
771
        /// <summary>
796
        /// <summary>
772
        /// OSD Menue 'L'
797
        /// OSD Menue 'L'
773
        /// single page called by pagenumber
798
        /// single page called by pagenumber
774
        /// no autoupdate
799
        /// no autoupdate
775
        /// </summary>
800
        /// </summary>
776
        /// <param name="data">the received byte array to process</param>
801
        /// <param name="data">the received byte array to process</param>
777
        void _processOSDSingle(byte[] data)
802
        void _processOSDSingle(byte[] data)
778
        {
803
        {
779
            if (data.Length == 84)
804
            if (data.Length == 84)
780
            {
805
            {
781
                string sMessage = "";
806
                string sMessage = "";
782
                iOSDPage = data[0];
807
                iOSDPage = data[0];
783
                iOSDMax = data[1];
808
                iOSDMax = data[1];
784
                if (cbOSD.Items.Count != iOSDMax) _initOSDCB();
809
                if (cbOSD.Items.Count != iOSDMax) _initOSDCB();
785
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 2, data.Length - 4));
810
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 2, data.Length - 4));
786
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20));
811
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20));
787
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20));
812
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20));
788
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20));
813
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20));
789
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20));
814
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20));
790
                lblOSDPageNr.Invoke((Action)(() => lblOSDPageNr.Text = iOSDPage.ToString("[0]")));
815
                lblOSDPageNr.Invoke((Action)(() => lblOSDPageNr.Text = iOSDPage.ToString("[0]")));
791
 
816
 
792
            }
817
            }
793
            else
818
            else
794
                OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 84)");
819
                OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 84)");
795
 
820
 
796
        }
821
        }
797
        /// <summary>
822
        /// <summary>
798
        /// OSD Menue 'H'
823
        /// OSD Menue 'H'
799
        /// called by keys (0x01,0x02,0x03,0x04)
824
        /// called by keys (0x01,0x02,0x03,0x04)
800
        /// autoupdate
825
        /// autoupdate
801
        /// </summary>
826
        /// </summary>
802
        /// <param name="data">the received byte array to process</param>
827
        /// <param name="data">the received byte array to process</param>
803
        void _processOSDAuto(byte[] data)
828
        void _processOSDAuto(byte[] data)
804
        {
829
        {
805
            if (data.Length == 81)
830
            if (data.Length == 81)
806
            {
831
            {
807
                string sMessage = "";
832
                string sMessage = "";
808
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length - 1));
833
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length - 1));
809
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20));
834
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20));
810
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20));
835
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20));
811
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20));
836
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20));
812
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20));
837
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20));
813
 
838
 
814
            }
839
            }
815
            else
840
            else
816
                OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 81)");
841
                OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 81)");
817
        }
842
        }
818
        #endregion processing received data
843
        #endregion processing received data
819
 
844
 
820
        /// <summary> send message to controller to request data
845
        /// <summary> send message to controller to request data
821
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
846
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
822
        /// </summary>
847
        /// </summary>
823
        /// <param name="CMDID"> the command ID </param>
848
        /// <param name="CMDID"> the command ID </param>
824
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
849
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
825
        private void _sendControllerMessage(char CMDID, byte address)
850
        private void _sendControllerMessage(char CMDID, byte address)
826
        {
851
        {
827
            if (simpleSerialPort.Port.IsOpen)
852
            if (simpleSerialPort.Port.IsOpen)
828
            {
853
            {
829
                Stream serialStream = simpleSerialPort.Port.BaseStream;
854
                Stream serialStream = simpleSerialPort.Port.BaseStream;
830
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address);
855
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address);
831
                serialStream.Write(bytes, 0, bytes.Length);
856
                serialStream.Write(bytes, 0, bytes.Length);
832
 
857
 
833
            }
858
            }
834
            else
859
            else
835
                Log(LogMsgType.Error, "NOT CONNECTED!");
860
                Log(LogMsgType.Error, "NOT CONNECTED!");
836
        }
861
        }
837
        /// <summary> send message to controller to request data
862
        /// <summary> send message to controller to request data
838
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
863
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
839
        /// </summary>
864
        /// </summary>
840
        /// <param name="CMDID"> the command ID </param>
865
        /// <param name="CMDID"> the command ID </param>
841
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
866
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
842
        /// <param name="data"> additional data for the request</param>
867
        /// <param name="data"> additional data for the request</param>
843
        private void _sendControllerMessage(char CMDID, byte address, byte[]data)
868
        private void _sendControllerMessage(char CMDID, byte address, byte[]data)
844
        {
869
        {
845
            if (simpleSerialPort.Port.IsOpen)
870
            if (simpleSerialPort.Port.IsOpen)
846
            {
871
            {
847
                Stream serialStream = simpleSerialPort.Port.BaseStream;
872
                Stream serialStream = simpleSerialPort.Port.BaseStream;
848
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address,data);
873
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address,data);
849
                serialStream.Write(bytes, 0, bytes.Length);
874
                serialStream.Write(bytes, 0, bytes.Length);
850
 
875
 
851
            }
876
            }
852
            else
877
            else
853
                Log(LogMsgType.Error, "NOT CONNECTED!");
878
                Log(LogMsgType.Error, "NOT CONNECTED!");
854
        }
879
        }
855
 
880
 
856
        /// <summary>
881
        /// <summary>
857
        /// read the analog-label names for the actual controller
882
        /// read the analog-label names for the actual controller
858
        /// and load it into listbox
883
        /// and load it into listbox
859
        /// </summary>
884
        /// </summary>
860
        void _loadLabelNames()
885
        void _loadLabelNames()
861
        {
886
        {
862
            if (_iCtrlAct > 0 && _iCtrlAct < 3)
887
            if (_iCtrlAct > 0 && _iCtrlAct < 3)
863
            {
888
            {
864
                switch (_iCtrlAct)
889
                switch (_iCtrlAct)
865
                {
890
                {
866
                    case 1:
891
                    case 1:
867
                        sAnalogLabel = Properties.Resources.FCLabelTexts.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
892
                        sAnalogLabel = Properties.Resources.FCLabelTexts.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
868
                        break;
893
                        break;
869
                    case 2:
894
                    case 2:
870
                        sAnalogLabel = Properties.Resources.NCLabelTexts.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
895
                        sAnalogLabel = Properties.Resources.NCLabelTexts.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
871
                        break;
896
                        break;
872
                }
897
                }
873
                for (int i = 0; i < 32; i++)
898
                for (int i = 0; i < 32; i++)
874
                {
899
                {
875
                    if (dtAnalog.Rows.Count < 32)
900
                    if (dtAnalog.Rows.Count < 32)
876
                        dtAnalog.Rows.Add(sAnalogLabel[i], "");
901
                        dtAnalog.Rows.Add(sAnalogLabel[i], "");
877
                    else
902
                    else
878
                        dtAnalog.Rows[i].SetField(0, sAnalogLabel[i]);
903
                        dtAnalog.Rows[i].SetField(0, sAnalogLabel[i]);
879
                }
904
                }
880
                dataGridView1.Invoke((Action)(()=>dataGridView1.Refresh()));
905
                dataGridView1.Invoke((Action)(()=>dataGridView1.Refresh()));
881
            }
906
            }
882
        }
907
        }
883
        /// <summary>
908
        /// <summary>
884
        /// no longer used...
909
        /// no longer used...
885
        /// read the analog-label textfile for the actual controller
910
        /// read the analog-label textfile for the actual controller
886
        /// </summary>
911
        /// </summary>
887
         private void _loadLabelFile()
912
         private void _loadLabelFile()
888
        {
913
        {
889
            switch (_iCtrlAct)
914
            switch (_iCtrlAct)
890
            {
915
            {
891
                case 1:
916
                case 1:
892
                    fileName = "FCLabelTexts.txt";
917
                    fileName = "FCLabelTexts.txt";
893
                    break;
918
                    break;
894
                case 2:
919
                case 2:
895
                    fileName = "NCLabelTexts.txt";
920
                    fileName = "NCLabelTexts.txt";
896
                    break;
921
                    break;
897
                //default:
922
                //default:
898
                //    fileName = "NCLabelTexts.txt";
923
                //    fileName = "NCLabelTexts.txt";
899
                //    break;
924
                //    break;
900
            }
925
            }
901
 
926
 
902
            if (File.Exists(filePath + "\\" + fileName))
927
            if (File.Exists(filePath + "\\" + fileName))
903
            {
928
            {
904
                sAnalogLabel.Initialize();
929
                sAnalogLabel.Initialize();
905
                sAnalogLabel = File.ReadAllLines(filePath + "\\" + fileName);
930
                sAnalogLabel = File.ReadAllLines(filePath + "\\" + fileName);
906
                lbLabels.Invoke((Action)(() => lbLabels.Items.Clear()));
931
                lbLabels.Invoke((Action)(() => lbLabels.Items.Clear()));
907
                lbLabels.Invoke((Action)(() => lbLabels.Update()));
932
                lbLabels.Invoke((Action)(() => lbLabels.Update()));
908
                lbLabels.Invoke((Action)(() => lbLabels.Items.AddRange(sAnalogLabel)));
933
                lbLabels.Invoke((Action)(() => lbLabels.Items.AddRange(sAnalogLabel)));
909
                Console.WriteLine("Names loaded from file");
934
                Console.WriteLine("Names loaded from file");
910
                lblFileName.Invoke((Action)(() => lblFileName.Text = fileName));
935
                lblFileName.Invoke((Action)(() => lblFileName.Text = fileName));
911
            }
936
            }
912
            else
937
            else
913
            {
938
            {
914
                _readCont(false);
939
                _readCont(false);
915
                Log(LogMsgType.Error, "Label-file not found!");
940
                Log(LogMsgType.Error, "Label-file not found!");
916
                Log(LogMsgType.Error, "Please go to settings-tab and load the label texts from the copter control (FC & NC)");
941
                Log(LogMsgType.Error, "Please go to settings-tab and load the label texts from the copter control (FC & NC)");
917
                Log(LogMsgType.Error, "When done, you have to save the label texts with the 'save' button!");
942
                Log(LogMsgType.Error, "When done, you have to save the label texts with the 'save' button!");
918
            }
943
            }
919
        }
944
        }
920
        /// <summary>
945
        /// <summary>
921
        /// no longer used...
946
        /// no longer used...
922
        /// assign the analog-label names from the textfile to the datatable
947
        /// assign the analog-label names from the textfile to the datatable
923
        /// 
948
        /// 
924
        /// </summary>
949
        /// </summary>
925
        private void _assignLabelNames()
950
        private void _assignLabelNames()
926
        {
951
        {
927
            if (lbLabels.Items.Count == 32)
952
            if (lbLabels.Items.Count == 32)
928
            {
953
            {
929
                lbLabels.Items.CopyTo(sAnalogLabel, 0);
954
                lbLabels.Items.CopyTo(sAnalogLabel, 0);
930
                for (int i = 0; i < 32; i++)
955
                for (int i = 0; i < 32; i++)
931
                {
956
                {
932
                    if (dtAnalog.Rows.Count < 32)
957
                    if (dtAnalog.Rows.Count < 32)
933
                        dtAnalog.Rows.Add(sAnalogLabel[i], "");
958
                        dtAnalog.Rows.Add(sAnalogLabel[i], "");
934
                    else
959
                    else
935
                        dtAnalog.Rows[i].SetField(0, sAnalogLabel[i]);
960
                        dtAnalog.Rows[i].SetField(0, sAnalogLabel[i]);
936
 
961
 
937
                }
962
                }
938
            }
963
            }
939
        }
964
        }
940
        /// <summary>
965
        /// <summary>
941
        /// get the version struct of actual controller
966
        /// get the version struct of actual controller
942
        /// </summary>
967
        /// </summary>
943
        /// <summary>
968
        /// <summary>
944
        /// get the labeltexts for the analog values
969
        /// get the labeltexts for the analog values
945
        /// </summary>
970
        /// </summary>
946
        private void _getAnalogLabels()
971
        private void _getAnalogLabels()
947
        {
972
        {
948
            if (simpleSerialPort.Port.IsOpen)
973
            if (simpleSerialPort.Port.IsOpen)
949
            {
974
            {
950
                iLableIndex = 0;
975
                iLableIndex = 0;
951
                for (int i = 0; i < 32; i++)
976
                for (int i = 0; i < 32; i++)
952
                {
977
                {
953
                    Stream serialStream = simpleSerialPort.Port.BaseStream;
978
                    Stream serialStream = simpleSerialPort.Port.BaseStream;
954
                    byte[] bytes = FlightControllerMessage.CreateMessage('a', 0, new byte[1] { (byte)i });
979
                    byte[] bytes = FlightControllerMessage.CreateMessage('a', 0, new byte[1] { (byte)i });
955
                    serialStream.Write(bytes, 0, bytes.Length);
980
                    serialStream.Write(bytes, 0, bytes.Length);
956
                    Thread.Sleep(10);
981
                    Thread.Sleep(10);
957
                }
982
                }
958
            }
983
            }
959
            else
984
            else
960
                Log(LogMsgType.Error, "NOT CONNECTED!");
985
                Log(LogMsgType.Error, "NOT CONNECTED!");
961
        }
986
        }
962
        /// <summary>
987
        /// <summary>
963
        /// get the labeltext for a single label
988
        /// get the labeltext for a single label
964
        /// </summary>
989
        /// </summary>
965
        /// <param name="iIndex">index of the label</param>
990
        /// <param name="iIndex">index of the label</param>
966
        private void _getAnalogLabels(int iIndex)
991
        private void _getAnalogLabels(int iIndex)
967
        {
992
        {
968
            if (simpleSerialPort.Port.IsOpen)
993
            if (simpleSerialPort.Port.IsOpen)
969
            {
994
            {
970
                if (iIndex < 32)
995
                if (iIndex < 32)
971
                {
996
                {
972
                    iLableIndex = iIndex;
997
                    iLableIndex = iIndex;
973
                    _sendControllerMessage('a', 0, new byte[1] { (byte)iLableIndex });
998
                    _sendControllerMessage('a', 0, new byte[1] { (byte)iLableIndex });
974
                }
999
                }
975
            }
1000
            }
976
            else
1001
            else
977
                Log(LogMsgType.Error, "NOT CONNECTED!");
1002
                Log(LogMsgType.Error, "NOT CONNECTED!");
978
        }
1003
        }
979
        private void _getVersion()
1004
        private void _getVersion()
980
        {
1005
        {
981
            _sendControllerMessage('v', 0);
1006
            _sendControllerMessage('v', 0);
982
        }
1007
        }
983
        /// <summary>
1008
        /// <summary>
984
        /// get FC version struct via NC
1009
        /// get FC version struct via NC
985
        /// by sending '1' as data (not documented in wiki...)
1010
        /// by sending '1' as data (not documented in wiki...)
986
        /// returns HW error 255 (comment in uart1.c : tells the KopterTool that it is the FC-version)
1011
        /// returns HW error 255 (comment in uart1.c : tells the KopterTool that it is the FC-version)
987
        /// </summary>
1012
        /// </summary>
988
        /// <param name="ctrl">controller number 1=FC</param> 
1013
        /// <param name="ctrl">controller number 1=FC</param> 
989
        private void _getVersion(byte ctrl)
1014
        private void _getVersion(byte ctrl)
990
        {
1015
        {
991
            _sendControllerMessage('v', 0, new byte[1] {ctrl});
1016
            _sendControllerMessage('v', 0, new byte[1] {ctrl});
992
        }
1017
        }
993
        /// <summary>
1018
        /// <summary>
994
        /// Switch back to NC by sending the 'Magic Packet' 0x1B,0x1B,0x55,0xAA,0x00
1019
        /// Switch back to NC by sending the 'Magic Packet' 0x1B,0x1B,0x55,0xAA,0x00
995
        /// </summary>
1020
        /// </summary>
996
        private void _switchToNC()
1021
        private void _switchToNC()
997
        {
1022
        {
998
            if (simpleSerialPort.Port.IsOpen)
1023
            if (simpleSerialPort.Port.IsOpen)
999
            {
1024
            {
1000
                Stream serialStream = simpleSerialPort.Port.BaseStream;
1025
                Stream serialStream = simpleSerialPort.Port.BaseStream;
1001
                byte[] bytes = new byte[5] { 0x1B,0x1B,0x55,0xAA,0x00 };
1026
                byte[] bytes = new byte[5] { 0x1B,0x1B,0x55,0xAA,0x00 };
1002
                serialStream.Write(bytes, 0, bytes.Length);
1027
                serialStream.Write(bytes, 0, bytes.Length);
1003
 
1028
 
1004
                Thread.Sleep(100);
1029
                Thread.Sleep(100);
1005
                _getVersion();
1030
                _getVersion();
1006
                Thread.Sleep(100);
1031
                Thread.Sleep(100);
1007
                _OSDMenue(0);
1032
                _OSDMenue(0);
1008
            }
1033
            }
1009
            else
1034
            else
1010
                Log(LogMsgType.Error, "NOT CONNECTED!");
1035
                Log(LogMsgType.Error, "NOT CONNECTED!");
1011
        }
1036
        }
1012
        /// <summary>
1037
        /// <summary>
1013
        /// switch to FC
1038
        /// switch to FC
1014
        /// </summary>
1039
        /// </summary>
1015
        private void _switchToFC()
1040
        private void _switchToFC()
1016
        {
1041
        {
1017
            _sendControllerMessage('u', 2, new byte[1] { (byte)0 });
1042
            _sendControllerMessage('u', 2, new byte[1] { (byte)0 });
1018
            Thread.Sleep(100);
1043
            Thread.Sleep(100);
1019
            _getVersion();
1044
            _getVersion();
1020
            Thread.Sleep(100);
1045
            Thread.Sleep(100);
1021
            _OSDMenue(0);
1046
            _OSDMenue(0);
1022
        }
1047
        }
1023
        /// <summary>
1048
        /// <summary>
1024
        /// send RESET signal to FC
1049
        /// send RESET signal to FC
1025
        /// </summary>
1050
        /// </summary>
1026
        private void _resetCtrl()
1051
        private void _resetCtrl()
1027
        {
1052
        {
1028
            _sendControllerMessage('R', 1);
1053
            _sendControllerMessage('R', 1);
1029
        }
1054
        }
1030
        /// <summary>
1055
        /// <summary>
1031
        /// poll the debug data (4sec subscription)
1056
        /// poll the debug data (4sec subscription)
1032
        /// </summary>
1057
        /// </summary>
1033
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
1058
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
1034
        private void _readDebugData(bool auto)
1059
        private void _readDebugData(bool auto)
1035
        {
1060
        {
1036
            byte interval = auto ? debugInterval : (byte)0;
1061
            byte interval = auto ? debugInterval : (byte)0;
1037
            _sendControllerMessage('d', 0, new byte[1] { debugInterval });
1062
            _sendControllerMessage('d', 0, new byte[1] { debugInterval });
1038
        }
1063
        }
1039
        /// <summary>
1064
        /// <summary>
1040
        /// poll the BL-CTRL status via NC (4sec subscription)
1065
        /// poll the BL-CTRL status via NC (4sec subscription)
1041
        /// </summary>
1066
        /// </summary>
1042
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
1067
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
1043
        private void _readBLCtrl(bool auto)
1068
        private void _readBLCtrl(bool auto)
1044
        {
1069
        {
1045
            byte interval = auto ? blctrlInterval : (byte)0;
1070
            byte interval = auto ? blctrlInterval : (byte)0;
1046
            _sendControllerMessage('k', 0, new byte[1] { interval });
1071
            _sendControllerMessage('k', 0, new byte[1] { interval });
1047
        }
1072
        }
1048
        /// <summary>
1073
        /// <summary>
1049
        /// poll the NC data struct (4sec subscription)
1074
        /// poll the NC data struct (4sec subscription)
1050
        /// </summary>
1075
        /// </summary>
1051
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
1076
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
1052
        private void _readNavData(bool auto)
1077
        private void _readNavData(bool auto)
1053
        {
1078
        {
1054
            byte interval = auto ? navctrlInterval : (byte)0;
1079
            byte interval = auto ? navctrlInterval : (byte)0;
1055
            _sendControllerMessage('o', 2, new byte[1] { interval });
1080
            _sendControllerMessage('o', 2, new byte[1] { interval });
1056
        }
1081
        }
1057
        /// <summary>
1082
        /// <summary>
1058
        /// get the errortext for pending NC error
1083
        /// get the errortext for pending NC error
1059
        /// </summary>
1084
        /// </summary>
1060
        private void _readNCError()
1085
        private void _readNCError()
1061
        {
1086
        {
1062
            _sendControllerMessage('e', 2);
1087
            _sendControllerMessage('e', 2);
1063
        }
1088
        }
1064
        /// <summary>
1089
        /// <summary>
1065
        /// start/stop continous polling of controller values
1090
        /// start/stop continous polling of controller values
1066
        /// </summary>
1091
        /// </summary>
1067
        /// <param name="b">start/stop switch</param>
1092
        /// <param name="b">start/stop switch</param>
1068
        void _readCont(bool b)
1093
        void _readCont(bool b)
1069
        {
1094
        {
1070
            bReadContinously = b;
1095
            bReadContinously = b;
1071
            btnReadDebugCont.Invoke((Action)(() => btnReadDebugCont.Text = bReadContinously ? "stop automatic" + Environment.NewLine + "data refresh" : "start automatic" + Environment.NewLine + "data refresh"));
1096
            btnReadDebugCont.Invoke((Action)(() => btnReadDebugCont.Text = bReadContinously ? "stop automatic" + Environment.NewLine + "data refresh" : "start automatic" + Environment.NewLine + "data refresh"));
1072
            btnReadDebugCont.Invoke((Action)(() => btnReadDebugCont.BackColor = bReadContinously ? Color.FromArgb(192, 255, 192) : Color.FromArgb(224, 224, 224)));
1097
            btnReadDebugCont.Invoke((Action)(() => btnReadDebugCont.BackColor = bReadContinously ? Color.FromArgb(192, 255, 192) : Color.FromArgb(224, 224, 224)));
1073
            if (bReadContinously)
1098
            if (bReadContinously)
1074
            {
1099
            {
1075
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
1100
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
1076
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
1101
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
1077
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
1102
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
1078
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); Thread.Sleep(10);}
1103
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); Thread.Sleep(10);}
1079
                lblLifeCounter.Invoke((Action)(() => lblLifeCounter.BackColor = Color.FromArgb(0, 224, 0)));
1104
                lblLifeCounter.Invoke((Action)(() => lblLifeCounter.BackColor = Color.FromArgb(0, 224, 0)));
1080
            }
1105
            }
1081
            else
1106
            else
1082
                lblLifeCounter.Invoke((Action)(() => lblLifeCounter.BackColor = Color.FromArgb(224, 224, 224)));
1107
                lblLifeCounter.Invoke((Action)(() => lblLifeCounter.BackColor = Color.FromArgb(224, 224, 224)));
1083
            _iLifeCounter = 0;
1108
            _iLifeCounter = 0;
1084
        }
1109
        }
1085
        /// <summary>
1110
        /// <summary>
1086
        /// set values to "NA" when not available with FC
1111
        /// set values to "NA" when not available with FC
1087
        /// </summary>
1112
        /// </summary>
1088
        void _setFieldsNA()
1113
        void _setFieldsNA()
1089
        {
1114
        {
1090
            Thread.Sleep(100);
1115
            Thread.Sleep(100);
1091
            _initDTMotors();
1116
            _initDTMotors();
1092
            lblNCFlTime.Invoke((Action)(() => lblNCFlTime.Text = "NA"));    //FlightTime
1117
            lblNCFlTime.Invoke((Action)(() => lblNCFlTime.Text = "NA"));    //FlightTime
1093
            lblNCErrNmbr.Invoke((Action)(() => lblNCErrNmbr.Text = "NA"));  //NC ErrorNr
1118
            lblNCErrNmbr.Invoke((Action)(() => lblNCErrNmbr.Text = "NA"));  //NC ErrorNr
1094
            lblNCMF.Invoke((Action)(() => lblNCMF.Text = "NA"));            //earth magnet field
1119
            lblNCMF.Invoke((Action)(() => lblNCMF.Text = "NA"));            //earth magnet field
1095
            lblNCGSpeed.Invoke((Action)(() => lblNCGSpeed.Text = "NA"));    //GroundSpeed
1120
            lblNCGSpeed.Invoke((Action)(() => lblNCGSpeed.Text = "NA"));    //GroundSpeed
1096
            lblNCDistHP.Invoke((Action)(() => lblNCDistHP.Text = "NA"));    //Distance to HP
1121
            lblNCDistHP.Invoke((Action)(() => lblNCDistHP.Text = "NA"));    //Distance to HP
1097
            lblNCSat.Invoke((Action)(() => lblNCSat.Text = "NA"));          //Sats used
1122
            lblNCSat.Invoke((Action)(() => lblNCSat.Text = "NA"));          //Sats used
1098
            lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = "NA"));  //GPS position - longitude
1123
            lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = "NA"));  //GPS position - longitude
1099
            lblNCGPSLat.Invoke((Action)(() => lblNCGPSLat.Text = "NA"));    //GPS position - latitude
1124
            lblNCGPSLat.Invoke((Action)(() => lblNCGPSLat.Text = "NA"));    //GPS position - latitude
-
 
1125
            lblNCDistWP.Invoke((Action)(() => lblNCDistWP.Text = "NA"));    //next WP distance
-
 
1126
            lblNCWPIndex.Invoke((Action)(() => lblNCWPIndex.Text = "NA"));  //index of actual WP
-
 
1127
            lblNCWPCount.Invoke((Action)(() => lblNCWPCount.Text = "NA"));  //count of items in WP list
1100
        }
1128
        }
1101
        /// <summary>
1129
        /// <summary>
1102
        /// one time query of the OSD Menue with pagenumber
1130
        /// one time query of the OSD Menue with pagenumber
1103
        /// </summary>
1131
        /// </summary>
1104
        /// <param name="iMenue">Menue page</param>
1132
        /// <param name="iMenue">Menue page</param>
1105
        void _OSDMenue(int iMenue)
1133
        void _OSDMenue(int iMenue)
1106
        {
1134
        {
1107
            if (simpleSerialPort.Port.IsOpen)
1135
            if (simpleSerialPort.Port.IsOpen)
1108
            {
1136
            {
1109
                if (iMenue > iOSDMax)
1137
                if (iMenue > iOSDMax)
1110
                    iMenue = 0;
1138
                    iMenue = 0;
1111
                Stream serialStream = simpleSerialPort.Port.BaseStream;
1139
                Stream serialStream = simpleSerialPort.Port.BaseStream;
1112
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
1140
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
1113
                serialStream.Write(bytes, 0, bytes.Length);
1141
                serialStream.Write(bytes, 0, bytes.Length);
1114
            }
1142
            }
1115
            else
1143
            else
1116
                Log(LogMsgType.Error, "NOT CONNECTED!");
1144
                Log(LogMsgType.Error, "NOT CONNECTED!");
1117
 
1145
 
1118
        }
1146
        }
1119
        /// <summary>
1147
        /// <summary>
1120
        /// call the OSDMenue and start autorefresh
1148
        /// call the OSDMenue and start autorefresh
1121
        ///  usually by sending a menuekey
1149
        ///  usually by sending a menuekey
1122
        /// a bit tricky - but by sending inverted value of 32 (32 = 0010 0000) you can start the OSD menue with autoupdate (abo) without switching the page with the keyvalues (0x1, 0x2)
1150
        /// a bit tricky - but by sending inverted value of 32 (32 = 0010 0000) you can start the OSD menue with autoupdate (abo) without switching the page with the keyvalues (0x1, 0x2)
1123
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
1151
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
1124
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
1152
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
1125
        /// </summary>
1153
        /// </summary>
1126
        void _OSDMenueAutoRefresh()
1154
        void _OSDMenueAutoRefresh()
1127
        {
1155
        {
1128
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)),OSDInterval });
1156
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)),OSDInterval });
1129
        }
1157
        }
1130
        void _OSDMenueAutoRefresh(byte key)
1158
        void _OSDMenueAutoRefresh(byte key)
1131
        {
1159
        {
1132
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
1160
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
1133
        }
1161
        }
1134
        /// <summary>
1162
        /// <summary>
1135
        /// initialize the OSD menue combobox
1163
        /// initialize the OSD menue combobox
1136
        /// combox is filled by numbers from 0 to max pagenumber
1164
        /// combox is filled by numbers from 0 to max pagenumber
1137
        /// </summary>
1165
        /// </summary>
1138
        void _initOSDCB()
1166
        void _initOSDCB()
1139
        {
1167
        {
1140
            _bCBInit = true;
1168
            _bCBInit = true;
1141
            if(iOSDMax == 0)
1169
            if(iOSDMax == 0)
1142
            {
1170
            {
1143
                _OSDMenue(0);
1171
                _OSDMenue(0);
1144
                Thread.Sleep(10);
1172
                Thread.Sleep(10);
1145
            }
1173
            }
1146
            cbOSD.Invoke((Action)(()=>cbOSD.Items.Clear()));
1174
            cbOSD.Invoke((Action)(()=>cbOSD.Items.Clear()));
1147
            for(int i = 0; i <= iOSDMax;i++)
1175
            for(int i = 0; i <= iOSDMax;i++)
1148
            {
1176
            {
1149
                cbOSD.Invoke((Action)(() => cbOSD.Items.Add(i)));
1177
                cbOSD.Invoke((Action)(() => cbOSD.Items.Add(i)));
1150
            }
1178
            }
1151
            cbOSD.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
1179
            cbOSD.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
1152
            _bCBInit = false;
1180
            _bCBInit = false;
1153
        }
1181
        }
1154
        void _readIni()
1182
        void _readIni()
1155
        {
1183
        {
1156
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
1184
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
1157
                _writeIni();
1185
                _writeIni();
1158
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
1186
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
1159
            ini.path = filePath + "\\MKLiveViewSettings.ini";
1187
            ini.path = filePath + "\\MKLiveViewSettings.ini";
1160
 
1188
 
1161
            string sVal = ini.IniReadValue("default", "AutorefreshDebugData");
1189
            string sVal = ini.IniReadValue("default", "AutorefreshDebugData");
1162
            _debugDataAutorefresh = Convert.ToBoolean(sVal);
1190
            _debugDataAutorefresh = Convert.ToBoolean(sVal);
1163
            sVal = ini.IniReadValue("default", "AutorefreshNavCtrlData");
1191
            sVal = ini.IniReadValue("default", "AutorefreshNavCtrlData");
1164
            _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
1192
            _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
1165
            sVal = ini.IniReadValue("default", "AutorefreshBLCtrlData");
1193
            sVal = ini.IniReadValue("default", "AutorefreshBLCtrlData");
1166
            _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
1194
            _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
1167
            sVal = ini.IniReadValue("default", "AutorefreshOSDData");
1195
            sVal = ini.IniReadValue("default", "AutorefreshOSDData");
1168
            _OSDAutorefresh = Convert.ToBoolean(sVal);
1196
            _OSDAutorefresh = Convert.ToBoolean(sVal);
1169
 
1197
 
1170
            sVal = ini.IniReadValue("default", "IntervalDebugData");
1198
            sVal = ini.IniReadValue("default", "IntervalDebugData");
1171
            debugInterval = (byte)Convert.ToInt16(sVal);
1199
            debugInterval = (byte)Convert.ToInt16(sVal);
1172
            sVal = ini.IniReadValue("default", "IntervalNavCtrlData");
1200
            sVal = ini.IniReadValue("default", "IntervalNavCtrlData");
1173
            navctrlInterval = (byte)Convert.ToInt16(sVal);
1201
            navctrlInterval = (byte)Convert.ToInt16(sVal);
1174
            sVal = ini.IniReadValue("default", "IntervalBLCtrlData");
1202
            sVal = ini.IniReadValue("default", "IntervalBLCtrlData");
1175
            blctrlInterval = (byte)Convert.ToInt16(sVal);
1203
            blctrlInterval = (byte)Convert.ToInt16(sVal);
1176
            sVal = ini.IniReadValue("default", "IntervalOSDData");
1204
            sVal = ini.IniReadValue("default", "IntervalOSDData");
1177
            OSDInterval = (byte)Convert.ToInt16(sVal);
1205
            OSDInterval = (byte)Convert.ToInt16(sVal);
1178
        }
1206
        }
1179
        void _writeIni()
1207
        void _writeIni()
1180
        {
1208
        {
1181
 
1209
 
1182
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
1210
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
1183
            ini.path = filePath + "\\MKLiveViewSettings.ini";
1211
            ini.path = filePath + "\\MKLiveViewSettings.ini";
1184
 
1212
 
1185
            ini.IniWriteValue("default", "AutorefreshDebugData", _debugDataAutorefresh ? "true":"false");
1213
            ini.IniWriteValue("default", "AutorefreshDebugData", _debugDataAutorefresh ? "true":"false");
1186
            ini.IniWriteValue("default", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true":"false");
1214
            ini.IniWriteValue("default", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true":"false");
1187
            ini.IniWriteValue("default", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true":"false");
1215
            ini.IniWriteValue("default", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true":"false");
1188
            ini.IniWriteValue("default", "AutorefreshOSDData", _OSDAutorefresh ? "true":"false");
1216
            ini.IniWriteValue("default", "AutorefreshOSDData", _OSDAutorefresh ? "true":"false");
1189
 
1217
 
1190
            ini.IniWriteValue("default", "IntervalDebugData", debugInterval.ToString());
1218
            ini.IniWriteValue("default", "IntervalDebugData", debugInterval.ToString());
1191
            ini.IniWriteValue("default", "IntervalNavCtrlData", navctrlInterval.ToString());
1219
            ini.IniWriteValue("default", "IntervalNavCtrlData", navctrlInterval.ToString());
1192
            ini.IniWriteValue("default", "IntervalBLCtrlData", blctrlInterval.ToString());
1220
            ini.IniWriteValue("default", "IntervalBLCtrlData", blctrlInterval.ToString());
1193
            ini.IniWriteValue("default", "IntervalOSDData", OSDInterval.ToString());
1221
            ini.IniWriteValue("default", "IntervalOSDData", OSDInterval.ToString());
1194
        }
1222
        }
1195
 
1223
 
1196
        /// <summary>
1224
        /// <summary>
1197
        /// initialize the 2 datatables for motor values
1225
        /// initialize the 2 datatables for motor values
1198
        /// dtMotors1 - motor 1 - 4
1226
        /// dtMotors1 - motor 1 - 4
1199
        /// dtMotors2 - motor 5 - 8
1227
        /// dtMotors2 - motor 5 - 8
1200
        /// DataGridView dgvMotors1/2 are bound to dtMotors1/2 
1228
        /// DataGridView dgvMotors1/2 are bound to dtMotors1/2 
1201
        /// </summary>
1229
        /// </summary>
1202
        void _initDTMotors()
1230
        void _initDTMotors()
1203
        {
1231
        {
1204
            for(int i = 0; i < 4; i++)
1232
            for(int i = 0; i < 4; i++)
1205
            {
1233
            {
1206
                if (dtMotors1.Rows.Count < 4)
1234
                if (dtMotors1.Rows.Count < 4)
1207
                    dtMotors1.Rows.Add((i + 1).ToString(), "NA", "NA");
1235
                    dtMotors1.Rows.Add((i + 1).ToString(), "NA", "NA");
1208
                else
1236
                else
1209
                {
1237
                {
1210
                    dtMotors1.Rows[i].SetField(1, "NA");
1238
                    dtMotors1.Rows[i].SetField(1, "NA");
1211
                    dtMotors1.Rows[i].SetField(2, "NA");
1239
                    dtMotors1.Rows[i].SetField(2, "NA");
1212
                }
1240
                }
1213
                if (dtMotors2.Rows.Count < 4)
1241
                if (dtMotors2.Rows.Count < 4)
1214
                    dtMotors2.Rows.Add((i + 5).ToString(), "NA", "NA");
1242
                    dtMotors2.Rows.Add((i + 5).ToString(), "NA", "NA");
1215
                else
1243
                else
1216
                {
1244
                {
1217
                    dtMotors2.Rows[i].SetField(1, "NA");
1245
                    dtMotors2.Rows[i].SetField(1, "NA");
1218
                    dtMotors2.Rows[i].SetField(2, "NA");
1246
                    dtMotors2.Rows[i].SetField(2, "NA");
1219
                }
1247
                }
1220
            }
1248
            }
1221
            dgvMotors1.Invoke((Action)(() => dgvMotors1.Refresh()));
1249
            dgvMotors1.Invoke((Action)(() => dgvMotors1.Refresh()));
1222
            dgvMotors2.Invoke((Action)(() => dgvMotors2.Refresh()));
1250
            dgvMotors2.Invoke((Action)(() => dgvMotors2.Refresh()));
1223
        }
1251
        }
1224
 
1252
 
1225
        /// <summary>
1253
        /// <summary>
1226
        /// Convert decimal degrees to degrees, minutes, seconds, milliseconds 
1254
        /// Convert decimal degrees to degrees, minutes, seconds, milliseconds 
1227
        /// </summary>
1255
        /// </summary>
1228
        /// <param name="coord">the degree value as double</param>
1256
        /// <param name="coord">the degree value as double</param>
1229
        /// <returns>0° 0' 0,0"</returns>
1257
        /// <returns>0° 0' 0,0"</returns>
1230
        string _convertDegree(double coord)
1258
        string _convertDegree(double coord)
1231
        {
1259
        {
1232
            //double minutes = (degree - Math.Floor(degree)) * 60.0;
1260
            //double minutes = (degree - Math.Floor(degree)) * 60.0;
1233
            //double seconds = (minutes - Math.Floor(minutes)) * 60.0;
1261
            //double seconds = (minutes - Math.Floor(minutes)) * 60.0;
1234
            //double tenths = (seconds - Math.Floor(seconds)) * 10.0;
1262
            //double tenths = (seconds - Math.Floor(seconds)) * 10.0;
1235
            //// get rid of fractional part
1263
            //// get rid of fractional part
1236
            //minutes = Math.Floor(minutes);
1264
            //minutes = Math.Floor(minutes);
1237
            //seconds = Math.Floor(seconds);
1265
            //seconds = Math.Floor(seconds);
1238
            //tenths = Math.Floor(tenths);
1266
            //tenths = Math.Floor(tenths);
1239
 
1267
 
1240
 
1268
 
1241
            //int sec = (int)Math.Round(coord * 3600);
1269
            //int sec = (int)Math.Round(coord * 3600);
1242
            //int deg = sec / 3600;
1270
            //int deg = sec / 3600;
1243
            //sec = Math.Abs(sec % 3600);
1271
            //sec = Math.Abs(sec % 3600);
1244
            //int min = sec / 60;
1272
            //int min = sec / 60;
1245
            //sec %= 60;
1273
            //sec %= 60;
1246
 
1274
 
1247
            var ts = TimeSpan.FromHours(Math.Abs(coord));
1275
            var ts = TimeSpan.FromHours(Math.Abs(coord));
1248
            double deg = Math.Sign(coord) * Math.Floor(ts.TotalHours);
1276
            double deg = Math.Sign(coord) * Math.Floor(ts.TotalHours);
1249
            int min = ts.Minutes;
1277
            int min = ts.Minutes;
1250
            int sec = ts.Seconds;
1278
            int sec = ts.Seconds;
1251
            int milli = ts.Milliseconds;
1279
            int milli = ts.Milliseconds;
1252
 
1280
 
1253
            return deg.ToString("0° ") + min.ToString("0") + "' " + sec.ToString("0") + "," + milli.ToString() + "\"";
1281
            return deg.ToString("0° ") + min.ToString("0") + "' " + sec.ToString("0") + "," + milli.ToString() + "\"";
1254
        }
1282
        }
-
 
1283
 
-
 
1284
        void _clearErrorLog(string s)
-
 
1285
        {
-
 
1286
            rtfError.Invoke((Action)(() =>
-
 
1287
            {
-
 
1288
                if (rtfError.Text.Contains(s))
-
 
1289
                {
-
 
1290
                    int iLength = 0;
-
 
1291
                    int iStart = rtfError.Text.IndexOf(s);
-
 
1292
                    int iEnd = rtfError.Text.IndexOf('\n', iStart);
-
 
1293
                    if (iEnd > 0)
-
 
1294
                    {
-
 
1295
                        iLength = iEnd + 1;
-
 
1296
                        int iHttp = rtfError.Text.IndexOf("http", iEnd);
-
 
1297
                        if (iHttp == iLength)
-
 
1298
                        {
-
 
1299
                            int iEnd2 = rtfError.Text.IndexOf('\n', iLength);
-
 
1300
                            if (iEnd2 > iLength)
-
 
1301
                            {
-
 
1302
                                iLength = iEnd2 + 1;
-
 
1303
                                rtfError.Select(iStart, iLength);
-
 
1304
                                rtfError.SelectedText = string.Empty;
-
 
1305
                                if(rtfError.Text.Length < 2) _bErrorLog = false;
-
 
1306
                            }
-
 
1307
 
-
 
1308
                        }
-
 
1309
                        else
-
 
1310
                        {
-
 
1311
                            rtfError.Select(iStart, iLength);
-
 
1312
                            rtfError.SelectedText = string.Empty;
-
 
1313
                            if(rtfError.Text.Length < 2) _bErrorLog = false;
-
 
1314
                        }
-
 
1315
                    }
-
 
1316
                }
-
 
1317
            }));
-
 
1318
 
-
 
1319
        }
1255
        #endregion functions
1320
        #endregion functions
1256
 
1321
 
1257
        #region buttons
1322
        #region buttons
1258
        private void buttonReset_Click(object sender, EventArgs e)
1323
        private void buttonReset_Click(object sender, EventArgs e)
1259
        {
1324
        {
1260
            _resetCtrl();
1325
            _resetCtrl();
1261
        }
1326
        }
1262
        private void btnVersion_Click(object sender, EventArgs e)
1327
        private void btnVersion_Click(object sender, EventArgs e)
1263
        {
1328
        {
1264
            _getVersion();
1329
            _getVersion();
1265
        }
1330
        }
1266
        private void btnAnalogLabels_Click(object sender, EventArgs e)
1331
        private void btnAnalogLabels_Click(object sender, EventArgs e)
1267
        {
1332
        {
1268
            _getAnalogLabels(0);
1333
            _getAnalogLabels(0);
1269
        }
1334
        }
1270
        private void btnDbgData_Click(object sender, EventArgs e)
1335
        private void btnDbgData_Click(object sender, EventArgs e)
1271
        {
1336
        {
1272
            _readDebugData(false); //onetime reading of debug data --> subscription lasts 4sec - this means you will receive data for 4 seconds
1337
            _readDebugData(false); //onetime reading of debug data --> subscription lasts 4sec - this means you will receive data for 4 seconds
1273
        }
1338
        }
1274
        private void btnSaveLabels_Click(object sender, EventArgs e)
1339
        private void btnSaveLabels_Click(object sender, EventArgs e)
1275
        {
1340
        {
1276
            switch (_iCtrlAct)
1341
            switch (_iCtrlAct)
1277
            {
1342
            {
1278
                case 1:
1343
                case 1:
1279
                    fileName = "FCLabelTexts.txt";
1344
                    fileName = "FCLabelTexts.txt";
1280
                    break;
1345
                    break;
1281
                case 2:
1346
                case 2:
1282
                    fileName = "NCLabelTexts.txt";
1347
                    fileName = "NCLabelTexts.txt";
1283
                    break;
1348
                    break;
1284
                default:
1349
                default:
1285
                    fileName = "NCLabelTexts.txt";
1350
                    fileName = "NCLabelTexts.txt";
1286
                    break;
1351
                    break;
1287
            }
1352
            }
1288
            if (sAnalogLabel[0] != null)
1353
            if (sAnalogLabel[0] != null)
1289
            {
1354
            {
1290
                File.WriteAllLines(filePath + "\\" + fileName, sAnalogLabel);
1355
                File.WriteAllLines(filePath + "\\" + fileName, sAnalogLabel);
1291
                Console.WriteLine("Names saved to file");
1356
                Console.WriteLine("Names saved to file");
1292
                _loadLabelFile();
1357
                _loadLabelFile();
1293
            }
1358
            }
1294
            else
1359
            else
1295
                Log(LogMsgType.Warning, "there's no data -> read first from fc/nc!");
1360
                Log(LogMsgType.Warning, "there's no data -> read first from fc/nc!");
1296
        }
1361
        }
1297
        private void btnLoadLabels_Click(object sender, EventArgs e)
1362
        private void btnLoadLabels_Click(object sender, EventArgs e)
1298
        {
1363
        {
1299
            _assignLabelNames();
1364
            _assignLabelNames();
1300
        }
1365
        }
1301
        private void btnReadLabelFile_Click(object sender, EventArgs e)
1366
        private void btnReadLabelFile_Click(object sender, EventArgs e)
1302
        {
1367
        {
1303
            _loadLabelFile();
1368
            _loadLabelFile();
1304
        }
1369
        }
1305
        private void btnSwitchFC_Click(object sender, EventArgs e)
1370
        private void btnSwitchFC_Click(object sender, EventArgs e)
1306
        {
1371
        {
1307
            _switchToFC();
1372
            _switchToFC();
1308
        }
1373
        }
1309
        private void btnSwitchNC_Click(object sender, EventArgs e)
1374
        private void btnSwitchNC_Click(object sender, EventArgs e)
1310
        {
1375
        {
1311
            _switchToNC();
1376
            _switchToNC();
1312
        }
1377
        }
1313
        private void btnReadDbgCont_Click(object sender, EventArgs e)
1378
        private void btnReadDbgCont_Click(object sender, EventArgs e)
1314
        {
1379
        {
1315
            _readCont(!bReadContinously);
1380
            _readCont(!bReadContinously);
1316
        }
1381
        }
1317
        private void btnReadBLCtrl_Click(object sender, EventArgs e)
1382
        private void btnReadBLCtrl_Click(object sender, EventArgs e)
1318
        {
1383
        {
1319
 
1384
 
1320
            if (_iCtrlAct == 2) _readBLCtrl(false);
1385
            if (_iCtrlAct == 2) _readBLCtrl(false);
1321
            else Log(LogMsgType.Warning, "only available when connected to NC");
1386
            else Log(LogMsgType.Warning, "only available when connected to NC");
1322
        }
1387
        }
1323
        private void btnGetNaviData_Click(object sender, EventArgs e)
1388
        private void btnGetNaviData_Click(object sender, EventArgs e)
1324
        {
1389
        {
1325
            if (_iCtrlAct == 2) _readNavData(false);
1390
            if (_iCtrlAct == 2) _readNavData(false);
1326
            else Log(LogMsgType.Warning, "only available when connected to NC");
1391
            else Log(LogMsgType.Warning, "only available when connected to NC");
1327
        }
1392
        }
1328
        private void btnConn_Click(object sender, EventArgs e)
1393
        private void btnConn_Click(object sender, EventArgs e)
1329
        {
1394
        {
1330
            simpleSerialPort.Connect(!simpleSerialPort.Port.IsOpen);
1395
            simpleSerialPort.Connect(!simpleSerialPort.Port.IsOpen);
1331
        }
1396
        }
1332
        private void button3_Click(object sender, EventArgs e)
1397
        private void button3_Click(object sender, EventArgs e)
1333
        {
1398
        {
1334
            _getVersion(1);
1399
            _getVersion(1);
1335
        }
1400
        }
1336
        private void button4_Click(object sender, EventArgs e)
1401
        private void button4_Click(object sender, EventArgs e)
1337
        {
1402
        {
1338
            _getVersion(2);
1403
            _getVersion(2);
1339
        }
1404
        }
1340
        private void btnOSD_Click(object sender, EventArgs e)
1405
        private void btnOSD_Click(object sender, EventArgs e)
1341
        {
1406
        {
1342
            if (iOSDPage > iOSDMax)
1407
            if (iOSDPage > iOSDMax)
1343
                iOSDPage = 0;
1408
                iOSDPage = 0;
1344
            _OSDMenue(iOSDPage);
1409
            _OSDMenue(iOSDPage);
1345
        }
1410
        }
1346
        private void btnOSDForward_Click(object sender, EventArgs e)
1411
        private void btnOSDForward_Click(object sender, EventArgs e)
1347
        {
1412
        {
1348
            iOSDPage++;
1413
            iOSDPage++;
1349
            if (iOSDPage > iOSDMax)
1414
            if (iOSDPage > iOSDMax)
1350
                iOSDPage = 0;
1415
                iOSDPage = 0;
1351
 
1416
 
1352
            _OSDMenue(iOSDPage);
1417
            _OSDMenue(iOSDPage);
1353
        }
1418
        }
1354
        private void btnOSDBackward_Click(object sender, EventArgs e)
1419
        private void btnOSDBackward_Click(object sender, EventArgs e)
1355
        {
1420
        {
1356
            iOSDPage--;
1421
            iOSDPage--;
1357
            if (iOSDPage < 0)
1422
            if (iOSDPage < 0)
1358
                iOSDPage = iOSDMax;
1423
                iOSDPage = iOSDMax;
1359
 
1424
 
1360
            _OSDMenue(iOSDPage);
1425
            _OSDMenue(iOSDPage);
1361
        }
1426
        }
1362
        private void btnOSDAuto_Click(object sender, EventArgs e)
1427
        private void btnOSDAuto_Click(object sender, EventArgs e)
1363
        {
1428
        {
1364
            _OSDMenueAutoRefresh();
1429
            _OSDMenueAutoRefresh();
1365
        }
1430
        }
1366
        /// call the OSDMenue with Key 0x8
1431
        /// call the OSDMenue with Key 0x8
1367
        private void btnOSDLeave_Click(object sender, EventArgs e)
1432
        private void btnOSDLeave_Click(object sender, EventArgs e)
1368
        {
1433
        {
1369
            _OSDMenueAutoRefresh(8);
1434
            _OSDMenueAutoRefresh(8);
1370
        }
1435
        }
1371
        /// call the OSDMenue with Key 0x4
1436
        /// call the OSDMenue with Key 0x4
1372
        private void btnOSDEnter_Click(object sender, EventArgs e)
1437
        private void btnOSDEnter_Click(object sender, EventArgs e)
1373
        {
1438
        {
1374
            _OSDMenueAutoRefresh(4);
1439
            _OSDMenueAutoRefresh(4);
1375
        }
1440
        }
1376
        #endregion buttons
1441
        #endregion buttons
-
 
1442
 
1377
    }
1443
    }
1378
    public class IniFile
1444
    public class IniFile
1379
    {
1445
    {
1380
        public string path;
1446
        public string path;
1381
 
1447
 
1382
        [DllImport("kernel32")]
1448
        [DllImport("kernel32")]
1383
        private static extern long WritePrivateProfileString(string section,
1449
        private static extern long WritePrivateProfileString(string section,
1384
          string key, string val, string filePath);
1450
          string key, string val, string filePath);
1385
 
1451
 
1386
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
1452
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
1387
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
1453
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
1388
               uint nSize, string lpFileName);
1454
               uint nSize, string lpFileName);
1389
 
1455
 
1390
        [DllImport("kernel32")]
1456
        [DllImport("kernel32")]
1391
        private static extern int GetPrivateProfileString(string section,
1457
        private static extern int GetPrivateProfileString(string section,
1392
          string key, string def, StringBuilder retVal,
1458
          string key, string def, StringBuilder retVal,
1393
          int size, string filePath);
1459
          int size, string filePath);
1394
 
1460
 
1395
        public IniFile(string INIPath)
1461
        public IniFile(string INIPath)
1396
        {
1462
        {
1397
            path = INIPath;
1463
            path = INIPath;
1398
        }
1464
        }
1399
 
1465
 
1400
        public void IniWriteValue(string Section, string Key, string Value)
1466
        public void IniWriteValue(string Section, string Key, string Value)
1401
        {
1467
        {
1402
            WritePrivateProfileString(Section, Key, Value, this.path);
1468
            WritePrivateProfileString(Section, Key, Value, this.path);
1403
        }
1469
        }
1404
 
1470
 
1405
        public string IniReadValue(string Section, string Key)
1471
        public string IniReadValue(string Section, string Key)
1406
        {
1472
        {
1407
            StringBuilder temp = new StringBuilder(255);
1473
            StringBuilder temp = new StringBuilder(255);
1408
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
1474
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
1409
            return temp.ToString();
1475
            return temp.ToString();
1410
        }
1476
        }
1411
        //Ini_sections auslesen in String-Array
1477
        //Ini_sections auslesen in String-Array
1412
        public string[] IniSectionNames()
1478
        public string[] IniSectionNames()
1413
        {
1479
        {
1414
 
1480
 
1415
            //  uint MAX_BUFFER = 32767;
1481
            //  uint MAX_BUFFER = 32767;
1416
            uint MAX_BUFFER = 8388608;
1482
            uint MAX_BUFFER = 8388608;
1417
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
1483
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
1418
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
1484
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
1419
            if (bytesReturned == 0)
1485
            if (bytesReturned == 0)
1420
            {
1486
            {
1421
                Marshal.FreeCoTaskMem(pReturnedString);
1487
                Marshal.FreeCoTaskMem(pReturnedString);
1422
                return null;
1488
                return null;
1423
            }
1489
            }
1424
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
1490
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
1425
            Marshal.FreeCoTaskMem(pReturnedString);
1491
            Marshal.FreeCoTaskMem(pReturnedString);
1426
            //use of Substring below removes terminating null for split
1492
            //use of Substring below removes terminating null for split
1427
            return local.Substring(0, local.Length - 1).Split('\0');
1493
            return local.Substring(0, local.Length - 1).Split('\0');
1428
 
1494
 
1429
 
1495
 
1430
        }
1496
        }
1431
    }
1497
    }
1432
    public static class ControlExtensions
1498
    public static class ControlExtensions
1433
    {
1499
    {
1434
        /// <summary> 
1500
        /// <summary> 
1435
        /// Execute a threadsafe operation, when accessing a control via another thread 
1501
        /// Execute a threadsafe operation, when accessing a control via another thread 
1436
        /// action is a lamdaexpression
1502
        /// action is a lamdaexpression
1437
        /// e.g. comboBox1.ExecuteThreadSafe(() => comboBox1.Enabled = true);
1503
        /// e.g. comboBox1.ExecuteThreadSafe(() => comboBox1.Enabled = true);
1438
        /// </summary>
1504
        /// </summary>
1439
        /// <param name="control"> The control </param>
1505
        /// <param name="control"> The control </param>
1440
        /// <param name="action"> The 'action' to perform </param>
1506
        /// <param name="action"> The 'action' to perform </param>
1441
        public static void ExecuteThreadSafe(this Control control, Action action)
1507
        public static void ExecuteThreadSafe(this Control control, Action action)
1442
        {
1508
        {
1443
            if (control.InvokeRequired)
1509
            if (control.InvokeRequired)
1444
            {
1510
            {
1445
                control.BeginInvoke(action); //"BeginInvoke" is an async call -> threadsafety error when called to many times successively -> then take "Invoke"
1511
                control.BeginInvoke(action); //"BeginInvoke" is an async call -> threadsafety error when called to many times successively -> then take "Invoke"
1446
            }
1512
            }
1447
            else
1513
            else
1448
            {
1514
            {
1449
                action.Invoke();
1515
                action.Invoke();
1450
            }
1516
            }
1451
        }
1517
        }
1452
    }
1518
    }
1453
 
1519
 
1454
}
1520
}
1455
 
1521