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 |