Subversion Repositories Projects

Rev

Rev 1517 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1517 - 1
/*****************************************************************************
2
 *   Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de                  *
3
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
4
 *   Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
5
 *   Copyright (C) 2011 Harald Bongartz                                      *
6
 *                                                                           *
7
 *   This program is free software; you can redistribute it and/or modify    *
8
 *   it under the terms of the GNU General Public License as published by    *
9
 *   the Free Software Foundation; either version 2 of the License.          *
10
 *                                                                           *
11
 *   This program is distributed in the hope that it will be useful,         *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
14
 *   GNU General Public License for more details.                            *
15
 *                                                                           *
16
 *   You should have received a copy of the GNU General Public License       *
17
 *   along with this program; if not, write to the                           *
18
 *   Free Software Foundation, Inc.,                                         *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
20
 *                                                                           *
21
 *                                                                           *
22
 *   Credits to:                                                             *
23
 *   Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN  *
24
 *                          http://www.mikrokopter.de                        *
25
 *   Gregor "killagreg" Stobrawa for his version of the MK code              *
26
 *   Thomas Kaiser "thkais" for the original project. See                    *
27
 *                          http://www.ft-fanpage.de/mikrokopter/            *
28
 *                          http://forum.mikrokopter.de/topic-4061-1.html    *
29
 *   Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
30
 *                          http://www.mylifesucks.de/oss/c-osd/             *
31
 *   Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
32
 *****************************************************************************/
33
 
34
 
35
#include "cpu.h"
36
#include <avr/io.h>
37
#include <inttypes.h>
38
#include <stdlib.h>
39
#include <avr/pgmspace.h>
40
#include <util/delay.h>
41
 
42
#include "main.h"
43
#include "osd.h"
44
#include "lcd.h"
45
#include "timer.h"
46
#include "usart.h"
47
#include "eeprom.h"
48
#include "messages.h"
49
 
50
#include "mk-data-structs.h"
51
 
52
#define COSD_WASFLYING 4
53
#define TIMEOUT 200     // 2 sec
54
 
55
// global definitions and global vars
56
NaviData_t *naviData;
57
 
58
// löschen und alle mit "naviData->Variometer" ersetzen
59
//int8_t Variometer = 0;
60
 
61
// Hier Höhenanzeigefehler Korrigieren
62
#define AltimeterAdjust 1.5
63
 
64
// stats for after flight
65
int16_t max_Altimeter = 0;
66
uint16_t max_GroundSpeed = 0;
67
int16_t max_Distance = 0;
68
uint8_t min_UBat = 255;
69
uint16_t max_FlyingTime = 0;
70
uint16_t max_Current = 0;
71
uint16_t max_Capacity = 0;
72
 
73
// cache old vars for blinking attribute, checkup is faster than full
74
// attribute write each time
75
volatile uint8_t last_UBat = 255;
76
volatile uint8_t last_RC_Quality = 255;
77
 
78
volatile uint16_t ftimer = 0;
79
 
80
// store stats description in progmem to save space
81
const char stats_item_0[] PROGMEM = "max Altitude:";
82
const char stats_item_1[] PROGMEM = "max Speed   :";
83
const char stats_item_2[] PROGMEM = "max Distance:";
84
const char stats_item_3[] PROGMEM = "min Voltage :";
85
const char stats_item_4[] PROGMEM = "max Time    :";
86
#if 1
87
const char stats_item_5[] PROGMEM = "max Current :";
88
const char stats_item_6[] PROGMEM = "UsedCapacity:";
89
#else
90
const char stats_item_5[] PROGMEM = "Long. :";
91
const char stats_item_6[] PROGMEM = "Lat.  :";
92
#endif
93
 
94
 
95
const char *stats_item_pointers[] PROGMEM = {
96
        stats_item_0,
97
        stats_item_1,
98
        stats_item_2,
99
        stats_item_3,
100
        stats_item_4,
101
        stats_item_5,
102
        stats_item_6
103
};
104
 
105
//char* rose = "-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W";
106
const char rose[48] PROGMEM = {
107
        0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S',
108
        0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O',
109
        0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N',
110
        0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W',
111
};
112
 
113
// the center is char 19 (north), we add the current heading in 8th
114
// which would be 22.5 degrees, but float would bloat up the code
115
// and *10 / 225 would take ages... so we take the uncorrect way
116
 
117
const char str_NE[] PROGMEM = "NE";
118
const char str_E[] PROGMEM  = "E ";
119
const char str_SE[] PROGMEM = "SE";
120
const char str_S[] PROGMEM  = "S ";
121
const char str_SW[] PROGMEM = "SW";
122
const char str_W[] PROGMEM  = "W ";
123
const char str_NW[] PROGMEM = "NW";
124
const char str_N[] PROGMEM  = "N ";
125
const char *directions_p[8] PROGMEM = {
126
        str_NE,
127
        str_E,
128
        str_SE,
129
        str_S,
130
        str_SW,
131
        str_W,
132
        str_NW,
133
        str_N
134
};
135
 
136
// Flags
137
uint8_t COSD_FLAGS2 = 0;
138
 
139
GPS_Pos_t last5pos[7];
140
uint8_t error = 0;
141
 
142
 
143
//--------------------------------------------------------------
144
// convert the <heading> gotton from NC into an index
145
uint8_t heading_conv (uint16_t heading)
146
{
147
        if (heading > 23 && heading < 68)
148
                return 0;               //direction = "NE";
149
        else if (heading > 67 && heading < 113)
150
                return 1;               //direction = "E ";
151
        else if (heading > 112 && heading < 158)
152
                return 2;               //direction = "SE";
153
        else if (heading > 157 && heading < 203)
154
                return 3;               //direction = "S ";
155
        else if (heading > 202 && heading < 248)
156
                return 4;               //direction = "SW";
157
        else if (heading > 247 && heading < 293)
158
                return 5;               //direction = "W ";
159
        else if (heading > 292 && heading < 338)
160
                return 6;               //direction = "NW";
161
 
162
        return 7;       //direction = "N ";
163
}
164
 
165
//--------------------------------------------------------------
166
// draw a compass rose at <x>/<y> for <heading>
167
void draw_compass (uint8_t x, uint8_t y, uint16_t heading)
168
{
169
        uint8_t front = 19 + (heading / 22);
170
        for (uint8_t i = 0; i < 9; i++)
171
                lcd_putc (x++, y, pgm_read_byte(&rose[front - 4 + i]), 0);
172
}
173
 
174
 
175
//--------------------------------------------------------------
176
// variometer
177
// draw variometer arrows at <x>/<y> according to <variometer>
178
//
179
void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer)
180
{
181
        lcd_rect (x, y - ((hight) / 2), width, hight, 1);
182
        lcd_frect (x + 1, y - ((hight) / 2) + 1, width - 2, hight - 2, 0);
183
        lcd_line (x, y, x + width, y, 1);
184
 
185
        if (variometer > 0)  // steigend
186
        {
187
                switch (variometer / 5)
188
                {
189
                        case 0:
190
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
191
                        break;
192
 
193
                        case 1:
194
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
195
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
196
                        break;
197
 
198
                        case 2:
199
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);      //  1 >  4
200
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
201
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
202
                        break;
203
 
204
                        default:
205
                                lcd_line  (x + 4, y - 1, x + 6, y - 1, 1);  //  1 >  4
206
                                lcd_frect (x + 3, y - 3, 4, 1, 1);                      //  5 >  9
207
                                lcd_frect (x + 2, y - 5, 6, 1, 1);                      // 10 > 14
208
                                lcd_frect (x + 1, y - 6, 8, 1, 1);                      // 15 >
209
                        break;
210
                }
211
        }
212
        else if (variometer < 0)  // fallend
213
        {
214
                switch ((variometer) / -5)
215
                {
216
                        case 0:
217
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
218
                        break;
219
 
220
                        case 1:
221
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
222
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
223
                        break;
224
 
225
                        case 2:
226
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
227
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
228
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
229
                        break;
230
 
231
                        default:
232
                                lcd_line  (x + 4, y + 1, x + 6, y + 1, 1);      // - 1 > - 4
233
                                lcd_frect (x + 3, y + 2, 4, 1, 1);                      // - 5 > - 9
234
                                lcd_frect (x + 2, y + 4, 6, 1, 1);                      // -10 > -14
235
                                lcd_frect (x + 1, y + 5, 8, 1, 1);                      // -15 >
236
                        break;
237
                }
238
        }
239
}
240
 
241
 
242
//--------------------------------------------------------------
243
void print_statistics (void)
244
{
245
        uint8_t line = 0;
246
        lcd_cls ();
247
//      lcd_printp_at (12, 7, PSTR("Ende"), 0);
248
        lcd_puts_at(12, 7, strGet(ENDE), 0);
249
 
250
        // max Altitude
251
        lcd_printp_at (0, line, stats_item_pointers[0], 0);
252
        write_ndigit_number_s (13, line, max_Altimeter / (30 / AltimeterAdjust), 4, 0);
253
        lcd_putc (17, line, 'm', 0);
254
 
255
        // max Speed
256
        lcd_printp_at (0, ++line, stats_item_pointers[1], 0);
257
        write_ndigit_number_u (14, line, (uint16_t) (((uint32_t) max_GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0);
258
        lcd_printp_at(17, line, PSTR("km/h"), 0);
259
 
260
        // max Distance
261
        lcd_printp_at (0, ++line, stats_item_pointers[2], 0);
262
        write_ndigit_number_u (14, line, max_Distance / 10, 3, 0);
263
        lcd_putc (17, line, 'm', 0);
264
 
265
        // max time
266
        lcd_printp_at (0, ++line, stats_item_pointers[4], 0);
267
        write_time (13, line, max_FlyingTime);
268
 
269
        // min voltage
270
        lcd_printp_at (0, ++line, stats_item_pointers[3], 0);
271
        write_ndigit_number_u_10th (13, line, min_UBat, 3, 0);
272
        lcd_putc (17, line, 'V', 0);
273
 
274
#if 1
275
        // max Current
276
        lcd_printp_at (0, ++line, stats_item_pointers[5], 0);
277
        write_ndigit_number_u_10th (13, line, max_Current, 3, 0);
278
        lcd_putc (17, line, 'A', 0);
279
 
280
        // Used Capacity
281
        lcd_printp_at (0, ++line, stats_item_pointers[6], 0);
282
        write_ndigit_number_u (13, line, max_Capacity, 4, 0);
283
        lcd_printp_at(17, line, PSTR("mAh"), 0);
284
#else
285
        // longitude
286
        lcd_printp_at (0, ++line, stats_item_pointers[5], 0);
287
        write_gps_pos (8, line, naviData->CurrentPosition.Longitude);
288
 
289
        // latitude
290
        lcd_printp_at (0, ++line, stats_item_pointers[6], 0);
291
        write_gps_pos (8, line, naviData->CurrentPosition.Latitude);
292
#endif
293
 
294
        while (!get_key_press (1 << KEY_ESC))
295
                timer = TIMEOUT;
296
 
297
        COSD_FLAGS2 &= ~COSD_WASFLYING;
298
        get_key_press(KEY_ALL);
299
        lcd_cls();
300
}
301
 
302
//--------------------------------------------------------------
303
void print_position (void)
304
{
305
        lcd_cls ();
306
//      lcd_printp_at (0, 0, PSTR(" Breitengr  Längengr "), 2);
307
        lcd_puts_at(0, 0, strGet(START_LASTPOS1), 2);
308
//      lcd_printp_at (12, 7, PSTR("Ende"), 0);
309
        lcd_puts_at(12, 7, strGet(ENDE), 0);
310
        uint8_t ij =0;
311
 
312
        for(ij=0;ij<6;ij++)
313
        {
1518 - 314
                uint32_t lon = last5pos[ij].Latitude;
1517 - 315
                write_ndigit_number_u (1, ij+1, (uint16_t)(lon/10000000), 2, 0);
316
                lcd_printp_at (3, ij+1, PSTR("."), 0);
317
                write_ndigit_number_u (4, ij+1, (uint16_t)((lon/1000) % 10000), 4, 1);
318
                write_ndigit_number_u (8, ij+1, (uint16_t)((lon/10) % 100), 2, 1);
319
 
1518 - 320
                uint32_t lat = last5pos[ij].Longitude;
1517 - 321
                write_ndigit_number_u (12, ij+1, (uint16_t)(lat/10000000), 2, 0);
322
                lcd_printp_at (14, ij+1, PSTR("."), 0);
323
                write_ndigit_number_u (15, ij+1, (uint16_t)((lat/1000) % 10000), 4, 1);
324
                write_ndigit_number_u (19, ij+1, (uint16_t)((lat/10) % 100), 2, 1);
325
        }
326
 
327
        while (!get_key_press (1 << KEY_ESC))
328
                timer = TIMEOUT;
329
 
330
        get_key_press(KEY_ALL);
331
        lcd_cls();
332
}
1518 - 333
void Show_LastPosition(void)
334
{
335
  lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
336
  uint32_t lon = last5pos[0].Latitude;
337
  write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0);
338
  lcd_printp_at (3, 6, PSTR("."), 0);
339
  write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1);
340
  write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1);
1517 - 341
 
1518 - 342
  uint32_t lat = last5pos[0].Longitude;
343
  write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0);
344
  lcd_printp_at (14, 6, PSTR("."), 0);
345
  write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1);
346
  write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1);
1517 - 347
 
1518 - 348
}
349
 
350
void OSD_Timeout(uint8_t flag)
351
{
352
 
353
//  uint8_t flag;
354
  uint8_t tmp_dat;
355
 // flag = 0;
356
  timer = TIMEOUT;
357
  // disable OSD Data from NC
358
  //      RS232_request_mk_data (1, 'o', 0);
359
//  tmp_dat = 0;
360
//  SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
361
 
362
  mode = 0;
363
  rxd_buffer_locked = FALSE;
364
 
365
 
366
  // Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!!
367
//  if (!timer)
368
//  {       // timeout occured
369
          if (flag)
370
          {
371
                  // Falls Spannungswarnung an war Beeper aus//
372
                  BeepTime = 0;
373
                  BeepMuster = 0xFFFF;
374
 
375
                  lcd_cls ();
376
                  WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude);  // im EEprom speichern
377
                  lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
378
 
379
//                      lcd_printp_at (0, 0, PSTR(" ERROR: Datenverlust "), 2);
380
 
381
//                      lcd_printp_at (0, 2, PSTR("Letzte bekannte"), 0);
382
//                      lcd_printp_at (0, 3, PSTR("Position gespeichert."), 0);
383
                  lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
384
                  lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
385
//                      lcd_printp_at (19, 7, PSTR("OK"), 0);
386
                  lcd_puts_at(19, 7, strGet(OK), 0);
387
//                      lcd_printp_at (0, 5, PSTR(" Breitengr  Längengr "), 0);
388
 
389
                  lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
390
 
391
                  lcd_puts_at(12, 7, strGet(ENDE), 0);
392
 
393
                  BeepTime = 250;
394
                  BeepMuster = 0x0080;
395
                  error = 1;
396
 
397
                  uint32_t lon = last5pos[0].Latitude;
398
                  write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0);
399
                  lcd_printp_at (3, 6, PSTR("."), 0);
400
                  write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1);
401
                  write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1);
402
 
403
                  uint32_t lat = last5pos[0].Longitude;
404
                  write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0);
405
                  lcd_printp_at (14, 6, PSTR("."), 0);
406
                  write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1);
407
                  write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1);
408
 
409
//                  while (!get_key_press (1 << KEY_ENTER));
410
                  _delay_ms(1000);
411
                  timer = TIMEOUT;
412
                  lcd_cls();
413
//                  return;
414
 
415
 
416
          }
417
          else
418
            {
419
              lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
420
              Show_LastPosition();
421
              BeepTime = 250;
422
              BeepMuster = 0x0080;
423
            }
424
//  }
425
                  SwitchToNC();
426
 
427
                  mode = 'O';
428
 
429
                  // disable debug...
430
                  //      RS232_request_mk_data (0, 'd', 0);
431
                  tmp_dat = 0;
432
                  SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);
433
 
434
                  // request OSD Data from NC every 100ms
435
                  //      RS232_request_mk_data (1, 'o', 100);
436
                  tmp_dat = 10;
437
                  SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
438
 
439
 
440
}
441
 
442
 
443
 
444
 
1517 - 445
//--------------------------------------------------------------
446
void osd (uint8_t ShowMode)
447
{
448
        uint8_t flag;
449
        uint8_t tmp_dat;
450
        uint8_t OSD_Mode;
451
        uint8_t info_3D = 0;
452
 
453
        // Clear statistics
454
        max_Altimeter = 0;
455
        max_GroundSpeed = 0;
456
        max_Distance = 0;
457
        min_UBat = 255;
458
        max_FlyingTime = 0;
459
 
460
        // flags from last round to check for changes
461
        uint8_t old_FCFlags = 0;
462
 
463
        uint16_t old_hh = 0;
464
        uint8_t old_AngleNick = 0;
465
        uint8_t old_AngleRoll = 0;
1518 - 466
        lcd_cls();
1517 - 467
        OSD_Mode = ShowMode;
468
 
1518 - 469
//      if(error == 0)
470
//              lcd_cls();
1517 - 471
 
472
        if (hardware == FC)
473
        {
474
                lcd_printp_at(0, 3, PSTR("Only with NC !"), 0);
475
                timer = 100;
476
                while (timer > 0);
477
 
478
                return;
479
        }
480
 
481
        SwitchToNC();
482
 
483
        mode = 'O';
484
 
485
        // disable debug...
486
        //      RS232_request_mk_data (0, 'd', 0);
487
        tmp_dat = 0;
488
        SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1);
489
 
490
        // request OSD Data from NC every 100ms
491
        //      RS232_request_mk_data (1, 'o', 100);
492
        tmp_dat = 10;
493
        SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
494
 
495
        flag = 0;
496
        timer = TIMEOUT;
497
        abo_timer = ABO_TIMEOUT;
498
 
499
 
500
        do
501
        {
502
                if (rxd_buffer_locked)
503
                {
504
                        timer = TIMEOUT;
505
                        Decode64 ();
506
                        naviData = (NaviData_t *) pRxData;
507
 
508
                        if(error == 1)
509
                                lcd_cls();
510
 
511
                        error = 0;
512
                        GPS_Pos_t currpos;
513
                        currpos.Latitude = naviData->CurrentPosition.Latitude;
514
                        currpos.Longitude = naviData->CurrentPosition.Longitude;
515
 
516
                        if((currpos.Latitude != last5pos[0].Latitude)&&(currpos.Longitude != last5pos[0].Longitude))
517
                        {
518
                                last5pos[6] = last5pos[5];
519
                                last5pos[5] = last5pos[4];
520
                                last5pos[4] = last5pos[3];
521
                                last5pos[3] = last5pos[2];
522
                                last5pos[2] = last5pos[1];
523
                                last5pos[1] = last5pos[0];
524
                                last5pos[0] = currpos;
525
                        }
526
 
527
                        flag = 1;
528
 
529
                        if (OSD_Mode == 1)
530
                        {
531
                                if (naviData->FCFlags & FCFLAG_MOTOR_RUN)
532
                                { // should be engines running
533
                                        // motors are on, assume we were/are flying
534
                                        COSD_FLAGS2 |= COSD_WASFLYING;
535
                                }
536
                                else
537
                                {       // stats
538
                                        if ((COSD_FLAGS2 & COSD_WASFLYING) | (get_key_press (1 << KEY_ENTER)))
539
                                                print_statistics ();
540
 
541
                                        if (get_key_press (1 << KEY_PLUS))
542
                                                print_position ();
543
                                }
544
 
545
                                lcd_ecircle(22, 35, 16, 1);
546
 
547
                                // Ground Speed
548
                                write_ndigit_number_u (1, 0, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0);
549
                                lcd_printp_at(4, 0, PSTR("km/h"), 0);
550
 
551
                                // Compass
552
                                write_ndigit_number_u (14, 0, naviData->CompassHeading, 3, 0);
553
                                lcd_putc (17, 0, 0x1E, 0);      // degree symbol
554
                                lcd_printp_at (18, 0, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0);
555
 
556
                                draw_compass (12, 1, naviData->CompassHeading);
557
 
558
                                // Altitude
559
                                //note:lephisto:according to several sources it's /30
560
                                if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust))    // above 10m only write full meters
561
                                        write_ndigit_number_s (0, 1, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0);
562
                                else    // up to 10m write meters.dm
563
                                        write_ndigit_number_s_10th (0, 1, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0);
564
 
565
                                lcd_putc (4, 1, 'm', 0);
566
 
567
                                draw_variometer (54, 7, 10, 14, naviData->Variometer);
568
 
569
                                // TODO: verify correctness
570
                                uint16_t heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
571
                                lcd_ecirc_line (22, 35, 15, old_hh, 0);
572
                                old_hh = heading_home;
573
                                lcd_ecirc_line (22, 35, 15, heading_home, 1);
574
 
575
                                write_ndigit_number_u (7, 3, heading_home, 3, 0);
576
                                lcd_putc (10, 3, 0x1e, 0);      // degree symbol
577
 
578
                                write_ndigit_number_u (7, 2, naviData->HomePositionDeviation.Distance / 10, 3, 0);
579
                                lcd_putc (10, 2, 'm', 0);
580
 
581
                                // Sats in use
582
                                lcd_printp_at(11, 4, PSTR("Sats"), 0);
583
                                write_ndigit_number_u (8, 4, naviData->SatsInUse, 2, 0);
584
 
585
                                if (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL)
586
                                        lcd_putc (19, 4, 'M', 0); // rc transmitter
587
                                else
588
                                        lcd_putc (19, 4, 'X', 0); // clear
589
 
590
                                if (naviData->NCFlags & NC_FLAG_CH)
591
                                        lcd_printp_at (8, 5, PSTR("Coming Home"), 0);
592
                                else if (naviData->NCFlags & NC_FLAG_PH)
593
                                        lcd_printp_at (8, 5, PSTR("Pos. Hold  "), 0);
594
                                else    // (naviData->NCFlags & NC_FLAG_FREE)
595
                                        lcd_printp_at (8, 5, PSTR("Free       "), 0);
596
 
597
                                // Flying time
598
                                write_time (7, 6, naviData->FlyingTime);
599
                                lcd_printp_at (12, 6, PSTR("h"), 0);
600
 
601
                                // RC
602
                                write_ndigit_number_u (15, 6, naviData->RC_Quality, 3, 0);
603
                                lcd_printp_at(18, 6, PSTR("\x1F"), 0);          // RC-transmitter
604
                                if (naviData->NCFlags & NC_FLAG_NOSERIALLINK)
605
                                {
606
                                        lcd_printpns_at(19, 6, PSTR("  "), 0);          // clear
607
                                }
608
                                else
609
                                {
610
                                        lcd_printpns_at(19, 6, PSTR("PC"), 0);
611
                                }
612
 
613
                                // Battery level
614
                                write_ndigit_number_u_10th (0, 7, naviData->UBat, 3, 0);
615
                                lcd_putc (4, 7, 'V', 0);
616
 
617
                                // Akku Warnung
618
                                if (naviData->UBat < MK_LowBat)
619
                                { //Beeper ein
620
                                        BeepTime = 3000;
621
                                        BeepMuster = 0x0020;
622
                                }
623
 
624
                                //if (naviData->UBat > MK_LowBat+2)  //bei kurzzeitigen Schwankungen Beeper erst wieder aus wenn UBat 0,2 V höher als Warnschwelle
625
                                //{ //Beeper aus
626
                                //      BeepTime = 0;
627
                                //      BeepMuster = 0xFFFF;
628
                                //}
629
                                // Akku Warnung Ende
630
 
631
                                // Current
632
                                write_ndigit_number_u_10th (7, 7, naviData->Current, 3, 0);
633
                                lcd_putc (11, 7, 'A', 0);
634
 
635
                                // Capacity
636
                                write_ndigit_number_u (14, 7, naviData->UsedCapacity, 4, 0);
637
                                lcd_printp_at(18, 7, PSTR("mAh"), 0);
638
 
639
                                // remember statistics (only when engines running)
640
                                if (naviData->FCFlags & FCFLAG_MOTOR_RUN)
641
                                {
642
                                        if (naviData->Altimeter > max_Altimeter) max_Altimeter = naviData->Altimeter;
643
                                        if (naviData->GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData->GroundSpeed;
644
                                        if (naviData->HomePositionDeviation.Distance > max_Distance) max_Distance = naviData->HomePositionDeviation.Distance;
645
                                        if (naviData->UBat < min_UBat) min_UBat = naviData->UBat;
646
                                        if (naviData->FlyingTime > max_FlyingTime) max_FlyingTime = naviData->FlyingTime;
647
                                        if (naviData->Current > max_Current) max_Current = naviData->Current;
648
                                        if (naviData->UsedCapacity > max_Capacity) max_Capacity = naviData->UsedCapacity;
649
                                }
650
 
651
                                // remember last values
652
                                last_RC_Quality = naviData->RC_Quality;
653
                                last_UBat = naviData->UBat;
654
                                old_FCFlags = naviData->FCFlags;
655
 
656
                                rxd_buffer_locked = FALSE;
657
                        }
658
        // 3D Lage anzeige beginnt hier -----------------------------------
659
                        else if (OSD_Mode == 3)
660
                        {
661
                                uint16_t head_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360;
662
 
663
                                lcd_cls ();
664
 
665
                                lcd_line(0,32,128,32,1);   // horizontal //
666
                                lcd_line(64,0,64,64,1);    // vertical   //
667
                                lcd_printp_at(12, 7, PSTR("End  Info"), 0);
668
 
669
 
670
                                // 45' Angel
671
                                lcd_line(62,11,66,11,1);   //    --    //
672
                                lcd_line(22,30,22,34,1);   //  |       //
673
                                lcd_line(106,30,106,34,1); //       |  //
674
                                lcd_line(62,53,66,53,1);   //    --    //
675
 
676
                                if (info_3D == 1)
677
                                {
678
                                        lcd_line(34,17,36,15,1);   //  /       //
679
                                        lcd_line(92,15,94,17,1);   //       \  //
680
                                        lcd_line(34,47,36,49,1);   //  \       //
681
                                        lcd_line(92,49,94,47,1);   //       /  //
682
 
683
//                                      lcd_printp_at(9, 0, PSTR("V"), 0);
684
//                                      lcd_printp_at(0, 3, PSTR("L"), 0);
685
//                                      lcd_printp_at(20, 3, PSTR("R"), 0);
686
//                                      lcd_printp_at(9, 7, PSTR("H"), 0);
687
 
688
                                        lcd_puts_at(9, 0, strGet(OSD_V), 0);
689
                                        lcd_puts_at(0, 3, strGet(OSD_L), 0);
690
                                        lcd_puts_at(20, 3, strGet(OSD_R), 0);
691
                                        lcd_puts_at(9, 7, strGet(OSD_H), 0);
692
 
693
                                        lcd_printp_at(0, 0, PSTR("N:"), 0);
694
                                        write_ndigit_number_s (2, 0, naviData->AngleNick, 3, 0);
695
 
696
                                        lcd_printp_at(0, 7, PSTR("R:"), 0);
697
                                        write_ndigit_number_s (2, 7, naviData->AngleRoll, 3, 0);
698
 
699
                                        lcd_printp_at(15, 0, PSTR("K:"), 0);
700
                                        write_ndigit_number_s (18, 0,head_home, 3, 0);
701
                                }
702
 
703
                                if (get_key_press (1 << KEY_ENTER))
704
                                {
705
                                        info_3D++;
706
                                        if (info_3D > 1)
707
                                                info_3D = 0;
708
                                }
709
 
710
                                uint8_t Nick = ((-naviData->AngleNick/2)+32);
711
                                uint8_t Roll = -naviData->AngleRoll+64;
712
                                lcd_ecircle(old_AngleRoll,old_AngleNick, 10, 0);
713
                                lcd_ecirc_line (old_AngleRoll, old_AngleNick, 9, old_hh, 0);
714
 
715
                                lcd_ecircle(Roll, Nick, 10, 1);
716
                                lcd_ecirc_line (Roll, Nick, 9, head_home, 1);
717
 
718
                                old_hh = head_home;
719
                                old_AngleNick = Nick;
720
                                old_AngleRoll = Roll;
721
                                // remember last values
722
                                last_RC_Quality = naviData->RC_Quality;
723
                                last_UBat = naviData->UBat;
724
                                old_FCFlags = naviData->FCFlags;
725
                                rxd_buffer_locked = FALSE;
726
                        }
727
 
728
                        if (!abo_timer)
729
                        {       // renew abo every 3 sec
730
                                // request OSD Data from NC every 100ms
731
                                //      RS232_request_mk_data (1, 'o', 100);
732
                                tmp_dat = 10;
733
                                SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
734
 
735
                                abo_timer = ABO_TIMEOUT;
736
                        }
737
                }
1518 - 738
            if (!timer)
739
              {
740
                OSD_Timeout(flag);
741
                flag = 0;
742
              }
1517 - 743
        }
744
 
1518 - 745
        while (!get_key_press (1 << KEY_ESC));
746
//        while (!get_key_press (1 << KEY_ESC) && timer);
747
//      get_key_press(KEY_ALL);
748
//
749
//
750
//      // disable OSD Data from NC
751
//      //      RS232_request_mk_data (1, 'o', 0);
752
//      tmp_dat = 0;
753
//      SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1);
754
//
755
//      mode = 0;
756
//      rxd_buffer_locked = FALSE;
757
//
758
//
759
//      // Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!!
760
//      if (!timer)
761
//      {       // timeout occured
762
//              if (flag)
763
//              {
764
//                      // Falls Spannungswarnung an war Beeper aus//
765
//                      BeepTime = 0;
766
//                      BeepMuster = 0xFFFF;
767
//
768
//                      lcd_cls ();
769
//                      WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude);  // im EEprom speichern
770
//                      lcd_puts_at(0, 0, strGet(OSD_ERROR), 2);
771
//
772
////                    lcd_printp_at (0, 0, PSTR(" ERROR: Datenverlust "), 2);
773
//
774
////                    lcd_printp_at (0, 2, PSTR("Letzte bekannte"), 0);
775
////                    lcd_printp_at (0, 3, PSTR("Position gespeichert."), 0);
776
//                        lcd_puts_at(0, 2, strGet(OSD_POS1), 0);
777
//                        lcd_puts_at(0, 3, strGet(OSD_POS2), 0);
778
////                    lcd_printp_at (19, 7, PSTR("OK"), 0);
779
//                        lcd_puts_at(19, 7, strGet(OK), 0);
780
////                    lcd_printp_at (0, 5, PSTR(" Breitengr  Längengr "), 0);
781
//
782
//                      lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0);
783
//
784
//                      lcd_puts_at(12, 7, strGet(ENDE), 0);
785
//
786
//                      BeepTime = 1500;
787
//                      BeepMuster = 0x0040;
788
//                      error = 1;
789
//
790
//                      uint32_t lon = last5pos[0].Longitude;
791
//                      write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0);
792
//                      lcd_printp_at (3, 6, PSTR("."), 0);
793
//                      write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1);
794
//                      write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1);
795
//
796
//                      uint32_t lat = last5pos[0].Latitude;
797
//                      write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0);
798
//                      lcd_printp_at (14, 6, PSTR("."), 0);
799
//                      write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1);
800
//                      write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1);
801
//
802
//                      while (!get_key_press (1 << KEY_ENTER));
803
//
804
//                      timer = TIMEOUT;
805
//                      lcd_cls();
806
//                      return;
807
//
808
//              }
809
//      }
1517 - 810
}
811