0,0 → 1,2725 |
/***************************************************************************** |
* Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de * |
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net * |
* Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net * |
* Copyright (C) 2011 Harald Bongartz * |
* * |
* This program is free software; you can redistribute it and/or modify * |
* it under the terms of the GNU General Public License as published by * |
* the Free Software Foundation; either version 2 of the License. * |
* * |
* This program is distributed in the hope that it will be useful, * |
* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
* GNU General Public License for more details. * |
* * |
* You should have received a copy of the GNU General Public License * |
* along with this program; if not, write to the * |
* Free Software Foundation, Inc., * |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
* * |
* * |
* Credits to: * |
* Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN * |
* http://www.mikrokopter.de * |
* Gregor "killagreg" Stobrawa for his version of the MK code * |
* Thomas Kaiser "thkais" for the original project. See * |
* http://www.ft-fanpage.de/mikrokopter/ * |
* http://forum.mikrokopter.de/topic-4061-1.html * |
* Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code * |
* http://www.mylifesucks.de/oss/c-osd/ * |
* Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility* |
*****************************************************************************/ |
|
//############################################################################ |
//# HISTORY osd.c |
//# |
//# 10.03.2013 OG |
//# - fix: doppelte Degree-Anzeige in OSD_Element_CompassDegree() |
//# - add: neuer Screen "MK-Status" |
//# - add: 7 neue OSD-Flags |
//# - chg: Screen-Refresh Zeit via timer2 (einstellbar durch define OSD_REFRESH_TIME) |
//# - chg: mit define OSD_DEBUG_SCREEN kann ein zusaetzlicher Screen verwendet werden zum testen/entwickeln |
//# - del: entfernt CFG2_HEIGHT_LIMIT in OSD_Element_AltitudeControl() (bis bessere Loesung gefunden ist) |
//# |
//# 08.03.2013 OG |
//# - del: OSD_Screen_Element() und cleanup in osd.h |
//# - add: OSD_Element_UpDown() (steigend/sinken via Pfeilen) |
//# - chg: OSD_Element_UpDown() in Screen "General" und "Navigation" hinzugefuegt (rechts neben der Hoehenanzeige) |
//# - chg: Screen "General" die Sat-Warnung wurde auf OSD_Element_Flag(OSD_FLAG_S0) geaendert |
//# - chg: Anzeige von Flag 'nicht genug GPS-Sateliten' (OSD_FLAG_S0) auf "S!" geändert |
//# |
//# 07.03.2013 OG |
//# - Hinweis bzgl. LowBatt-Anzeige in den Screens "General" und "Navigation": |
//# Es gibt zwei unabhängige LowBatt-Warnungen. |
//# 1. die PKT LowBatt-Warnung: sie arbeitet mit der im PKT hinterlegten |
//# LowBatt Spannung und stellt den Spannungswert inkl. der Einheit "V" |
//# invers dar wenn der Warnwert erreicht wurde (inkl. lautem PKT-Peepen) |
//# 2. die MK-LowBatt Warnung: hierbeit wird das Flag "BA" angezeigt wenn |
//# der MK eine LowBatt Warnung sendet |
//# Dadurch hat man nun zwei verschiedene LowBatt Warnungen die man auf Wunsch |
//# verschieden einstellen kann. Bei mir ist die PKT-LowBatt etwas niedriger |
//# eingestellt als die MK-Warnung und bedeutet "es ist aller hoechste Zeit zu landen". |
//# Die Spannung der MK-LowBat ist ein wenig hoeher eingestellt und |
//# zeigt mir "es ist bald Zeit zu landen". |
//# - del: Kommunikation zu FC - siehe Kommentare in osd() |
//# - chg: Kommunikation zu NC - siehe Kommentare in osd() |
//# - add: neuer Screen "Navigation" |
//# - chg: Layout Screen "Statistics" - Einheiten um zwei Pixel nach rechts verschoben |
//# - chg: Layout von Screen "General" modifiziert (u.a. xoffs,yoffs Pixelverschiebungen) |
//# - add: OSD_FLAG_BA in Screen "General" |
//# - add: die OSD_Element_xyz() Funktionen in osd.h aufgenommen |
//# - chg: an verschiedenen Stellen die Char-Drawmode defines MNORMAL, MINVERS, usw. eingebaut |
//# - del: Kompatibilitaetscode fuer "3D-Lage" ueber Hauptmenue entfernt |
//# - chg: die Funktionen OSD_Element_Switch() und OSD_Element_SwitchLabel() heissen |
//# nun OSD_Element_Flag() und OSD_Element_Flag_Label() |
//# - chg: die defines OSD_SWITCH_xy heissen jetzt OSD_FLAG_xy |
//# - fix: letzte GPS-Koordinaten werden jetzt permanent Config.LastLatitude, Config.LastLongitude gespeichert |
//# |
//# 03.03.2013 OG |
//# - add: delay in Mainloop von osd() um springende Werte abzudaempfen (TEST) |
//# - add: Startverzoegerung der Screens bis NaviData sich etwas stabilisiert hat (TEST) |
//# - add: OSD Startup Message "connecting MK..." |
//# - add: 'Emergency Landing' (EL) Anzeige in Screen "General" |
//# - del: OUT1/OUT2 Anzeige in Screen "General" |
//# - add: RC-Quality in Screen "General" |
//# - add: func: draw_symbol_rc() (alternative RC-Quality Symbol) |
//# - fix: Hoehenanzeige fuer Screens "OSD0" und "OSD1" |
//# - fix: OSD_Element_SwitchLabel() angepasst fuer x=0 und y=0 |
//# - add: OSD_Element_Switch/Label() erweitert um OSD_SWITCH_FS |
//# - fix: Screen-Redraw nach OSD_Timeout() und anderen Fehlermeldungen |
//# - chg: messages.c: STATS_ITEM_0 bis STATS_ITEM_6 angepasst (1 char kuerzer) |
//# - chg: Layout von OSD_Info() - mehr background-clear und etwas kleiner |
//# |
//# 02.03.2013 OG |
//# - chg: keine internal func in Screen's wegen warnings bei anderen |
//# - del: Screen "OSD3" |
//# - fix: Hoehenanzeige in Screen "General" (Minuszeichen) |
//# - add: MK LowBat Warning in Screen "General" |
//# - add: neues Degree Symbol (als func) in Screen General (kleiner als das Char 0x1E) |
//# - add: weitere Flags in OSD_Element_Flag() |
//# |
//# 01.03.2013 OG |
//# - Reskrukturierung Code (+ neuer OSD-Screens und einiges mehr) |
//############################################################################ |
|
|
//############################################################################ |
//# HINWEISE: |
//# |
//# 1. define: OSD_DEMO |
//# mit define OSD_DEMO wird ein Demo-Modus bei den neuen Screens einge- |
//# schaltet - damit werden u.a. alle Flag's angezeigt fuer Scree-Fotos |
//# |
//# 2. define: OSD_DEBUG_SCREEN |
//# mit diesem define wird ein zusaetzlicher Screen "Debug" einkompiliert |
//# fuer Test / Experimente / Debug von OSD-Elementen |
//# |
//# 3. Informationen zum Display |
//# DOG: 128 x 64 Pixel with 6x8 Font => 21 x 8 |
//############################################################################ |
|
|
#include "../cpu.h" |
#include <avr/io.h> |
#include <inttypes.h> |
#include <stdlib.h> |
#include <avr/pgmspace.h> |
#include <util/delay.h> |
|
#include "../main.h" |
#include "../osd/osd.h" |
#include "../lcd/lcd.h" |
#include "../timer/timer.h" |
#include "../uart/usart.h" |
#include "../eeprom/eeprom.h" |
#include "../messages.h" |
#include "../parameter.h" |
#include "../sound/pwmsine8bit.h" |
#include "../mk-data-structs.h" |
|
|
//#define OSD_DEMO // zeigt Demo-Daten in den OSD-Screens (sofern vom Screen unterstuetzt) |
//#define OSD_DEBUG_SCREEN // zusaetzlichen Debug-Screen aktivieren |
|
#define OSD_REFRESH_TIME 45 // Screen Refresh; ein Wert von 100 entspricht ca. 1 Sekunde (Steuerung via timer2) |
|
#define COSD_WASFLYING 4 |
#define TIMEOUT 200 // 2 sec |
|
|
// Hier Höhenanzeigefehler Korrigieren |
#define AltimeterAdjust 1.5 |
|
|
// global definitions and global vars |
NaviData_t *naviData; |
mk_param_struct_t *mk_param_struct; |
uint8_t Flags_ExtraConfig; |
uint8_t Flags_GlobalConfig; |
uint8_t Flags_GlobalConfig3; |
unsigned char Element; |
uint16_t heading_home; |
uint8_t drawmode; |
|
// flags from last round to check for changes |
uint8_t old_FCFlags = 0; |
uint8_t old_AngleNick = 0; |
uint8_t old_AngleRoll = 0; |
uint16_t old_hh = 0; |
|
// stats for after flight |
int16_t max_Altimeter = 0; |
uint16_t max_GroundSpeed = 0; |
int16_t max_Distance = 0; |
uint8_t min_UBat = 255; |
uint16_t max_FlyingTime = 0; |
uint16_t max_Current = 0; |
uint16_t max_Capacity = 0; |
|
// cache old vars for blinking attribute, checkup is faster than full |
// attribute write each time |
volatile uint8_t last_UBat = 255; |
volatile uint8_t last_RC_Quality = 255; |
|
volatile uint16_t ftimer = 0; |
volatile uint8_t OSD_active; |
|
uint8_t Vario_Beep_Up = 0; |
uint8_t Vario_Beep_Down = 0; |
uint8_t Vario_Beep_Up_Interval = 9; |
uint8_t Vario_Beep_Down_Interval = 6; |
uint8_t Vario_Threshold = 0; |
uint8_t Vario_Threshold_Value = 7; |
uint8_t OldWP = 0; |
uint8_t NextWP = 0; |
|
|
|
//char* rose = "-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W-+-N-+-O-+-S-+-W"; |
const char rose[48] PROGMEM = { |
0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S', |
0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N', 0x0e, 0x0f, 0x0e, 'O', |
0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W', 0x0e, 0x0f, 0x0e, 'N', |
0x0e, 0x0f, 0x0e, 'O', 0x0e, 0x0f, 0x0e, 'S', 0x0e, 0x0f, 0x0e, 'W', |
}; |
|
// the center is char 19 (north), we add the current heading in 8th |
// which would be 22.5 degrees, but float would bloat up the code |
// and *10 / 225 would take ages... so we take the uncorrect way |
|
const char str_NE[] PROGMEM = "NE"; |
const char str_E[] PROGMEM = "E "; |
const char str_SE[] PROGMEM = "SE"; |
const char str_S[] PROGMEM = "S "; |
const char str_SW[] PROGMEM = "SW"; |
const char str_W[] PROGMEM = "W "; |
const char str_NW[] PROGMEM = "NW"; |
const char str_N[] PROGMEM = "N "; |
const char *directions_p[8] PROGMEM = { |
str_NE, |
str_E, |
str_SE, |
str_S, |
str_SW, |
str_W, |
str_NW, |
str_N |
}; |
|
|
#define MAX_CELL_VOLTAGE 43 // max cell voltage for LiPO |
#define MIN_CELL_VOLTAGE 32 // min cell voltage for LiPO |
|
// Flags |
GPS_Pos_t last5pos[7]; |
uint8_t COSD_FLAGS2 = 0; |
volatile uint8_t error = 0; |
uint8_t cells = 0; |
uint8_t BattLowVoltageWarning = 0; |
uint8_t CellIsChecked = 0; |
uint8_t AkkuWarnThreshold = 0; |
uint16_t duration = 0; |
|
|
|
//########################################################### |
//########################################################### |
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void variobeep(int16_t vario) |
{ |
{ //start Beep |
|
if (vario >0 ) // MK steigt |
{ |
Vario_Beep_Down = 0; // Down Beep freischalten |
Vario_Threshold++; |
|
if ((Vario_Beep_Up == 0) && (Vario_Threshold >= Vario_Threshold_Value)) |
{ |
// set_beep ( 100, 0xffff, BeepNormal); |
duration = 52 -vario; |
// if (duration =0); duration = 1; |
|
// write_ndigit_number_u (0,6,duration,5,0); |
|
playTone(300+vario*2,duration,Config.Volume); |
// playTone(300,duration,volume); |
Vario_Threshold = Vario_Threshold_Value; // auf Maximalwert begrenzen |
} |
Vario_Beep_Up++; // Interval hochzählen in dem nicht gepiept wird |
if (Vario_Beep_Up == Vario_Beep_Up_Interval) Vario_Beep_Up = 0; |
} |
|
if (vario <0) // MK fällt |
{ |
Vario_Beep_Up = 0; // Up Beep freischalten |
Vario_Threshold++; |
if ((Vario_Beep_Down == 0) && (Vario_Threshold >= Vario_Threshold_Value)) |
{ |
duration = 50 -vario; |
// write_ndigit_number_u (0,7,duration,5,0); |
// if (duration < vario) ; duration = 0; |
// playTone(300,50,volume); |
|
|
playTone(300+vario*2,duration,Config.Volume); |
Vario_Threshold = Vario_Threshold_Value; // auf Maximalwert begrenzen |
} |
Vario_Beep_Down++; // Interval hochzählen in dem nicht gepiept wird |
if (Vario_Beep_Down == Vario_Beep_Down_Interval) Vario_Beep_Down = 0; |
} |
|
if (vario == 0) Vario_Threshold = 0; //Startverzögerung löschen |
} // end Beep |
|
} |
|
|
//-------------------------------------------------------------- |
// Diese Funktion Beept unabhaengig von der Einstellung Config.OSD_VarioBeep |
// Aufruf ggf. mit: if( Config.OSD_VarioBeep ) Beep_Vario(); |
// |
// Ansonten: |
// -> hier noch aufräumen in Zusammenhang mit func variobeep() |
//-------------------------------------------------------------- |
void Beep_Vario(void) |
{ |
if ( (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN) && (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL)) |
{ //start Beep |
if (naviData->Variometer <0) // MK fällt |
{ |
Vario_Beep_Up = 0; // Up Beep freischalten |
Vario_Threshold++; |
if ((Vario_Beep_Down == 0) && (Vario_Threshold >= Vario_Threshold_Value)) |
{ |
|
if (!Config.HWSound) set_beep ( 300, 0xffff, BeepNormal); |
else variobeep(naviData->Variometer); |
|
Vario_Threshold = Vario_Threshold_Value; // auf Maximalwert begrenzen |
} |
Vario_Beep_Down++; // Interval hochzählen in dem nicht gepiept wird |
if (Vario_Beep_Down == Vario_Beep_Down_Interval) Vario_Beep_Down = 0; |
} |
|
if (naviData->Variometer == 0) Vario_Threshold = 0; //Startverzögerung löschen |
|
if (naviData->Variometer >0 ) // MK steigt |
{ |
Vario_Beep_Down = 0; // Down Beep freischalten |
Vario_Threshold++; |
|
if ((Vario_Beep_Up == 0) && (Vario_Threshold >= Vario_Threshold_Value)) |
{ |
if (!Config.HWSound) set_beep ( 100, 0xffff, BeepNormal); |
else variobeep(naviData->Variometer); |
Vario_Threshold = Vario_Threshold_Value; // auf Maximalwert begrenzen |
} |
Vario_Beep_Up++; // Interval hochzählen in dem nicht gepiept wird |
if (Vario_Beep_Up == Vario_Beep_Up_Interval) Vario_Beep_Up = 0; |
} |
} // end Beep |
} |
|
|
|
//-------------------------------------------------------------- |
// Quelle Mikrokopter FC-Software Holger + Ingo |
//-------------------------------------------------------------- |
void CheckMKLipo(void) |
{ |
if(Config.MK_LowBat < 50) // automatische Zellenerkennung |
{ |
if (CellIsChecked <= 2) //Nur beim Start 1x prüfen |
{ |
// up to 6s LiPo, less than 2s is technical impossible |
for(cells = 2; cells < 7; cells++) |
{ |
if(naviData->UBat < cells * MAX_CELL_VOLTAGE) break; |
} |
BattLowVoltageWarning = cells * Config.MK_LowBat; |
CellIsChecked++; |
} |
} |
else BattLowVoltageWarning = Config.MK_LowBat; |
|
if (naviData->UBat < BattLowVoltageWarning) |
{ |
if (AkkuWarnThreshold <= 4) AkkuWarnThreshold++; |
else |
{ //Beeper ein |
set_beep ( 1000, 0x0020, BeepSevere); |
// BeepTime = 3000; |
// BeepMuster = 0x0020; |
} |
} |
} |
|
|
//-------------------------------------------------------------- |
// convert the <heading> gotton from NC into an index |
uint8_t heading_conv (uint16_t heading) |
{ |
if (heading > 23 && heading < 68) |
return 0; //direction = "NE"; |
else if (heading > 67 && heading < 113) |
return 1; //direction = "E "; |
else if (heading > 112 && heading < 158) |
return 2; //direction = "SE"; |
else if (heading > 157 && heading < 203) |
return 3; //direction = "S "; |
else if (heading > 202 && heading < 248) |
return 4; //direction = "SW"; |
else if (heading > 247 && heading < 293) |
return 5; //direction = "W "; |
else if (heading > 292 && heading < 338) |
return 6; //direction = "NW"; |
|
return 7; //direction = "N "; |
} |
|
|
//-------------------------------------------------------------- |
// draw a compass rose at <x>/<y> for <heading> |
void draw_compass (uint8_t x, uint8_t y, uint16_t heading) |
{ |
uint8_t front = 19 + (heading / 22); |
for (uint8_t i = 0; i < 9; i++) |
lcd_putc (x++, y, pgm_read_byte(&rose[front - 4 + i]), 0); |
} |
|
|
//-------------------------------------------------------------- |
// variometer |
// x, y in Pixel! |
//-------------------------------------------------------------- |
void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer) |
{ |
lcd_rect (x, y - ((hight) / 2), width, hight, 1); |
lcd_frect (x + 1, y - ((hight) / 2) + 1, width - 2, hight - 2, 0); |
lcd_line (x, y, x + width, y, 1); |
|
if (variometer > 0) // steigend |
{ |
switch (variometer / 5) |
{ |
case 0: |
lcd_line (x + 4, y - 1, x + 6, y - 1, 1); // 1 > 4 |
break; |
|
case 1: |
lcd_line (x + 4, y - 1, x + 6, y - 1, 1); // 1 > 4 |
lcd_frect (x + 3, y - 3, 4, 1, 1); // 5 > 9 |
break; |
|
case 2: |
lcd_line (x + 4, y - 1, x + 6, y - 1, 1); // 1 > 4 |
lcd_frect (x + 3, y - 3, 4, 1, 1); // 5 > 9 |
lcd_frect (x + 2, y - 5, 6, 1, 1); // 10 > 14 |
break; |
|
default: |
lcd_line (x + 4, y - 1, x + 6, y - 1, 1); // 1 > 4 |
lcd_frect (x + 3, y - 3, 4, 1, 1); // 5 > 9 |
lcd_frect (x + 2, y - 5, 6, 1, 1); // 10 > 14 |
lcd_frect (x + 1, y - 6, 8, 1, 1); // 15 > |
break; |
} |
} |
else if (variometer < 0) // fallend |
{ |
switch ((variometer) / -5) |
{ |
case 0: |
lcd_line (x + 4, y + 1, x + 6, y + 1, 1); // - 1 > - 4 |
break; |
|
case 1: |
lcd_line (x + 4, y + 1, x + 6, y + 1, 1); // - 1 > - 4 |
lcd_frect (x + 3, y + 2, 4, 1, 1); // - 5 > - 9 |
break; |
|
case 2: |
lcd_line (x + 4, y + 1, x + 6, y + 1, 1); // - 1 > - 4 |
lcd_frect (x + 3, y + 2, 4, 1, 1); // - 5 > - 9 |
lcd_frect (x + 2, y + 4, 6, 1, 1); // -10 > -14 |
break; |
|
default: |
lcd_line (x + 4, y + 1, x + 6, y + 1, 1); // - 1 > - 4 |
lcd_frect (x + 3, y + 2, 4, 1, 1); // - 5 > - 9 |
lcd_frect (x + 2, y + 4, 6, 1, 1); // -10 > -14 |
lcd_frect (x + 1, y + 5, 8, 1, 1); // -15 > |
break; |
} |
} |
} |
|
|
//-------------------------------------------------------------- |
// variometer 2 |
// |
// x, y in Pixel |
// x, y top, left |
//-------------------------------------------------------------- |
/* |
void draw_variometer2( uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer) |
{ |
uint8_t max = 5; // max: 5 m/sec == 100% |
|
lcd_rect (x, y, width, hight, 1); |
lcd_frect(x + 1, y + 1, width - 2, hight - 2, 0); |
lcd_line (x, y + ((hight) / 2), x + width, y + ((hight) / 2), 1); |
|
} |
*/ |
|
|
//-------------------------------------------------------------- |
// Home symbol |
// draw Homesymbol at <x>/<y> |
//-------------------------------------------------------------- |
void draw_homesymbol (uint8_t x, uint8_t y) |
{ |
x *= 6; |
y *= 8; |
y += 7; |
|
lcd_plot (x,y-4,1); |
lcd_line (x+1,y-1,x+1,y-5,1); |
lcd_plot (x+2,y-6,1); |
lcd_plot (x+3,y-7,1); |
lcd_plot (x+4,y-6,1); |
lcd_line (x+5,y-1,x+5,y-5,1); |
lcd_plot (x+6,y-4,1); |
lcd_plot (x+3,y-1,1); |
lcd_plot (x+3,y-2,1); |
lcd_line (x+1,y,x+5,y,1); |
|
} |
|
//-------------------------------------------------------------- |
// Target symbol |
// draw Targetsymbol at <x>/<y> |
//-------------------------------------------------------------- |
void draw_targetsymbol (uint8_t x, uint8_t y) |
{ |
x *= 6; |
y *= 8; |
y += 7; |
|
lcd_circle (x+3, y-3, 4, 1); |
lcd_line (x,y-3,x+6,y-3,1); |
lcd_line (x+3,y,x+3,y-6,1); |
lcd_circle (x+3, y-3, 2, 1); |
} |
|
|
//-------------------------------------------------------------- |
// Degree symbol |
// draw Degreesymbol at <x>/<y> |
// |
// Ein etwas kleineres Degeree als Char 0x1E |
//-------------------------------------------------------------- |
void draw_symbol_degree (uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs) |
{ |
x *= 6; |
y *= 8; |
lcd_rect (x+1+xoffs, y+yoffs, 2, 2, 1); |
} |
|
|
//-------------------------------------------------------------- |
// RC symbol |
// alternatives Symbol fuer RC-Quality |
//-------------------------------------------------------------- |
void draw_symbol_rc (uint8_t x, uint8_t y) |
{ |
x *= 6; |
y *= 8; |
y += 1; |
x += 1; |
|
lcd_plot ( x+3, y+4, 1); |
lcd_line ( x+2, y+2, x+4, y+2, 1); |
lcd_line ( x+1, y+0, x+5, y+0, 1); |
} |
|
|
//-------------------------------------------------------------- |
void print_position (void) |
{ |
lcd_cls (); |
lcd_puts_at(0, 0, strGet(START_LASTPOS1), 2); // Breitengr Längengr |
lcd_puts_at(12, 7, strGet(ENDE), 0); |
uint8_t ij =0; |
|
for(ij=0;ij<6;ij++) |
{ |
uint32_t lon = last5pos[ij].Latitude; |
write_ndigit_number_u (1, ij+1, (uint16_t)(lon/10000000), 2, 0,0); |
lcd_printp_at (3, ij+1, PSTR("."), 0); |
write_ndigit_number_u (4, ij+1, (uint16_t)((lon/1000) % 10000), 4, 1,0); |
write_ndigit_number_u (8, ij+1, (uint16_t)((lon/10) % 100), 2, 1,0); |
|
uint32_t lat = last5pos[ij].Longitude; |
write_ndigit_number_u (12, ij+1, (uint16_t)(lat/10000000), 2, 0,0); |
lcd_printp_at (14, ij+1, PSTR("."), 0); |
write_ndigit_number_u (15, ij+1, (uint16_t)((lat/1000) % 10000), 4, 1,0); |
write_ndigit_number_u (19, ij+1, (uint16_t)((lat/10) % 100), 2, 1,0); |
} |
|
while (!get_key_press (1 << KEY_ESC)) |
timer = TIMEOUT; |
|
get_key_press(KEY_ALL); |
lcd_cls(); |
} |
|
|
//-------------------------------------------------------------- |
void Show_LastPosition(void) |
{ |
lcd_puts_at(0, 2, strGet(OSD_POS1), 0); |
lcd_puts_at(0, 3, strGet(OSD_POS2), 0); |
lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0); |
uint32_t lon = last5pos[0].Latitude; |
write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0,0); |
lcd_printp_at (3, 6, PSTR("."), 0); |
write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1,0); |
write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1,0); |
|
uint32_t lat = last5pos[0].Longitude; |
write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0,0); |
lcd_printp_at (14, 6, PSTR("."), 0); |
write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1,0); |
write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1,0); |
|
} |
|
|
//-------------------------------------------------------------- |
void OSD_Timeout(uint8_t flag) |
{ |
|
// uint8_t flag; |
uint8_t tmp_dat; |
// flag = 0; |
timer = TIMEOUT; |
// disable OSD Data from NC |
// RS232_request_mk_data (1, 'o', 0); |
// tmp_dat = 0; |
// SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1); |
|
mode = 0; |
rxd_buffer_locked = FALSE; |
|
|
// Bei Verbindungsverlusst werden hier die letzten bekannten Koordinaten ausgegeben!!! |
if( flag ) |
{ |
// Falls Spannungswarnung an war Beeper aus// |
|
set_beep ( 0, 0, BeepOff); |
|
lcd_cls (); |
WriteLastPosition(last5pos[0].Longitude,last5pos[0].Latitude); // im EEprom speichern |
lcd_puts_at(0, 0, strGet(OSD_ERROR), 2); // ERROR: Datenverlust |
lcd_puts_at(0, 2, strGet(OSD_POS1), 0); // Letzte bekannte |
lcd_puts_at(0, 3, strGet(OSD_POS2), 0); // Position gespeichert. |
lcd_puts_at(0, 5, strGet(START_LASTPOS1), 0); // Breitengr Längengr |
// lcd_puts_at(12, 7, strGet(ENDE), 0); |
// lcd_puts_at(19, 7, strGet(OK), 0); |
// if (OSD_RCErrorbeep==true) |
// { |
set_beep ( 250, 0x0040, BeepNormal); |
// } |
|
uint32_t lon = last5pos[0].Latitude; |
write_ndigit_number_u (1, 6, (uint16_t)(lon/10000000), 2, 0,0); |
lcd_printp_at (3, 6, PSTR("."), 0); |
write_ndigit_number_u (4, 6, (uint16_t)((lon/1000) % 10000), 4, 1,0); |
write_ndigit_number_u (8, 6, (uint16_t)((lon/10) % 100), 2, 1,0); |
|
uint32_t lat = last5pos[0].Longitude; |
write_ndigit_number_u (12, 6, (uint16_t)(lat/10000000), 2, 0,0); |
lcd_printp_at (14, 6, PSTR("."), 0); |
write_ndigit_number_u (15, 6, (uint16_t)((lat/1000) % 10000), 4, 1,0); |
write_ndigit_number_u (19, 6, (uint16_t)((lat/10) % 100), 2, 1,0); |
|
// while (!get_key_press (1 << KEY_ENTER)); |
// _delay_ms(1000); |
timer = TIMEOUT; |
// lcd_cls(); |
// return; |
} |
else |
{ |
lcd_puts_at(0, 0, strGet(OSD_ERROR), 2); |
Show_LastPosition(); |
if (Config.OSD_RCErrorbeep==true) set_beep ( 200, 0x0080, BeepNormal); |
// _delay_ms(2000); |
} |
|
rxd_buffer_locked = FALSE; // 07.03.2013 OG: fix |
// es gab Probleme mit dem Empfang gueltiger NC-Daten, die zu unschoenen Starteffekten bei den |
// OSD-Screens gefuehrt haben. Mit rxd_buffer_locked = FALSE vor SwitchToNC() ist das PKT wieder im 'Takt' |
|
SwitchToNC(); |
|
mode = 'O'; |
|
// disable debug... |
// RS232_request_mk_data (0, 'd', 0); |
tmp_dat = 0; |
SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1); |
|
// request OSD Data from NC every 100ms |
// RS232_request_mk_data (1, 'o', 100); |
tmp_dat = 10; |
SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1); |
|
//_delay_ms(100); |
//rxd_buffer_locked = FALSE; |
} |
|
|
|
|
//----------------------------------------------------------- |
// |
void lcd_o_circle (uint16_t x, uint16_t y, int16_t breite, uint8_t mode, int8_t xoffs, int8_t yoffs) |
{ |
breite *= 6; |
int16_t radius = breite / 2; |
x += 2; |
x *= 6; |
x += 2; |
y += 1; |
y *= 8; |
y += 3; |
|
// 04.03.2012 OG: chg: x-radius von -3 auf -2 (runder auf dem display) |
//lcd_ellipse (x, y, radius - 3, radius - 5, mode); |
lcd_ellipse( x+xoffs, y+yoffs, radius - 2, radius - 5, mode); |
} |
|
|
//----------------------------------------------------------- |
// lcd_o_circ_line( x, y, breite, deg, rOffset, mode) |
// |
// x, y : in Chars |
// breite : in Chars |
// deg : in Pixel |
// rOffset: Beeinflusst den Schluss der Linie zum Huellkreis |
// 0 = Standard |
// >0 naeher zum Huellkreis |
// <0 entfernter vom Huellkreis |
// mode : siehe: lcd_ellipse_line() |
//----------------------------------------------------------- |
void lcd_o_circ_line( uint16_t x, uint16_t y, uint8_t breite, uint16_t deg, int8_t rOffset, uint8_t mode, int8_t xoffs, int8_t yoffs) |
{ |
breite *= 6; |
int16_t radius = breite / 3; |
x += 2; |
x *= 6; |
x += 2; |
y += 1; |
y *= 8; |
y += 3; |
|
// 04.03.2013 OG: der Radius kann mit rOffset >0 vergroessert werden um zum Kreis aufzuschliessen |
lcd_ellipse_line( x+xoffs, y+yoffs, radius+rOffset, radius+rOffset, deg, mode); |
} |
|
|
//-------------------------------------------------------------- |
void draw_icon_home(uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
lcd_rect( x+0, y+5, 10, 8, 1); // Mitte |
lcd_line( x+5, y+0, x+0, y+5, 1); // Dach Links |
lcd_line( x+5, y+0, x+10, y+5, 1); // Dach Rechts |
lcd_rect( x+4, y+10, 2, 3, 1); // Tuere |
|
} |
|
|
//-------------------------------------------------------------- |
void draw_icon_sat(uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
lcd_rect( x+0, y+2, 4, 2, 1); // linker Fluegel |
lcd_rect( x+8, y+2, 4, 2, 1); // rechter Fluegel |
lcd_rect( x+4, y+0, 4, 6, 1); // Mitte, oben |
lcd_line( x+6, y+7, x+2, y+11, 1); // Strahl Links |
lcd_line( x+6, y+7, x+10, y+11, 1); // Strahl Rechts |
lcd_line( x+1, y+12, x+11, y+12, 1); // Strahl Unten |
} |
|
|
//-------------------------------------------------------------- |
void draw_icon_battery(uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
lcd_rect( x+2, y+0, 2, 2, 1); // der kleine Knubbel oben |
lcd_rect( x+0, y+2, 6, 15, 1); // body |
} |
|
|
|
//############################################################## |
//# OSD-ELEMENTS |
//############################################################## |
|
//-------------------------------------------------------------- |
// OSD_Element_Flag_Label( xC, yC, item, lOn, xoffs, yoffs) |
// |
// xC, yC : x,y in Characters |
// item : OSD_FLAG_AH, OSD_FLAG_PH, usw. |
// lOn : true / false |
// xoffs,yoffs : x,y Pixelverschiebung |
//-------------------------------------------------------------- |
void OSD_Element_Flag_Label( uint8_t xC, uint8_t yC, uint8_t item, uint8_t lOn, int8_t xoffs, int8_t yoffs) |
{ |
int8_t x = (xC*6)-2; |
int8_t y = (yC*8)-1; |
uint8_t w = 14; |
uint8_t h = 8; |
|
const char *labels[OSD_FLAG_COUNT] = |
{ |
PSTR("AH"), // OSD_FLAG_AH Altitue Hold |
PSTR("PH"), // OSD_FLAG_PH Position Hold |
PSTR("CF"), // OSD_FLAG_CF Care Free |
PSTR("CH"), // OSD_FLAG_CH Coming Home |
PSTR("o1"), // OSD_FLAG_O1 Out1 |
PSTR("o2"), // OSD_FLAG_O2 Out2 |
PSTR("BA"), // OSD_FLAG_BA LowBat warning (MK) |
PSTR("CA"), // OSD_FLAG_CA Calibrate |
PSTR("ST"), // OSD_FLAG_ST Start |
PSTR("MR"), // OSD_FLAG_MR Motor Run |
PSTR("FY"), // OSD_FLAG_FY Fly |
PSTR("EL"), // OSD_FLAG_EL Emergency Landing |
PSTR("FS"), // OSD_FLAG_FS RX Failsave Active |
PSTR("GP"), // OSD_FLAG_GP GPS Ok |
PSTR("S!"), // OSD_FLAG_S0 GPS-Sat not ok (GPS NOT ok) |
PSTR("TU"), // OSD_FLAG_TU Vario Trim Up |
PSTR("TD"), // OSD_FLAG_TD Vario Trim Down |
PSTR("FR"), // OSD_FLAG_FR Free |
PSTR("RL"), // OSD_FLAG_RL Range Limit |
PSTR("SL"), // OSD_FLAG_SL No Serial Link |
PSTR("TR"), // OSD_FLAG_TR Target Reached |
PSTR("MC") // OSD_FLAG_MC Manual Control |
}; |
|
//lcd_plot( x-2, y-2, 1); // Referenz |
|
if( yC==0 ) { y = 0; h = 7; } |
if( xC==0 ) { x = 0; w = 12; } |
|
if( lOn ) |
{ |
lcd_frect( x+xoffs, y+yoffs, w, h, 1); // Filler |
lcdx_printp_at( xC, yC, labels[item], MINVERS, xoffs,yoffs); // Label |
} |
else |
{ |
lcd_frect( x+xoffs, y+yoffs, w, h, 0); // clear |
} |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_Flag( uint8_t xC, uint8_t yC, uint8_t item, int8_t xoffs, int8_t yoffs) |
{ |
uint8_t lOn = 0; |
|
// FC_StatusFlags 0.88 |
switch( item ) |
{ |
// Altitue Hold |
case OSD_FLAG_AH : lOn = (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL); |
break; |
|
// Position Hold |
case OSD_FLAG_PH : lOn = (naviData->NCFlags & NC_FLAG_PH); |
break; |
|
// Coming Home |
case OSD_FLAG_CH : lOn = (naviData->NCFlags & NC_FLAG_CH); |
break; |
|
// Care Free |
case OSD_FLAG_CF : lOn = (naviData->FCStatusFlags2 & FC_STATUS2_CAREFREE); |
break; |
|
// Out1 |
case OSD_FLAG_O1 : lOn = (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE); |
break; |
|
// Out2 |
case OSD_FLAG_O2 : lOn = (naviData->FCStatusFlags2 & FC_STATUS2_OUT2_ACTIVE); |
break; |
|
// LowBat warning (MK) |
case OSD_FLAG_BA : lOn = (naviData->FCStatusFlags & FC_STATUS_LOWBAT); |
break; |
|
// Calibrate |
case OSD_FLAG_CA : lOn = (naviData->FCStatusFlags & FC_STATUS_CALIBRATE); |
break; |
|
// Start |
case OSD_FLAG_ST : lOn = (naviData->FCStatusFlags & FC_STATUS_START); |
break; |
|
// Motor Run |
case OSD_FLAG_MR : lOn = (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN); |
break; |
|
// Fly |
case OSD_FLAG_FY : lOn = (naviData->FCStatusFlags & FC_STATUS_FLY); |
break; |
|
// Emergency Landing |
case OSD_FLAG_EL : lOn = (naviData->FCStatusFlags & FC_STATUS_EMERGENCY_LANDING); |
break; |
|
// RC Failsave Active |
case OSD_FLAG_FS : lOn = (naviData->FCStatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE); |
break; |
|
// GPS ok |
case OSD_FLAG_GP : lOn = (naviData->NCFlags & NC_FLAG_GPS_OK); |
break; |
|
// GPS-Sat not ok (GPS NOT ok) |
case OSD_FLAG_S0 : lOn = !(naviData->NCFlags & NC_FLAG_GPS_OK); |
break; |
|
// Vario Trim Up |
case OSD_FLAG_TU : lOn = (naviData->FCStatusFlags & FC_STATUS_VARIO_TRIM_UP); |
break; |
|
// Vario Trim Down |
case OSD_FLAG_TD : lOn = (naviData->FCStatusFlags & FC_STATUS_VARIO_TRIM_DOWN); |
break; |
|
// Free |
case OSD_FLAG_FR : lOn = (naviData->NCFlags & NC_FLAG_FREE); |
break; |
|
// Range Limit |
case OSD_FLAG_RL : lOn = (naviData->NCFlags & NC_FLAG_RANGE_LIMIT); |
break; |
|
// No Serial Link |
case OSD_FLAG_SL : lOn = (naviData->NCFlags & NC_FLAG_NOSERIALLINK); |
break; |
|
// Target Reached |
case OSD_FLAG_TR : lOn = (naviData->NCFlags & NC_FLAG_TARGET_REACHED); |
break; |
|
// Manual Control |
case OSD_FLAG_MC : lOn = (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL); |
break; |
|
} |
|
OSD_Element_Flag_Label( xC, yC, item, lOn, xoffs,yoffs); |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_AltitudeControl( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_AltitudeControl( uint8_t x, uint8_t y ) |
{ |
//--------------------------------------------------------- |
// 10.03.2013 OG: |
// CFG2_HEIGHT_LIMIT im Augenblick nicht unterstuetzt |
// Siehe Anmerkungen in osd() |
//--------------------------------------------------------- |
/* |
if (Flags_ExtraConfig & CFG2_HEIGHT_LIMIT) |
{ |
if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL) |
lcd_puts_at (x, y, strGet(OSD_ALTI_1), 0); // Höhe begr. |
else |
lcd_puts_at (x, y, strGet(OSD_ALTI_0), 0); // Höhe aus |
} |
else |
{ |
if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL) |
lcd_puts_at (x, y, strGet(OSD_VARIO_1), 0); // Vario Höhe |
else |
lcd_puts_at (x, y, strGet(OSD_VARIO_0), 0); // Vario aus |
} |
*/ |
|
if (naviData->FCStatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL) |
lcd_puts_at (x, y, strGet(OSD_VARIO_1), 0); // Vario Höhe |
else |
lcd_puts_at (x, y, strGet(OSD_VARIO_0), 0); // Vario aus |
|
} |
|
|
//-------------------------------------------------------------- |
// Anzeige von Steigen / Sinken |
//-------------------------------------------------------------- |
void OSD_Element_UpDown( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs) |
{ |
x = (x*6) + xoffs; |
y = (y*8) + yoffs; |
|
lcd_frect( x, y, 6, 7, 0); // clear |
|
if( naviData->Variometer > 2 ) // steigen mehr als 0.2 m/sec (ein guter Wert muss noch in der Praxis ermittelt werden) |
{ |
lcd_line( x+2, y+0, x+0, y+2, 1); |
lcd_line( x+2, y+0, x+4, y+2, 1); |
} |
else if( naviData->Variometer < -2 ) // sinken mehr als 0.2 m/sec |
{ |
lcd_line( x+2, y+6, x+0, y+4, 1); |
lcd_line( x+2, y+6, x+4, y+4, 1); |
} |
|
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_Altitude( x, y, nStyle) |
// nStyle entspricht dem ehemaligen 'Mode' |
//-------------------------------------------------------------- |
void OSD_Element_Altitude( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
switch( nStyle ) |
{ |
case 0 : |
case 1 : //note:lephisto:according to several sources it's /30 |
if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust)) // above 10m only write full meters |
write_ndigit_number_s (x, y, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL); |
else // up to 10m write meters.dm |
write_ndigit_number_s_10th (x, y, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0,MNORMAL); |
|
lcd_printp_at (x+4, y, PSTR("m"), MNORMAL); |
lcd_putc (x+5, y, 0x09, 0); // Hoehensymbol |
break; |
|
case 2 : //note:lephisto:according to several sources it's /30 |
if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust)) // above 10m only write full meters |
write_ndigit_number_s (x+4, y, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0,MBIG); |
else // up to 10m write meters.dm |
write_ndigit_number_s_10th (x+4, y, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0,MBIG); |
lcd_putc( x+8, y, 'm', MBIG); |
lcd_printp_at (x, y, PSTR("Höhe"), MNORMAL); |
break; |
} |
} |
|
|
//-------------------------------------------------------------- |
// fuer: Config.OSD_LipoBar==1 |
//-------------------------------------------------------------- |
void OSD_Element_BatteryLevel_Bar( uint8_t x, uint8_t y ) |
{ |
uint16_t Balken = 0; |
|
drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0); |
|
if( cells > 0 ) // LipobargraphAnzeige nur wenn Anzahl der Lipozellen bekannt sind |
{ |
write_ndigit_number_u (x+6, y, cells, 1, 0, drawmode); |
lcd_printp_at (x+7, y, PSTR("S"), drawmode); |
|
if( cells==3 ) |
{ |
lcd_rect(x*6, y*8, 28, 7, 1); // Rahmen |
Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/12; |
if((Balken > 0) && (Balken <28)) lcd_frect((x*6)+1, (y*8)+1, Balken, 5, 1); // Fuellung |
if(Balken <= 26) lcd_frect(Balken+(x*6)+1, (y*8)+1, 26-Balken, 5, 0); // loeschen |
} |
|
if( cells==4 ||cells==5 ) |
{ |
lcd_rect(x*6, y*8, 30, 7, 1); // Rahmen |
if (cells == 4) Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/15; |
if (cells == 5) Balken = ((naviData->UBat-(cells*MIN_CELL_VOLTAGE))*10)/19; |
if ((Balken > 0) && (Balken <=29)) lcd_frect((x*6)+1, (y*8)+1, Balken, 5, 1); // Fuellung |
if (Balken <= 27) lcd_frect(Balken+(x*6)+1, (y*8)+1, 28-Balken, 5, 0); // loeschen |
} |
|
} // end if: cells > 0 (TODO: Anzeige fuer cells==0 implementieren) |
} |
|
|
|
//-------------------------------------------------------------- |
// fuer die neuen OSD-Screens |
//-------------------------------------------------------------- |
void OSD_Element_BattLevel2( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs ) |
{ |
drawmode = (naviData->UBat < BattLowVoltageWarning ? MINVERS : MNORMAL); |
writex_ndigit_number_u_10th( x, y, naviData->UBat, 3, 0, drawmode, xoffs,yoffs); |
lcdx_printp_at( x+4, y, PSTR("V"), drawmode, xoffs+1,yoffs); // Einheit |
lcd_line( (x+4)*6, y*8, (x+4)*6, y*8+7, (drawmode==MINVERS ? 1 : 0) ); // filler zwischen Spannung und "V" |
|
} |
|
|
//-------------------------------------------------------------- |
// fuer: Config.OSD_LipoBar==0 |
// nStyle entspricht dem ehemaligen 'Mode' |
//-------------------------------------------------------------- |
void OSD_Element_BatteryLevel_Text( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
if( nStyle <= 1) |
drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0); // Normal-Schrift |
else |
drawmode = (naviData->UBat < BattLowVoltageWarning ? 4 : 3); // Fett-Schrift |
|
if( nStyle <= 1) |
{ |
write_ndigit_number_u_10th (x, y, naviData->UBat, 3, 0, drawmode); |
lcd_printp_at (x+4, y, PSTR("V"), drawmode); |
} |
else |
{ |
write_ndigit_number_u_10th (x-2, y, naviData->UBat, 3, 0, drawmode); |
lcd_printp_at (x+2, y, PSTR("V"), drawmode); |
} |
} |
|
|
//-------------------------------------------------------------- |
// nStyle entspricht dem ehemaligen 'Mode' |
//-------------------------------------------------------------- |
void OSD_Element_BatteryLevel( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
if( Config.OSD_LipoBar ) |
OSD_Element_BatteryLevel_Bar( x, y); |
else |
OSD_Element_BatteryLevel_Text( x, y, nStyle); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_Capacity( uint8_t x, uint8_t y ) |
{ |
drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? 2 : 0); |
|
write_ndigit_number_u (x, y, naviData->UsedCapacity, 5, 0, drawmode); |
lcd_printp_at (x+5, y, PSTR("mAh"), drawmode); |
// BeepTime = 3000; |
// BeepMuster = 0x0020; |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_CareFree( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_CareFree( uint8_t x, uint8_t y ) |
{ |
lcd_puts_at (x, y, strGet( naviData->FCStatusFlags2 & FC_STATUS2_CAREFREE ? OSD_CARE_FREE_1 : OSD_CARE_FREE_0 ), 0); |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_CompassDegree( x, y, nStyle) |
// nStyle entspricht dem ehemaligen 'Mode' |
//-------------------------------------------------------------- |
void OSD_Element_CompassDegree( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
switch( nStyle ) |
{ |
case 0 : |
case 1 : write_ndigit_number_u (x, y, naviData->CompassHeading, 3, 0,MNORMAL); |
x += 3; |
break; |
|
case 2 : write_ndigit_number_u (x, y, naviData->CompassHeading, 3, 0,MBIG); |
x += 8; |
break; |
} |
lcd_putc( x, y, 0x1E, MNORMAL); // degree symbol |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_CompassDirection( uint8_t x, uint8_t y ) |
{ |
lcd_printp_at (x, y, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_CompassRose( uint8_t x, uint8_t y ) |
{ |
draw_compass (x, y, naviData->CompassHeading); |
} |
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_Current( uint8_t x, uint8_t y ) |
{ |
write_ndigit_number_u_10th (x, y, naviData->Current, 3, 0,0); |
lcd_printp_at (x+4, y, PSTR("A"), 0); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_FlyingTime( uint8_t x, uint8_t y ) |
{ |
write_time (x, y, naviData->FlyingTime); |
lcd_printp_at (x+5, y, PSTR("m"), 0); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_GroundSpeed( uint8_t x, uint8_t y ) |
{ |
write_ndigit_number_u (x, y, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,0); |
lcd_printp_at (x+3, y, PSTR("Kmh"), 0); |
} |
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_HomeCircle( uint8_t x, uint8_t y, uint8_t breite, int8_t rOffset, int8_t xoffs, int8_t yoffs ) |
{ |
lcd_o_circle( x, y, breite, 1, xoffs,yoffs); |
|
if (Config.OSD_HomeMKView==1) |
heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360; |
else |
heading_home = (naviData->CompassHeading- naviData->HomePositionDeviation.Bearing + 360 ) % 360; |
|
lcd_o_circ_line( x, y, breite, old_hh , rOffset, 0, xoffs,yoffs); |
lcd_o_circ_line( x, y, breite, heading_home, rOffset, 1, xoffs,yoffs); |
|
old_hh = heading_home; |
} |
|
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_HomeDegree( uint8_t x, uint8_t y ) |
{ |
write_ndigit_number_u (x, y, heading_home, 3, 0,0); |
lcd_putc (x+3, y, 0x1e, 0); // degree symbol |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_HomeDistance( x, y, nStyle) |
//-------------------------------------------------------------- |
void OSD_Element_HomeDistance( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
switch( nStyle ) |
{ |
case 0 : |
case 1 : write_ndigit_number_u (x, y, naviData->HomePositionDeviation.Distance / 10, 3, 0,0); |
lcd_putc (x+3, y, 'm', 0); |
draw_homesymbol(x+4, y); |
break; |
|
case 2 : lcd_printp_at (x, y, PSTR("Home"), 0); |
write_ndigit_number_u (x+5, y, naviData->HomePositionDeviation.Distance / 10, 3, 0,0); |
lcd_printp_at (x+8, y, PSTR("m -"), 0); |
break; |
} |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_LEDOutput( x, y, bitmask) |
// |
// bitmask: LED1 = FC_STATUS2_OUT1_ACTIVE |
// LED2 = FC_STATUS2_OUT2_ACTIVE |
//-------------------------------------------------------------- |
void OSD_Element_LEDOutput( uint8_t x, uint8_t y, uint8_t bitmask ) |
{ |
uint8_t lOn; |
|
lOn = (naviData->FCStatusFlags2 & bitmask ? 1 : 0); // Bit gesetzt? |
lOn = (Config.OSD_InvertOut ? !lOn : lOn); // Invertieren? |
lOn = (lOn ? 1 : 0); // auf 0 oder 1 setzen (hmm, geht auch besser...). |
|
lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, lOn); |
lcd_circle (x * 6 + 5, y * 8 + 3, 3, 1); |
|
/* |
if (!Config.OSD_InvertOut) |
{ |
if (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE) |
{ |
lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 0); |
lcd_circle (x * 6 + 5, y * 8 + 3, 3, 1); |
} |
else |
{ |
lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 1); |
lcd_circle (x * 6 + 5, y * 8 + 3, 3, 1); |
} |
} |
else |
{ |
if (naviData->FCStatusFlags2 & FC_STATUS2_OUT1_ACTIVE) |
{ |
lcd_fcircle (x * 6 + 5, y * 8 + 3,Config.OSD_LEDform, 1); |
lcd_circle (x * 6 + 5, y * 8 + 3, 3, 1); |
} |
else |
{ |
lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, 0); |
lcd_circle (x * 6 + 5, y * 8 + 3, 3, 1); |
} |
} |
break; |
*/ |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_LED1Output( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_LED1Output( uint8_t x, uint8_t y ) |
{ |
OSD_Element_LEDOutput( x, y, FC_STATUS2_OUT1_ACTIVE ); |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_LED2Output( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_LED2Output( uint8_t x, uint8_t y ) |
{ |
OSD_Element_LEDOutput( x, y, FC_STATUS2_OUT2_ACTIVE ); |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_Manuell( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_Manuell( uint8_t x, uint8_t y ) |
{ |
if (naviData->NCFlags & NC_FLAG_MANUAL_CONTROL) |
lcd_putc (x, y, 'M', 0); // rc transmitter |
else |
lcd_putc (x, y, 'X', 0); // clear |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_NaviMode( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_NaviMode( uint8_t x, uint8_t y ) |
{ |
if (naviData->NCFlags & NC_FLAG_FREE) |
lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_0), 0); // Navi aus |
else if (naviData->NCFlags & NC_FLAG_PH) |
lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_1), 0); // Pos. Hold |
else if (naviData->NCFlags & NC_FLAG_CH) |
lcd_puts_at (x, y, strGet(OSD_NAVI_MODE_2), 0); // Coming Home |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_RCIntensity( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_RCIntensity( uint8_t x, uint8_t y ) |
{ |
write_ndigit_number_u (x, y, naviData->RC_Quality, 3, 0,0); |
lcd_printp_at (x+3, y, PSTR("\x1F"), 0); // RC-transmitter |
if (naviData->NCFlags & NC_FLAG_NOSERIALLINK) |
{ |
lcd_printpns_at(x+3, y, PSTR(" "), 0); // Clear |
} |
else |
{ |
lcd_printpns_at(x+3, y, PSTR("PC"), 0); |
} |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_SatsInUse( x, y, nStyle) |
// |
// nStyle == 0: "00s" |
// nStyle == 1: wie 0 |
// nStyle == 2: "00 Sat" |
// |
// nStyle entspricht dem ehemaligen 'Mode' |
//-------------------------------------------------------------- |
void OSD_Element_SatsInUse( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
drawmode = (naviData->NCFlags & NC_FLAG_GPS_OK ? 0 : 2); |
|
switch( nStyle ) |
{ |
case 0 : |
case 1 : write_ndigit_number_u (x, y, naviData->SatsInUse, 2, 0, drawmode); |
lcd_putc (x+2, y, 0x08, drawmode); |
break; |
|
case 2 : write_ndigit_number_u (x, y, naviData->SatsInUse, 2, 0, drawmode); |
lcd_printp_at (x+2, y, PSTR(" Sat"), drawmode); |
break; |
} |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_StatusFlags( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_StatusFlags( uint8_t x, uint8_t y ) |
{ |
// FC_StatusFlags 0.88 |
// #define FC_STATUS_MOTOR_RUN 0x01 |
// #define FC_STATUS_FLY 0x02 |
// #define FC_STATUS_CALIBRATE 0x04 |
// #define FC_STATUS_START 0x08 |
// #define FC_STATUS_EMERGENCY_LANDING 0x10 |
// #define FC_STATUS_LOWBAT 0x20 |
// #define FC_STATUS_VARIO_TRIM_UP 0x40 |
// #define FC_STATUS_VARIO_TRIM_DOWN 0x80 |
|
if (naviData->FCStatusFlags & FC_STATUS_CALIBRATE) |
lcd_puts_at (x, y, strGet(OSD_FLAGS_1), 0); // Calibrate |
else if (naviData->FCStatusFlags & FC_STATUS_START) |
lcd_puts_at (x, y, strGet(OSD_FLAGS_2), 0); // Start |
else if (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN) |
lcd_puts_at (x, y, strGet(OSD_FLAGS_3), 0); // Run |
else if (naviData->FCStatusFlags & FC_STATUS_FLY) |
lcd_puts_at (x, y, strGet(OSD_FLAGS_4), 0); // Fly |
else if (naviData->FCStatusFlags & FC_STATUS_EMERGENCY_LANDING) |
lcd_puts_at (x, y, strGet(OSD_FLAGS_5), 0); // Landing |
else if (naviData->FCStatusFlags & FC_STATUS_LOWBAT) |
lcd_puts_at (x, y, strGet(OSD_FLAGS_6), 0); // LowBat |
else |
// lcd_printp_at (x, y, PSTR(" "), 0); // Clear |
lcd_puts_at (x, y, strGet(OSD_FLAGS_0), 0); // Clear |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_Variometer( x, y) |
//-------------------------------------------------------------- |
void OSD_Element_Variometer( uint8_t x, uint8_t y ) |
{ |
x *= 6; |
y *= 8; |
y += 7; |
|
draw_variometer (x, y, 10, 14, naviData->Variometer); |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_Target( x, y, nStyle) |
// |
// nStyle entspricht dem ehemaligen 'Mode' |
// nStyle = 0,1: "000m" |
// nStyle = 2,3: "Ziel 000m -" |
//-------------------------------------------------------------- |
void OSD_Element_Target( uint8_t x, uint8_t y, uint8_t nStyle ) |
{ |
if( nStyle <= 1 ) |
{ |
write_ndigit_number_u (x, y, naviData->TargetPositionDeviation.Distance / 10, 3, 0,0); |
lcd_putc (x+3, y, 'm', 0); |
draw_targetsymbol(x+4,y); |
} |
else |
{ |
lcd_printp_at (x, y, PSTR("Ziel"), 0); |
write_ndigit_number_u (x+5, y, naviData->TargetPositionDeviation.Distance / 10, 3, 0,0); |
lcd_printp_at (x+8, y, PSTR("m -"), 0); |
} |
} |
|
|
//-------------------------------------------------------------- |
// TODO: |
// - pruefen ob beep hier an richtiger Stelle ist |
//-------------------------------------------------------------- |
void OSD_Element_VarioWert( uint8_t x, uint8_t y ) |
{ |
uint8_t FC_Fallspeed; |
|
FC_Fallspeed = (unsigned int)naviData->Variometer; |
FC_Fallspeed = 255-FC_Fallspeed; |
|
drawmode = ( (naviData->Variometer < 0) && (FC_Fallspeed > Config.OSD_Fallspeed) ? 2 : 0); |
|
|
if( Config.OSD_VarioBeep ) |
Beep_Vario(); // Beep ??? |
|
if( drawmode == 2 ) |
{ |
if( !Config.HWSound ) |
set_beep ( 1000, 0x0060, BeepNormal); // muss ein Beep hier hin???? |
else |
variobeep(naviData->Variometer); // muss ein Beep hier hin???? |
} |
|
write_ndigit_number_s_10th (x, y, naviData->Variometer, 3,0, drawmode); |
lcd_printpns_at(x+4, y, PSTR("ms"), drawmode); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_WayPoint( uint8_t x, uint8_t y ) |
{ |
if (!OldWP == naviData->WaypointIndex) |
{ |
// BeepTime = 500; |
// BeepMuster = 0x0080; |
OldWP = naviData->WaypointIndex; |
NextWP = true; |
} |
|
if ((NextWP==true)&& naviData->NCFlags & NC_FLAG_TARGET_REACHED) |
{ |
set_beep ( 500, 0x0080, BeepNormal); |
NextWP = false; |
} |
|
write_ndigit_number_u (x+2, y, naviData->WaypointIndex , 2, 0,0); |
|
lcd_printp_at (x, y, PSTR("WP"), 0); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_TargetDegree( uint8_t x, uint8_t y ) |
{ |
write_ndigit_number_u (x, y, naviData->TargetPositionDeviation.Bearing/ 10, 3, 0,0); |
lcd_putc (x+3, y, 0x1e, 0); // degree symbol |
} |
|
|
|
//############################################################## |
//# OSD-SCREENS |
//############################################################## |
|
//-------------------------------------------------------------- |
// OSD-Screen "General" |
// |
// nMode: 0 = update values |
// 1 = redraw labels and update values |
//-------------------------------------------------------------- |
const char * OSD_Screen_General( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("General"); |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// Display: 128 x 64 with 6x8 Font => 21 x 8 |
|
// Linien: Horizontal |
lcd_line (0, 28, 127, 28, 1); // mitte |
lcd_line (0, 51, 127, 51, 1); // unten |
|
// Linien: Vertikal |
lcd_line (65, 0, 65, 50, 1); // mitte |
|
//----------------------------------------- |
// Block: Oben - Links |
//----------------------------------------- |
draw_icon_battery(0,4); |
//lcdx_printp_at( 6, 0, PSTR("V") , MNORMAL, 1,0); // Spannung (Volt) |
lcdx_printp_at( 7, 2, PSTR(" mA"), MNORMAL, 0,2); |
|
//----------------------------------------- |
// Block: Oben - Rechts |
//----------------------------------------- |
lcdx_printp_at( 12, 0, PSTR("Alt:") , MNORMAL, 0,0); |
lcdx_printp_at( 12, 1, PSTR("Dir:") , MNORMAL, 0,1); |
draw_symbol_degree( 20, 1, 1,1); |
lcdx_printp_at( 12, 2, PSTR(" I:") , MNORMAL, 0,2); |
lcdx_printp_at( 20, 2, PSTR("A") , MNORMAL, 2,2); |
|
//----------------------------------------- |
// Block: Unten - Links |
//----------------------------------------- |
draw_icon_sat(0,33); |
lcdx_printp_at( 6, 5, PSTR(" kmh"), MNORMAL, 0,1); |
|
//----------------------------------------- |
// Block: Unten - Rechts |
//----------------------------------------- |
draw_icon_home( 70, 32); |
lcdx_printp_at( 20, 4, PSTR("m"), MNORMAL, 2,0); |
draw_symbol_degree( 20, 5, 1,1); |
//lcd_putc( 20, 5, 0x1E, 0); // alternativ: degree symbol |
|
//----------------------------------------- |
// unterste Zeile |
//----------------------------------------- |
draw_symbol_rc(20,7); // RC-transmitter |
} |
|
//----------------- |
// Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 2, 0, 0,0 ); |
|
//----------------- |
// LowBat Warnung MK |
//----------------- |
OSD_Element_Flag( 8, 0, OSD_FLAG_BA, 0,0 ); |
|
//----------------- |
// Flugzeit |
//----------------- |
writex_time(2, 1, naviData->FlyingTime, MNORMAL, 0,1); |
|
//----------------- |
// entnommene Kapazitaet (mAh) |
//----------------- |
drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL); |
writex_ndigit_number_u( 2, 2, naviData->UsedCapacity, 5, 0, drawmode, 0,2); |
|
//----------------- |
// Höhe |
//----------------- |
if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust)) // above 10m only write full meters |
write_ndigit_number_s ( 16, 0, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0, MNORMAL); |
else // up to 10m write meters.dm |
write_ndigit_number_s_10th( 16, 0, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0, MNORMAL); |
|
//----------------- |
// steigen / sinken |
//----------------- |
OSD_Element_UpDown( 20, 0, 2,0); |
|
//----------------- |
// Compass Degree |
//----------------- |
writex_ndigit_number_u (17, 1, naviData->CompassHeading, 3, 0,MNORMAL, 0,1); |
|
//----------------- |
// Strom |
//----------------- |
//write_ndigit_number_u_10th( 16, 2, naviData->Current, 3, 0,0); // alternativ mit Nachkomma |
writex_ndigit_number_u( 17, 2, naviData->Current/10, 3, 0,MNORMAL, 0,2); |
|
//----------------- |
// Sat Anzahl |
//----------------- |
write_ndigit_number_u (4, 4, naviData->SatsInUse, 2, 0,MNORMAL); |
|
//----------------- |
// Sat Warnung "!" |
//----------------- |
/* |
if( naviData->NCFlags & NC_FLAG_GPS_OK ) |
lcd_printp_at( 9, 4, PSTR(" "), MNORMAL); |
else |
lcd_printp_at( 9, 4, PSTR("!"), MNORMAL); |
*/ |
OSD_Element_Flag( 8, 4, OSD_FLAG_S0, -1,0 ); // Sat Warnung (GPS not ok) |
|
//----------------- |
// Geschwindigkeit |
//----------------- |
writex_ndigit_number_u( 3, 5, (uint16_t) (((uint32_t) naviData->GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,MNORMAL, 0,1); |
|
//----------------- |
// Home Distance |
//----------------- |
write_ndigit_number_u( 17, 4, naviData->HomePositionDeviation.Distance / 10, 3, 0,MNORMAL); |
|
//----------------- |
// Home Winkel |
//----------------- |
writex_ndigit_number_u( 16, 5, heading_home, 4, 0,MNORMAL, 0,1); |
|
//----------------- |
// Flags |
//----------------- |
OSD_Element_Flag( 1, 7, OSD_FLAG_CF, 0,0 ); // Care Free |
OSD_Element_Flag( 4, 7, OSD_FLAG_AH, 0,0 ); // Altitude Hold |
OSD_Element_Flag( 7, 7, OSD_FLAG_PH, 0,0 ); // Position Hold |
OSD_Element_Flag( 10, 7, OSD_FLAG_CH, 0,0 ); // Coming Home |
OSD_Element_Flag( 13, 7, OSD_FLAG_EL, 0,0 ); // Emergency Landing |
|
//----------------- |
// RC-Quality (MK) |
//----------------- |
write_ndigit_number_u( 17, 7, naviData->RC_Quality, 3, 0,MNORMAL); |
|
#ifdef OSD_DEMO |
//----------------- |
// Flags |
//----------------- |
OSD_Element_Flag_Label( 8, 0, OSD_FLAG_BA, true, 0,0 ); // DEMO: Batterie Warnung |
OSD_Element_Flag_Label( 8, 4, OSD_FLAG_S0, true, -1,0 ); // DEMO: Sat Warnung (GPS not ok) |
|
OSD_Element_Flag_Label( 1, 7, OSD_FLAG_CF, true, 0,0 ); // DEMO |
OSD_Element_Flag_Label( 4, 7, OSD_FLAG_AH, true, 0,0 ); // DEMO |
OSD_Element_Flag_Label( 7, 7, OSD_FLAG_PH, true, 0,0 ); // DEMO |
OSD_Element_Flag_Label( 10, 7, OSD_FLAG_CH, true, 0,0 ); // DEMO |
OSD_Element_Flag_Label( 13, 7, OSD_FLAG_EL, true, 0,0 ); // DEMO |
#endif |
|
|
return( ScreenName ); |
} |
|
|
//-------------------------------------------------------------- |
// OSD-Screen "Navigation" |
// |
// nMode: 0 = update values |
// 1 = redraw labels and update values |
//-------------------------------------------------------------- |
const char * OSD_Screen_Navigation( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("Navigation"); |
int8_t xoffs, yoffs; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
|
lcd_line ((6*6-4), 0, (6*6-4), 9, 1); // Linie Vertikal links |
lcd_line ((15*6+3), 0, (15*6+3), 9, 1); // Linie Vertikal rechts |
lcd_line (0, 10, 127, 10, 1); // Linie Horizontal |
|
lcdx_printp_at( 0, 2, PSTR("Alt:"), MNORMAL, 0,2); // Hoehe |
lcdx_printp_at( 0, 5, PSTR("Home:"), MNORMAL, 0,3); // Home Distance |
} |
|
|
//----------------- |
// Oben: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Oben: Kompass Rose |
//----------------- |
OSD_Element_CompassRose( 6, 0); |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
write_time(16, 0, naviData->FlyingTime); |
|
//----------------- |
// Hoehe |
//----------------- |
xoffs = 0; |
yoffs = 3; |
drawmode = MNORMAL; |
if (naviData->Altimeter > (300 / AltimeterAdjust) || naviData->Altimeter < (-300 / AltimeterAdjust)) // above 10m only write full meters |
writex_ndigit_number_s ( 0, 3, naviData->Altimeter / (30 / AltimeterAdjust), 4, 0, drawmode, xoffs,yoffs); |
else // up to 10m write meters.dm |
writex_ndigit_number_s_10th( 0, 3, naviData->Altimeter / (3 / AltimeterAdjust), 3, 0, drawmode, xoffs,yoffs); |
|
//----------------- |
// Steigen / Sinken |
//----------------- |
OSD_Element_UpDown( 4, 3, 1,yoffs); |
|
//----------------- |
// Home Distance |
//----------------- |
yoffs = 3; |
writex_ndigit_number_u( 0, 6, naviData->HomePositionDeviation.Distance / 10, 4, 0,MNORMAL, 0,yoffs+1); |
lcdx_printp_at( 4, 6, PSTR("m"), MNORMAL, 2,yoffs+1); // Home |
|
//----------------- |
// Home Circle |
//----------------- |
xoffs = 0; |
yoffs = 3; |
OSD_Element_HomeCircle( 8, 3, 9, 4, xoffs,yoffs); // Home Circle |
lcd_frect( (9*6)-3+xoffs, (4*8)-2+yoffs, (3*6)+4, (1*8)+2, 0); // inner clear |
lcd_rect ( (9*6)-4+xoffs, (4*8)-3+yoffs, (3*6)+6, (1*8)+4, 1); // inner rect |
lcd_frect ( 61+xoffs, 57+yoffs, 2, 2, 1); // bottom mini rect |
writex_ndigit_number_u( 9, 4, heading_home, 3, 0,MNORMAL, xoffs,yoffs); // Degree (Winkel) |
|
//----------------- |
// Variometer |
//----------------- |
//void draw_variometer (uint8_t x, uint8_t y, uint8_t width, uint8_t hight, int16_t variometer) |
//draw_variometer( 95, 38, 7, 30, naviData->Variometer); |
//draw_variometer( 94, 38, 7, 21, naviData->Variometer); |
//draw_variometer2( 94, 28, 7, 21, naviData->Variometer); |
|
//----------------- |
// Flags |
//----------------- |
OSD_Element_Flag( 16, 2, OSD_FLAG_BA, -3, 0); // MK Batt Warning |
OSD_Element_Flag( 19, 2, OSD_FLAG_CF, 0, 0); // Carefree |
OSD_Element_Flag( 19, 4, OSD_FLAG_AH, 0,-3); // Altitude Hold |
OSD_Element_Flag( 19, 6, OSD_FLAG_PH, 0,-6); // Position Hold |
OSD_Element_Flag( 19, 7, OSD_FLAG_CH, 0,-1); // Coming Home |
OSD_Element_Flag( 16, 7, OSD_FLAG_S0, -3,-1); // GPS-Sat not ok (GPS NOT ok) |
|
|
#ifdef OSD_DEMO |
//----------------- |
// Flags |
//----------------- |
OSD_Element_Flag_Label( 16, 2, OSD_FLAG_BA, true, -3,0); // DEMO |
|
OSD_Element_Flag_Label( 19, 2, OSD_FLAG_CF, true, 0,0); // DEMO |
OSD_Element_Flag_Label( 19, 4, OSD_FLAG_AH, true, 0,-3); // DEMO |
OSD_Element_Flag_Label( 19, 6, OSD_FLAG_PH, true, 0,-6); // DEMO |
OSD_Element_Flag_Label( 19, 7, OSD_FLAG_CH, true, 0,-1); // DEMO |
|
OSD_Element_Flag_Label( 16, 7, OSD_FLAG_S0, true, -3,-1); // DEMO |
#endif |
|
|
return( ScreenName ); |
} |
|
|
|
|
//-------------------------------------------------------------- |
// OSD-Screen "Status" |
// |
// nMode: 0 = update values |
// 1 = redraw labels and update values |
//-------------------------------------------------------------- |
const char * OSD_Screen_MKStatus( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("MK-Status"); |
int8_t xoffs; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
|
lcd_line ((6*6-3), 0, (6*6-3), 9, 1); // Linie Vertikal links |
lcd_line ((15*6+3), 0, (15*6+3), 9, 1); // Linie Vertikal rechts |
lcd_line (0, 10, 127, 10, 1); // Linie Horizontal |
|
//lcdx_printp_at( 8, 0, PSTR("Status"), MNORMAL, -3,0); // oben, mitte Text |
lcdx_printp_at( 13, 0, PSTR("A"), MNORMAL, -4,0); // oben, mitte "A" |
} |
|
|
//----------------- |
// Oben: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Strom |
//----------------- |
writex_ndigit_number_u_10th( 7, 0, naviData->Current, 4, 0,MNORMAL, 1,0); // Strom mit Nachkomma |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
write_time(16, 0, naviData->FlyingTime); |
|
//----------------- |
// Flags |
//----------------- |
xoffs = -7; |
OSD_Element_Flag( 19, 2, OSD_FLAG_CF, 0+xoffs, 0); // Carefree |
OSD_Element_Flag( 19, 4, OSD_FLAG_AH, 0+xoffs,-3); // Altitude Hold |
OSD_Element_Flag( 19, 6, OSD_FLAG_PH, 0+xoffs,-6); // Position Hold |
OSD_Element_Flag( 19, 7, OSD_FLAG_CH, 0+xoffs,-1); // Coming Home |
|
xoffs -= 4; |
OSD_Element_Flag( 16, 2, OSD_FLAG_BA, -3+xoffs, 0); // MK Batt Warning |
OSD_Element_Flag( 16, 4, OSD_FLAG_EL, -3+xoffs,-3); // Emergency Landing |
OSD_Element_Flag( 16, 6, OSD_FLAG_RL, -3+xoffs,-6); // Range Limit |
OSD_Element_Flag( 16, 7, OSD_FLAG_S0, -3+xoffs,-1); // GPS-Sat not ok (GPS NOT ok) |
|
xoffs -= 4; |
OSD_Element_Flag( 12, 2, OSD_FLAG_CA, 0+xoffs, 0); // Calibrate |
OSD_Element_Flag( 12, 4, OSD_FLAG_ST, 0+xoffs,-3); // Start |
OSD_Element_Flag( 12, 6, OSD_FLAG_MR, 0+xoffs,-6); // Motor Run |
OSD_Element_Flag( 12, 7, OSD_FLAG_FY, 0+xoffs,-1); // Fly |
|
xoffs -= 4; |
OSD_Element_Flag( 9, 2, OSD_FLAG_O1, -2+xoffs, 0); // Out1 |
OSD_Element_Flag( 9, 4, OSD_FLAG_O2, -2+xoffs,-3); // Out2 |
OSD_Element_Flag( 9, 6, OSD_FLAG_TR, -2+xoffs,-6); // Target Reached |
OSD_Element_Flag( 9, 7, OSD_FLAG_MC, -2+xoffs,-1); // Manual Control |
|
xoffs -= 4; |
OSD_Element_Flag( 6, 2, OSD_FLAG_TU, -4+xoffs, 0); // Vario Trim Up |
OSD_Element_Flag( 6, 4, OSD_FLAG_TD, -4+xoffs,-3); // Vario Trim Down |
OSD_Element_Flag( 6, 6, OSD_FLAG_FR, -4+xoffs,-6); // Free |
OSD_Element_Flag( 6, 7, OSD_FLAG_SL, -4+xoffs,-1); // No Serial Link |
|
|
#ifdef OSD_DEMO |
//----------------- |
// Flags |
//----------------- |
/* |
PSTR("AH"), // OSD_FLAG_AH Altitue Hold |
PSTR("PH"), // OSD_FLAG_PH Position Hold |
PSTR("CF"), // OSD_FLAG_CF Care Free |
PSTR("CH"), // OSD_FLAG_CH Coming Home |
PSTR("o1"), // OSD_FLAG_O1 Out1 |
PSTR("o2"), // OSD_FLAG_O2 Out2 |
PSTR("BA"), // OSD_FLAG_BA LowBat warning (MK) |
PSTR("CA"), // OSD_FLAG_CA Calibrate |
PSTR("ST"), // OSD_FLAG_ST Start |
PSTR("MR"), // OSD_FLAG_MR Motor Run |
PSTR("FY"), // OSD_FLAG_FY Fly |
PSTR("EL"), // OSD_FLAG_EL Emergency Landing |
PSTR("FS"), // OSD_FLAG_FS RX Failsave Active |
PSTR("GP"), // OSD_FLAG_GP GPS Ok |
PSTR("S!") // OSD_FLAG_S0 GPS-Sat not ok (GPS NOT ok) |
PSTR("TU"), // OSD_FLAG_TU Vario Trim Up |
PSTR("TD"), // OSD_FLAG_TD Vario Trim Down |
PSTR("FR"), // OSD_FLAG_FR Free |
PSTR("RL"), // OSD_FLAG_RL Range Limit |
PSTR("SL"), // OSD_FLAG_SL No Serial Link |
PSTR("TR"), // OSD_FLAG_TR Target Reached |
PSTR("MC") // OSD_FLAG_MC Manual Control |
*/ |
xoffs = -7; |
OSD_Element_Flag_Label( 19, 2, OSD_FLAG_CF, true, 0+xoffs, 0); // DEMO: Carefree |
OSD_Element_Flag_Label( 19, 4, OSD_FLAG_AH, true, 0+xoffs,-3); // DEMO: Altitude Hold |
OSD_Element_Flag_Label( 19, 6, OSD_FLAG_PH, true, 0+xoffs,-6); // DEMO: Position Hold |
OSD_Element_Flag_Label( 19, 7, OSD_FLAG_CH, true, 0+xoffs,-1); // DEMO: Coming Home |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 16, 2, OSD_FLAG_BA, true, -3+xoffs, 0); // DEMO: MK Batt Warning |
OSD_Element_Flag_Label( 16, 4, OSD_FLAG_EL, true, -3+xoffs,-3); // DEMO: Emergency Landing |
OSD_Element_Flag_Label( 16, 6, OSD_FLAG_RL, true, -3+xoffs,-6); // DEMO: Range Limit |
OSD_Element_Flag_Label( 16, 7, OSD_FLAG_S0, true, -3+xoffs,-1); // DEMO: GPS-Sat not ok (GPS NOT ok) |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 12, 2, OSD_FLAG_CA, true, 0+xoffs, 0); // DEMO: Calibrate |
OSD_Element_Flag_Label( 12, 4, OSD_FLAG_ST, true, 0+xoffs,-3); // DEMO: Start |
OSD_Element_Flag_Label( 12, 6, OSD_FLAG_MR, true, 0+xoffs,-6); // DEMO: Motor Run |
OSD_Element_Flag_Label( 12, 7, OSD_FLAG_FY, true, 0+xoffs,-1); // DEMO: Fly |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 9, 2, OSD_FLAG_O1, true, -2+xoffs, 0); // DEMO: Out1 |
OSD_Element_Flag_Label( 9, 4, OSD_FLAG_O2, true, -2+xoffs,-3); // DEMO: Out2 |
OSD_Element_Flag_Label( 9, 6, OSD_FLAG_TR, true, -2+xoffs,-6); // DEMO: Target Reached |
OSD_Element_Flag_Label( 9, 7, OSD_FLAG_MC, true, -2+xoffs,-1); // DEMO: Manual Control |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 6, 2, OSD_FLAG_TU, true, -4+xoffs, 0); // DEMO: Vario Trim Up |
OSD_Element_Flag_Label( 6, 4, OSD_FLAG_TD, true, -4+xoffs,-3); // DEMO: Vario Trim Down |
OSD_Element_Flag_Label( 6, 6, OSD_FLAG_FR, true, -4+xoffs,-6); // DEMO: Free |
OSD_Element_Flag_Label( 6, 7, OSD_FLAG_SL, true, -4+xoffs,-1); // DEMO: No Serial Link |
|
#endif |
|
|
return( ScreenName ); |
} |
|
|
|
//############################################################## |
#ifdef OSD_DEBUG_SCREEN |
//############################################################## |
|
//************************************************************** |
//* OSD_DEBUG_SCREEN - Experimental-Code usw. |
//* - nicht fuer die Oeffentlichkeit bestimmt |
//* - gesteuert ueber define OSD_DEBUG_SCREEN |
//************************************************************** |
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// NOTIZEN |
// |
// 1. Thema: Motorwerte abfragen |
// |
// ja, auf die gleiche Weise wie man an die Config Parameter kommt. |
// |
// SwitchToFC(); |
// SendOutData( 'u', ADDRESS_FC, BL-Adresse, &tmp_dat, 1); |
// |
// Die Daten kommen dann in der Form: |
// typedef struct |
// { |
// uint8_t Version; // the version of the BL (0 = old) |
// uint8_t SetPoint; // written by attitude controller |
// uint8_t SetPointLowerBits; // for higher Resolution of new BLs |
// uint8_t State; // 7 bit for I2C error counter, highest bit indicates if motor is present |
// uint8_t ReadMode; // select data to read |
// // the following bytes must be exactly in that order! |
// uint8_t Current; // in 0.1 A steps, read back from BL |
// uint8_t MaxPWM; // read back from BL -> is less than 255 if BL is in current limit, not running (250) or starting (40) |
// int8_t Temperature; // old BL-Ctrl will return a 255 here, the new version the temp. in ?C |
// } __attribute__((packed)) MotorData_t; |
// |
// |
// kennst Du die Seite?:http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=%28%28----%28-*%29%28\r%29%3F\n%29%28.*%29CategoryCoding%29#en.2BAC8-SerialCommands.Flight-Ctrl |
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
uint8_t xload_setting( uint8_t setting ) |
{ |
mode = 'Q'; // Settings |
uint8_t timeout = 50; |
rxd_buffer_locked = FALSE; |
|
while (!rxd_buffer_locked && timeout) |
{ |
SendOutData ('q', ADDRESS_FC, 1, &setting, 1); |
// _delay_ms(50); |
timer = 20; |
while (timer > 0); |
timeout--; |
} |
|
if (timeout != 0) |
{ |
Decode64 (); |
setting = *pRxData; |
mk_param_struct = (mk_param_struct_t *) (pRxData + 1) ; |
} |
else |
{ // timeout occured |
// lcd_printp_at (0, 2, PSTR("Fehler: keine Daten"), 0); |
lcd_puts_at(0, 2, strGet(OSD_ERROR), 0); |
timer = 100; |
while (timer > 0); |
setting = 255; |
} |
return setting; |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
const char * OSD_Screen_Debug( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("Debug"); |
|
static s16 min_debug = 0; |
static s16 max_debug = 0; |
static uint16_t debug_count = 0; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
min_debug = 0; |
max_debug = 0; |
} |
|
lcd_printp_at( 0, 0, PSTR("Debug"), 0); |
|
|
debug_count++; |
|
if( naviData->Variometer < min_debug ) min_debug = naviData->Variometer; |
if( naviData->Variometer > max_debug ) max_debug = naviData->Variometer; |
|
write_ndigit_number_s ( 8, 1, (naviData->Variometer), 12, 0,MNORMAL); // s16 Variometer; |
write_ndigit_number_s ( 8, 2, (min_debug), 12, 0,MNORMAL); // s16 Variometer; |
write_ndigit_number_s ( 8, 3, (max_debug), 12, 0,MNORMAL); // s16 Variometer; |
|
write_ndigit_number_u ( 8, 5, (debug_count), 12, 0,MNORMAL); // |
//write_ndigit_number_u ( 8, 6, (timer), 12, 0,MNORMAL); // |
|
//draw_variometer2( 6, 19, 7, 21, naviData->Variometer); |
|
return( ScreenName ); |
} |
//############################################################## |
#endif // OSD_DEBUG_SCREEN |
//############################################################## |
|
|
|
//-------------------------------------------------------------- |
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 0 |
//-------------------------------------------------------------- |
const char * OSD_Screen_OSD0( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("OSD0"); |
//uint8_t xoffs; |
|
//----------------------------------------- |
// REDRAW static screen elements |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
} |
|
OSD_Element_AltitudeControl ( 0, 3); |
OSD_Element_Altitude ( 11, 3, 0); |
OSD_Element_BatteryLevel ( 0, 7, 0); |
OSD_Element_Capacity ( 13, 7); |
OSD_Element_Current ( 8, 7); |
OSD_Element_CareFree ( 0, 5); |
OSD_Element_CompassDegree ( 13, 0, 0); |
OSD_Element_CompassDirection( 18, 0); |
OSD_Element_CompassRose ( 12, 1); |
OSD_Element_FlyingTime ( 0, 1); |
OSD_Element_GroundSpeed ( 0, 0); |
OSD_Element_HomeCircle ( 16, 4, 5, 0, 0,0); |
OSD_Element_HomeDegree ( 12, 4); |
OSD_Element_HomeDistance ( 10, 5, 0); |
OSD_Element_Target ( 10, 6, 0); |
//OSD_Element_TargetDegree ( x, y); |
OSD_Element_WayPoint ( 5, 6); |
OSD_Element_LED1Output ( 0, 6); |
OSD_Element_LED2Output ( 3, 6); |
//OSD_Element_Manuell ( x, y); |
OSD_Element_NaviMode ( 0, 4); |
//OSD_Element_RCIntensity ( x, y); |
OSD_Element_VarioWert ( 12, 2); |
OSD_Element_SatsInUse ( 18, 2, 0); |
OSD_Element_StatusFlags ( 0, 2); |
OSD_Element_Variometer ( 9, 0); |
|
return( ScreenName ); |
} |
|
|
|
|
//-------------------------------------------------------------- |
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 1 |
//-------------------------------------------------------------- |
const char * OSD_Screen_OSD1( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("OSD1"); |
//uint8_t xoffs; |
|
//----------------------------------------- |
// REDRAW static screen elements |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
} |
|
//OSD_Element_AltitudeControl( x, y); |
OSD_Element_Altitude ( 1, 1, 1); |
OSD_Element_BatteryLevel ( 0, 7, 1); |
OSD_Element_Capacity ( 13, 7); |
OSD_Element_Current ( 8, 7); |
//OSD_Element_CareFree ( x, y); |
OSD_Element_CompassDegree ( 13, 0, 1); |
OSD_Element_CompassDirection( 18, 0); |
OSD_Element_CompassRose ( 12, 1); |
OSD_Element_FlyingTime ( 7, 6); |
OSD_Element_GroundSpeed ( 0, 0); |
OSD_Element_HomeCircle ( 1, 3, 7, 0, 0,0); |
OSD_Element_HomeDegree ( 8, 3); |
OSD_Element_HomeDistance ( 7, 2, 1); |
//OSD_Element_Target ( x, y, 1); |
//OSD_Element_TargetDegree ( x, y); |
//OSD_Element_WayPoint ( x, y); |
//OSD_Element_LED1Output ( x, y); |
//OSD_Element_LED2Output ( x, y); |
//OSD_Element_Manuell ( x, y); |
OSD_Element_NaviMode ( 8, 5); |
OSD_Element_RCIntensity ( 15, 6); |
OSD_Element_VarioWert ( 15, 2); |
OSD_Element_SatsInUse ( 8, 4, 1); |
//OSD_Element_StatusFlags ( x, y); |
OSD_Element_Variometer ( 9, 0); |
|
return( ScreenName ); |
} |
|
|
//-------------------------------------------------------------- |
// ehemals: OSD_ALTITUDE,Config.OSD_ScreenMode == 2 |
//-------------------------------------------------------------- |
const char * OSD_Screen_OSD2( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("OSD2"); |
//uint8_t xoffs; |
|
//----------------------------------------- |
// REDRAW static screen elements |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
} |
|
OSD_Element_AltitudeControl ( 0, 1); |
OSD_Element_Altitude ( 0, 4, 2); |
OSD_Element_BatteryLevel ( 13, 7, 2); |
OSD_Element_Capacity ( 0, 7); |
OSD_Element_Current ( 8, 7); |
OSD_Element_CareFree ( 0, 3); |
OSD_Element_CompassDegree ( 12, 3, 2); |
//OSD_Element_CompassDirection( x, y); |
//OSD_Element_CompassRose ( x, y); |
OSD_Element_FlyingTime ( 15, 5); |
//OSD_Element_GroundSpeed ( x, y); |
OSD_Element_HomeCircle ( 16, 0, 5, 0, 0,0); |
OSD_Element_HomeDegree ( 11, 5); |
OSD_Element_HomeDistance ( 0, 5, 2); |
OSD_Element_Target ( 0, 6, 2); |
OSD_Element_TargetDegree ( 11, 6); |
//OSD_Element_WayPoint ( x, y); |
OSD_Element_LED1Output ( 12, 2); |
OSD_Element_LED2Output ( 14, 2); |
//OSD_Element_Manuell ( x, y); |
OSD_Element_NaviMode ( 0, 2); |
//OSD_Element_RCIntensity ( x, y); |
OSD_Element_VarioWert ( 15, 4); |
OSD_Element_SatsInUse ( 10, 0, 2); |
OSD_Element_StatusFlags ( 0, 0); |
//OSD_Element_Variometer ( x, y); |
|
return( ScreenName ); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
const char * OSD_Screen_3DLage( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("3D Lage"); |
uint16_t head_home; |
uint8_t Nick; |
uint8_t Roll; |
|
//----------------------------------------- |
// REDRAW static screen elements |
//----------------------------------------- |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
} |
|
head_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360; |
|
//lcd_cls (); |
|
lcd_line(26,32,100,32,1); // horizontal // |
lcd_line(63,0,63,63,1); // vertical // |
//lcd_puts_at(12, 7, strGet(KEYLINE5), 0); |
|
// 45' Angel |
lcd_line(61,11,65,11,1); // -- // |
lcd_line(40,30,40,34,1); // | // |
lcd_line(86,30,86,34,1); // | // |
lcd_line(61,53,65,53,1); // -- // |
|
lcd_puts_at(9, 0, strGet(OSD_3D_V), 0); // V |
lcd_puts_at(3, 3, strGet(OSD_3D_L), 0); // L |
lcd_puts_at(17, 3, strGet(OSD_3D_R), 0); // R |
lcd_puts_at(9, 7, strGet(OSD_3D_H), 0); // H |
|
lcd_puts_at(0, 0, strGet(OSD_3D_NICK), 0); // Ni |
write_ndigit_number_s (2, 0, naviData->AngleNick, 3, 0,0); |
lcd_putc (5, 0, 0x1e, 0); // degree symbol |
|
lcd_puts_at(0, 7, strGet(OSD_3D_ROLL), 0); // Ro |
write_ndigit_number_s (2, 7, naviData->AngleRoll, 3, 0,0); |
lcd_putc (5, 7, 0x1e, 0); // degree symbol |
|
lcd_puts_at(13, 0, strGet(OSD_3D_COMPASS), 0); |
//write_ndigit_number_s (15, 0,head_home, 3, 0); |
write_ndigit_number_u (15, 0, naviData->CompassHeading, 3, 0,0); |
lcd_putc (18, 0, 0x1e, 0); // degree symbol |
lcd_printp_at (19, 0, (const char *) (pgm_read_word ( &(directions_p[heading_conv(naviData->CompassHeading)]))), 0); |
|
Nick = ((-naviData->AngleNick/2)+32); |
Roll = ((-naviData->AngleRoll/2)+63); |
|
lcd_ellipse ( old_AngleRoll, old_AngleNick, 9, 8, 0); |
lcd_ellipse_line( old_AngleRoll, old_AngleNick, 8, 7, old_hh, 0); |
|
lcd_ellipse ( Roll, Nick, 9, 8, 1); |
lcd_ellipse_line( Roll, Nick, 8, 7, head_home, 1); |
|
// remember last values (3DL) |
old_hh = head_home; |
old_AngleNick = Nick; |
old_AngleRoll = Roll; |
|
return( ScreenName ); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
const char * OSD_Screen_Statistics( uint8_t nMode ) |
{ |
const char *ScreenName = PSTR("Statistics"); |
uint8_t line = 0; |
|
//----------------------------------------- |
// REDRAW static screen elements |
//----------------------------------------- |
/* |
if( nMode == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
} |
*/ |
|
//--------------------------- |
// max Altitude |
lcd_puts_at (0, line, strGet(STATS_ITEM_0), MNORMAL); |
write_ndigit_number_s (14, line, max_Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL); |
lcdx_putc (18, line, 'm', MNORMAL, 2,0); |
|
//--------------------------- |
// max Speed |
// max_GroundSpeed = 1; |
lcd_puts_at (0, ++line, strGet(STATS_ITEM_1), MNORMAL); |
write_ndigit_number_u (15, line, (uint16_t) (((uint32_t) max_GroundSpeed * (uint32_t) 9) / (uint32_t) 250), 3, 0,MNORMAL); |
lcdx_printp_at(18, line, PSTR("kmh"), MNORMAL, 2,0); |
|
//--------------------------- |
// max Distance |
// max_Distance = 64512; |
lcd_puts_at (0, ++line, strGet(STATS_ITEM_2), MNORMAL); |
write_ndigit_number_u (14, line, max_Distance / 10, 4, 0,MNORMAL); |
lcdx_putc (18, line, 'm', MNORMAL, 2,0); |
|
//--------------------------- |
// max time |
// max_FlyingTime = 3600; |
lcd_puts_at (0, ++line, strGet(STATS_ITEM_4), MNORMAL); |
write_time (13, line, max_FlyingTime); |
|
//--------------------------- |
// min voltage |
lcd_puts_at (0, ++line, strGet(STATS_ITEM_3), MNORMAL); |
if( min_UBat==255 ) |
lcd_printp_at(14, line, PSTR(" 0"), MNORMAL); |
else |
write_ndigit_number_u_10th (14, line, min_UBat, 3, 0,MNORMAL); |
lcdx_putc (18, line, 'V', MNORMAL, 2,0); |
|
//--------------------------- |
// max Current |
// max_Current = 1000; |
lcd_puts_at (0, ++line, strGet(STATS_ITEM_5), MNORMAL); |
write_ndigit_number_u_10th (13, line, max_Current, 4, 0,MNORMAL); |
lcdx_putc (18, line, 'A', MNORMAL, 2,0); |
|
//--------------------------- |
// Used Capacity |
lcd_puts_at (0, ++line, strGet(STATS_ITEM_6), MNORMAL); |
write_ndigit_number_u (14, line, max_Capacity, 4, 0,MNORMAL); |
lcdx_printp_at(18, line, PSTR("mAh"), MNORMAL, 2,0); |
|
return( ScreenName ); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void print_statistics (void) |
{ |
lcd_cls (); |
lcd_puts_at(12, 7, strGet(ENDE), 0); |
|
OSD_Screen_Statistics( OSD_SCREEN_REDRAW ); |
|
while (!get_key_press (1 << KEY_ESC)) |
timer = TIMEOUT; |
|
COSD_FLAGS2 &= ~COSD_WASFLYING; |
get_key_press(KEY_ALL); |
lcd_cls(); |
} |
|
|
//----------------------------------------------------------- |
//----------------------------------------------------------- |
void OSD_Info( uint8_t ScreenNum, const char *ScreenName) |
{ |
lcd_frect( 0, 36, 127, 10, 0); // clear |
lcd_frect( 0, 34, 4, 4, 0); // clear links |
lcd_frect( 0, 40, 127, 24, 1); // Box |
lcd_frect( 10, 36, 108, 4, 1); // Filler oben |
lcd_fcircle( 8, 39, 7, 1); // Links |
lcd_fcircle( 121, 41, 5, 1); // Rechts |
|
lcd_line ( 4, 51, 122, 51, 0); // Linie mitte |
|
//----------------------- |
// ScreenNummer: ScreenName |
//----------------------- |
write_ndigit_number_s ( 1, 5, ScreenNum, 2, 1,2); |
lcd_printp_at( 3, 5, PSTR(":"), 2); |
lcd_printp_at( 5, 5, ScreenName, 2); |
|
//----------------------- |
// Key's |
//----------------------- |
lcd_puts_at(0, 7, strGet(KEYLINE3), 2); |
lcd_printp_at (17, 7, PSTR("Info"), 2); |
|
do |
{ |
timer = TIMEOUT; |
_delay_ms(50); |
} while ( !( (get_key_press (1 << KEY_ENTER)) || (get_key_press (1 << KEY_ESC)) || (get_key_press (1 << KEY_PLUS)) || (get_key_press (1 << KEY_MINUS)) ) ); |
} |
|
|
|
//############################################################## |
//# OSD MAIN LOOP |
//############################################################## |
|
//-------------------------------------------------------------- |
// OSD MAIN LOOP |
//-------------------------------------------------------------- |
void osd( uint8_t ShowMode ) |
{ |
uint8_t flag; |
uint8_t tmp_dat; |
uint8_t ScreenRefresh; |
uint8_t MAX_OSD_Screens; |
//uint8_t status; // FC Kommunikation |
|
const char *ScreenName = PSTR(""); |
|
lcd_cls(); |
|
//---------------------------------------- |
// NC Hardware needed |
//---------------------------------------- |
if( hardware == FC ) |
{ |
lcd_puts_at(0, 3, strGet(ONLY_NC), 0); // Nur mit NC |
timer = 100; |
while (timer > 0); |
return; |
} |
|
|
/* |
//----------------------------------------------------------------------------------------------- |
// 07.03.2013 OG: del |
// Dieser Teil hat immer wieder Probleme bereitet bei der Verbindung des PKT-OSD zum MK da |
// Timeouts zustande kamen. Eine Recherche im Code ergab, dass die Nutzdaten die |
// hierueber bezogen werden sich lediglich auf Flags_ExtraConfig beschraenkten (CFG2_HEIGHT_LIMIT). |
// Siehe dazu untere Kommentare. |
// |
// Der negative Effekt moeglicher Timeouts und Verzoegerungen sind es aktuell nicht Wert |
// CFG2_HEIGHT_LIMIT zu unterstuetzen. Dieses Feature ist erstmal raus. |
// |
// Falls gewuenscht wird, dass CFG2_HEIGHT_LIMIT wieder in das PKT-OSD kommt muss |
// es zuverlaessig an anderer Stelle implementiert werden - und zwar nicht in osd.c |
// weil es eine statische FC-Information ist (ggf. beim Verbindungsaufbau PKT <-> MK). |
// |
// Hat auch aktuell Auswirkung auf den Code OSD_Element_AltitudeControl() |
// |
lcd_printp_at( 0, 3, PSTR("connecting MK..."), 0); |
|
SwitchToFC(); |
|
status = load_setting(0xff); |
|
if( status == 255 ) |
{ |
lcd_puts_at(0, 0, strGet(NO_SETTINGS), 0); // Keine Settings |
_delay_ms(2000); |
} |
Flags_ExtraConfig = mk_param_struct->ExtraConfig; // OG: wird in osd.c nur verwendet von: OSD_Element_AltitudeControl() |
Flags_GlobalConfig = mk_param_struct->GlobalConfig; // OG: wird nicht in osd.c verwendet |
Flags_GlobalConfig3 = mk_param_struct->GlobalConfig3; // OG: wird nicht in osd.c verwendet |
*/ |
|
|
rxd_buffer_locked = FALSE; // 07.03.2013 OG: fix |
// es gab Probleme mit dem Empfang gueltiger NC-Daten, die zu unschoenen Starteffekten bei den |
// OSD-Screens gefuehrt haben. Mit rxd_buffer_locked = FALSE vor SwitchToNC() ist das PKT wieder im 'Takt' |
|
SwitchToNC(); |
|
mode = 'O'; |
|
// disable debug... |
// RS232_request_mk_data (0, 'd', 0); |
tmp_dat = 0; |
SendOutData ('d', ADDRESS_ANY, 1, &tmp_dat, 1); |
|
// request OSD Data from NC every 100ms |
// RS232_request_mk_data (1, 'o', 100); |
tmp_dat = 10; |
OSD_active = true; // benoetigt für Navidata Ausgabe an SV2 |
SendOutData( 'o', ADDRESS_NC, 1, &tmp_dat, 1); |
|
|
//------------------------- |
// Clear statistics |
//------------------------- |
max_Altimeter = 0; |
max_GroundSpeed = 0; |
max_Distance = 0; |
min_UBat = 255; |
max_FlyingTime = 0; |
CellIsChecked = 0; |
cells = 0; |
AkkuWarnThreshold = 0; |
OldWP = 0; |
NextWP = false; |
|
|
//------------------------- |
//------------------------- |
MAX_OSD_Screens = 8; |
|
#ifdef OSD_DEBUG_SCREEN |
MAX_OSD_Screens += 1; |
#endif |
|
if( Config.OSD_ScreenMode >= MAX_OSD_Screens ) Config.OSD_ScreenMode = 0; |
|
|
//------------------------- |
// Timer & Flags |
//------------------------- |
ScreenRefresh = OSD_SCREEN_REDRAW; |
flag = 0; |
timer = TIMEOUT; |
abo_timer = ABO_TIMEOUT; |
timer2 = OSD_REFRESH_TIME; |
|
|
do |
{ |
if( rxd_buffer_locked ) |
{ |
timer = TIMEOUT; |
Decode64 (); |
naviData = (NaviData_t *) pRxData; |
|
|
//---------------------------------- |
// Winkel zu Home |
//---------------------------------- |
if( Config.OSD_HomeMKView == 1 ) |
heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360; |
else |
heading_home = (naviData->CompassHeading - naviData->HomePositionDeviation.Bearing + 360 ) % 360; |
|
|
//---------------------------------- |
// speichere letzte GPS-Positionen |
//---------------------------------- |
GPS_Pos_t currpos; |
currpos.Latitude = naviData->CurrentPosition.Latitude; |
currpos.Longitude = naviData->CurrentPosition.Longitude; |
|
if((currpos.Latitude != last5pos[0].Latitude)&&(currpos.Longitude != last5pos[0].Longitude)) |
{ |
last5pos[6] = last5pos[5]; |
last5pos[5] = last5pos[4]; |
last5pos[4] = last5pos[3]; |
last5pos[3] = last5pos[2]; |
last5pos[2] = last5pos[1]; |
last5pos[1] = last5pos[0]; |
last5pos[0] = currpos; |
} |
|
// 07.03.2013 OG: Speichere permanent letzte Position in Config |
// wurde vorher nur in OSD_TimeOut() gemacht |
Config.LastLatitude = currpos.Latitude; // speichere letzte Position in Config |
Config.LastLongitude = currpos.Longitude; // speichere letzte Position in Config |
|
flag = 1; |
|
if (naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN) |
{ // should be engines running |
// motors are on, assume we were/are flying |
COSD_FLAGS2 |= COSD_WASFLYING; |
} |
|
|
//---------------------------------- |
// remember statistics (only when engines running) |
//---------------------------------- |
if( naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN ) |
{ |
if (naviData->Altimeter > max_Altimeter) max_Altimeter = naviData->Altimeter; |
if (naviData->GroundSpeed > max_GroundSpeed) max_GroundSpeed = naviData->GroundSpeed; |
if (naviData->HomePositionDeviation.Distance > max_Distance) max_Distance = naviData->HomePositionDeviation.Distance; |
if (naviData->FlyingTime > max_FlyingTime) max_FlyingTime = naviData->FlyingTime; |
if (naviData->UBat < min_UBat) min_UBat = naviData->UBat; |
if (naviData->Current > max_Current) max_Current = naviData->Current; |
if (naviData->UsedCapacity > max_Capacity) max_Capacity = naviData->UsedCapacity; |
} |
|
|
//---------------------------------- |
// OSD-Screens |
//---------------------------------- |
if( ScreenRefresh == OSD_SCREEN_REDRAW ) lcd_cls(); |
|
if( timer2 == 0 || ScreenRefresh == OSD_SCREEN_REDRAW) |
{ |
if( Config.OSD_ScreenMode == 0) ScreenName = OSD_Screen_General( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 1) ScreenName = OSD_Screen_Navigation( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 2) ScreenName = OSD_Screen_MKStatus( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 3) ScreenName = OSD_Screen_OSD0( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 4) ScreenName = OSD_Screen_OSD1( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 5) ScreenName = OSD_Screen_OSD2( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 6) ScreenName = OSD_Screen_3DLage( ScreenRefresh ); |
else if( Config.OSD_ScreenMode == 7) ScreenName = OSD_Screen_Statistics( ScreenRefresh ); |
|
#ifdef OSD_DEBUG_SCREEN |
else if( Config.OSD_ScreenMode == (MAX_OSD_Screens-1) ) ScreenName = OSD_Screen_Debug( ScreenRefresh ); |
#endif |
|
} |
ScreenRefresh = OSD_SCREEN_REFRESH; |
|
if( timer2 == 0 ) timer2 = OSD_REFRESH_TIME; |
|
|
//----------------------- |
// Key-Handler |
//----------------------- |
|
//if (get_key_press (1 << KEY_PLUS)) |
//{ |
// print_position (); |
//} |
|
if( get_key_press (1 << KEY_ENTER) ) // info |
{ |
OSD_Info( Config.OSD_ScreenMode, ScreenName); |
ScreenRefresh = OSD_SCREEN_REDRAW; |
} |
|
if (get_key_press (1 << KEY_MINUS)) // previous screen |
{ |
if( Config.OSD_ScreenMode == 0 ) |
Config.OSD_ScreenMode = MAX_OSD_Screens-1; |
else |
Config.OSD_ScreenMode--; |
ScreenRefresh = OSD_SCREEN_REDRAW; |
} |
|
if (get_key_press (1 << KEY_PLUS)) // next Screen |
{ |
Config.OSD_ScreenMode++; |
Config.OSD_ScreenMode = ( Config.OSD_ScreenMode >= MAX_OSD_Screens ? 0 : Config.OSD_ScreenMode ); |
ScreenRefresh = OSD_SCREEN_REDRAW; |
} |
|
|
//----------------------- |
// Akku Warnung |
//----------------------- |
CheckMKLipo(); |
|
// if (naviData->UBat > MK_LowBat) //bei kurzzeitigen Schwankungen Beeper erst wieder aus wenn UBat 0,2 V höher als Warnschwelle |
// { //Beeper aus |
// BeepTime = 0; |
// BeepMuster = 0xFFFF; |
// } |
// Akku Warnung Ende |
|
|
//----------------------- |
// remember last values |
//----------------------- |
last_RC_Quality = naviData->RC_Quality; |
last_UBat = naviData->UBat; |
old_FCFlags = naviData->FCStatusFlags; |
|
rxd_buffer_locked = FALSE; |
|
|
//----------------------- |
// abo_timer |
//----------------------- |
if (!abo_timer) |
{ // renew abo every 3 sec |
// request OSD Data from NC every 100ms |
// RS232_request_mk_data (1, 'o', 100); |
tmp_dat = 10; |
SendOutData ('o', ADDRESS_NC, 1, &tmp_dat, 1); |
abo_timer = ABO_TIMEOUT; |
} |
|
} //if (rxd_buffer_locked) |
|
if (!timer) |
{ |
OSD_Timeout(flag); |
flag = 0; |
ScreenRefresh = OSD_SCREEN_REDRAW; |
} |
|
} while (!get_key_press (1 << KEY_ESC)); |
|
OSD_active = false; |
} |
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |