0,0 → 1,4919 |
/***************************************************************************** |
* 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* |
* Oliver Gemesi "olli42" for additions und changes in OSDScreen * |
*****************************************************************************/ |
|
|
//-------------------- |
// Debug |
//-------------------- |
//#define DEBUG_OSD_TIME // mit dem NC-Simulator koennen keine brauchbaren Zeit/Datum Daten ermittelt werden |
// am Anfang von osd() wird mit dieser Einstellung eine gueltige Fake-Zeit/Date gesetzt |
//#define DEBUG_OSD_STAT_MOTORRUN // erzwingt Statistik Aufzeichnung auch wenn die Motoren nicht laufen |
|
//############################################################################ |
//# HISTORY osd.c |
//# |
//# 05.04.2015 Cebra |
//# - chg: SendOutData( 'h', ADDRESS_ANY, 2, &mkdisplayCmd, 1, 0x00,1) ergänzt um 2. Parameter wegen Fehlfunktion mit NC 2.09h |
//# |
//# 21.06.2014 OG |
//# - chg: osd() - bei auftreten von mk_timeout wieder OSD_MK_Connect(MK_CONNECT) |
//# aktiviert -> dadurch wird u.a. wieder auf die NC umgeschaltet falls |
//# etwas anderes (z.B. ein anderes PKT) auf die FC umgeschaltet hat |
//# - add: draw_icon_mk() |
//# |
//# 18.06.2014 OG |
//# - add: MKLiPoCells_Init(), MKLiPoCells_Check() |
//# - chg: define ORIENTATION_H, ORIENTATION_V verschoben nach osd.h |
//# |
//# 02.06.2014 OG |
//# - fix: Beep_Waypoint() Target-Reach Beep auch bei Single-WP's (WP-Listen |
//# die nur aus einem WP bestehen) |
//# |
//# 01.06.2014 OG |
//# Beginn von Auslagerungen von Code alter OSD-Screens nach osdold_screens.c/h |
//# - add: include "../osd/osdold_screens.h" |
//# - add: include "../osd/osdold_messages.h" |
//# - chg: osd() - Check bzgl. NC-Hardware entfernt da das bereits durch das |
//# aufrufende Menue erledigt wird |
//# - add: OSD_Screen_MKDisplay() um Beep_Waypoint() ergaenzt |
//# - chg: OSD_Screen_Waypoints() umgestellt auf Beep_Waypoint() |
//# - add: Beep_Waypoint() |
//# |
//# 31.05.2014 OG |
//# - chg: OSD_Screen_MKDisplay() - umgestellt auf PKT_KeylineUpDown() |
//# |
//# 26.05.2014 OG |
//# - add: etliche Aenderungen/Erweiterung am Screen "Waypoints" (auch neues Layout) |
//# |
//# 24.05.2014 OG |
//# - fix: OSD_Screen_Waypoints(), OSD_Screen_MKDisplay() - Anzeige des akt. WP-Index |
//# - chg: OSD_Screen_3DLage() - optisches Facelift |
//# - fix: OSD_Screen_3DLage() - es wurden ggf. Kreise gezeichnet die ungueltig |
//# und in undefinierten Speicher gingen - wurde korrigiert |
//# - chg: OSD0,1,2 angepasst an OSD_Element_CompassDirection() mit xoffs,yoffs |
//# - chg: OSD_Element_CompassDirection() - erweitert um xoffs,yoffs |
//# |
//# 20.05.2014 OG |
//# - chg: OSD_Element_Flag_Label() - Anpassung zur Rahmenbestimmung eines Flags |
//# |
//# 19.05.2014 OG |
//# - fix: osd() - Tastensteuerung bei MK-Empfangsverlust |
//# - chg: osd() - wenn MK-Setting nicht ermittelt werden konnte dann exit |
//# - add: OSD_Screen_MKDisplay() - Anzeige von akt. Waypoint und Anzahl der Waypoints |
//# - chg: OSD_Popup_MKSetting() - gibt true/false fuer Ok zurueck und Beep bei Fehler |
//# - chg: OSD_Popup_MKSetting() - timeout von 15 auf 9 reduziert |
//# - chg: OSD_Popup_MKSetting(), OSD_Popup_MKError() - Layout, Multi-Sprachenunterstuetzung |
//# |
//# 02.05.2014 OG |
//# - del: Popup_Draw() (jetzt in lcd.c) |
//# |
//# 02.05.2014 OG |
//# - chg: kleine Aenderung an Codereihenfolge von MkError_Save() wegen Compiler-Warning |
//# |
//# 28.04.2014 OG |
//# Anmerkung OSD-MK-Display: wenn der MK-Display Modus eingeschaltet wird, dann werden die Display Daten |
//# angefordert und die BL-Daten etwas reduziert. Hin und wieder kann es passieren das ein Tastendruck im |
//# OSD-MK-Display-Modus nicht durch kommt (aber nicht allzu stoerend) - kann evtl. verbessert werden wenn |
//# auch die OSD-Daten reduziert werden (waere jedoch einiges mehr Aufwand). |
//# - Unterstuetzung von MK-Display (nur NC-Modus) im OSD |
//# (einschalten mit langem Druck dritte Taste von links, abschalten ebenso) |
//# - Info-Anzeige bzgl. langem Tastendruck fuer MK-Display erweitert und deutsche Uebersetzung von "long press" |
//# - Umstrukturierung von osd.c fuer MK-Display |
//# - Aenderungen/Erweiterungen an verschiedenen weiteren Funktionen wie OSD_MK_GetData() fuer MK-Display |
//# - add: OSD_MK_ShowTimeout() - neues Design/Layout |
//# - del: OSD_Timeout() (ersetzt durch OSD_MK_ShowTimeout()) |
//# - chg: verschiedene Aenderungen an Timings |
//# - add: neuer Timer fuer MK-Display: timer_get_displaydata |
//# - fix: es gab bei einem Datenpaket-Timer einen Konflikt mit 'timer' - ein neuer Timer wurde aktiviert (timer_mk_timeout) |
//# |
//# 22.04.2014 OG |
//# - add: OSD_Element_HomeCircleX() - soll das alte OSD_Element_HomeCircle() ersetzen, wenn |
//# die alten OSD-Screens endgueltig rausfliegen |
//# - chg: Aenderung Anzeige OSD_Screen_UserGPS() (abgerundete Ecken und Code Einsparung) |
//# - chg: Aenderung Anzeige OSD_Screen_MKStatus() (abgerundete Ecken und Code Einsparung) |
//# - chg: Aenderung Anzeige OSD_Screen_Electric() (abgerundete Ecken und Code Einsparung) |
//# |
//# 01.03.2014 OG |
//# - chg: OSD_Popup_MKError() auf lcdx_printp_center() umgestellt |
//# |
//# 16.02.2014 OG |
//# - chg: OSD_Popup_MKSetting() umgestellt auf MK_Setting_load() |
//# |
//# 13.02.2014 OG |
//# - chg: OSD_MK_GetData() prueft mit MKVersion_Cmp() auf NC-Version v0.30g |
//# ob GPS-Zeit-Datenpakete ('t') von der NC angefordert werden koennen |
//# |
//# 12.02.2014 OG |
//# - chg: define MKVERSIONnnn rund um OSD_MK_UTCTime() entfernt |
//# -> TODO OG: auf neue MKVersion bzgl. Versionsprüfung anpassen! |
//# -> keine Unterstuetzung mehr durch zu alte NC-Versionen |
//# - del: die includes zu den alten parameter... entfernt |
//# |
//# 10.02.2014 OG |
//# - chg: OSD_Popup_MKSetting() umgestellt auf MKVersion_Setting_print() |
//# |
//# 08.02.2014 OG |
//# - chg: OSD_Popup_MKSetting() umgestellt auf neue MKVersion Struktur |
//# |
//# 04.02.2014 OG |
//# - fix: OSD_Element_BattLevel2() Aufruf von writex_ndigit_number_u_100th() |
//# |
//# 03.02.2014 OG |
//# - chg: OSD_Element_BattLevel2() unterstuetzt Config.OSD_ShowCellU zur Anzeige |
//# der MK-Spannung als Einzelzelle (kalk. auf Basis der ermittelten Zellenzahl) |
//# |
//# 29.01.2014 OG |
//# - add: neue MK-Errorcodes 32,33,34 |
//# - add: #include "mk/mkbase.h" |
//# |
//# 24.01.2014 OG |
//# - chg: OSD_Popup_MKSetting(): MK-Settings wird beim Start vom OSD wieder angezeigt |
//# auch wenn die falsche FC-Revision vorhanden ist mit folgender Regel: |
//# a) wenn falsche FC-Settings-Revision dann nur die Nummer |
//# b) wenn richtige FC-Revision dann mit Nummer und Namen |
//# |
//# 06.01.2014 Cebra |
//# - add: MK-Settingsname wird bei falscher FC Version nicht angezeigt |
//# |
//# 07.07.2013 OG |
//# - add: OSD-Screens koennen vom Benutzer an-/ausgeschaltet werden (osd(), ScreenCtrl_Push()) |
//# - chg: OSD-Screen Namen jetzt in messages.c |
//# - fix: MK-Error Check prueft ob die Fehlernummer gueltig ist |
//# - del: alten Screen Electric (der ohne Nachkomma bei den Stroemen) |
//# |
//# 03.07.2013 OG |
//# - chg: OSD_Popup_MKSetting() - zentrierte Anzeige des Setting-Namens |
//# - chg: OSD_Popup_MKSetting() - timing |
//# - chg: osd() - Screen-Umschaltung beschleunigt |
//# - chg: timinigs bei OSD_MK_Connect(), osd() (werden Verbindungsfehler reduziert?) |
//# |
//# 02.07.2013 OG |
//# - chg: CheckMKLipo() - MK-Unterspannungs-Beep nur wenn Motoren laufen |
//# - del: unbenutzte Variablen |
//# |
//# 30.06.2013 OG |
//# - add: grafische Akku-Anzeige auch fuer Screen Navigation und ElectricN |
//# |
//# 30.06.2013 OG |
//# - add: Screen General: das Batt-Symbol zeigt grafisch den Fuellstand |
//# des MK-Lipos |
//# - add: Mittelwert fuer Gesamtstrom |
//# - add: calc_avg() - Mittelwertberechnung |
//# - chg: Benamung Statistik-Var's von mid_* auf avg_* geaendert |
//# - add: USE_OSD_PKTHOOK in osd() - aktuell noch nicht klar ob PKT_Hook() |
//# die Kommunikation stoert |
//# |
//# 27.06.2013 OG |
//# - chg: numerische Winkelanzeige im Screen "Navigation" von -180 bis 180 Grad |
//# 0 Grad = vorderer Ausleger zeigt zur Startposition |
//# - fix: Homesicht des MK's (Winkelanzeige, Grafik) |
//# ab nun: keine Benutzereinstellung mehr dafuer |
//# es gilt: 0 Grad bzw. Strich nach unten -> der vordere Ausleger des MK |
//# zeigt auf seine Startposition |
//# |
//# 19.06.2013 OG |
//# - fix: redundante PKT-Error 40 eliminiert durch merken via old_PKTErrorcode |
//# -> hilft wenn der MK ausgeschaltet wird waehrend man in der PKT-OSD-Anzeige ist |
//# - fix: last_FlyTime in osd() |
//# |
//# 18.06.2013 OG |
//# - chg: OSD_Timeout() erweitert um Errorlogging (Code 40 = "PKT RX lost") |
//# - add: Fehlerliste "PKT RX lost" (Code: 40) |
//# |
//# 15.06.2013 OG |
//# - chg: Anzeige OSD_Popup_MKSetting() kann durch Benutzer via Setup an/ausgeschaltet werden |
//# |
//# 15.06.2013 OG |
//# - chg: OSD_Popup_MKSetting() optimiert, Layout, fix |
//# - chg: PKT_CtrlHook erstmal wieder disabled in osd() (evtl. Probleme mit Timings?) |
//# |
//# 13.06.2013 cebra |
//# - add: Settings Popup beim Start des OSD-Screens |
//# |
//# 11.06.2013 OG |
//# - add: Mittelwertberechnung BL-Strom [MK_GetData()] |
//# - chg: Config.OSD_ScreenMode wird vor PKT_CtrlHook() gesetzt [osd()] |
//# |
//# 27.05.2013 OG |
//# - fix: OSD_MK_UTCTime() (neue "t" Version) Problem wegen cast fuer Sekunden |
//# |
//# 19.05.2013 OG |
//# - chg: osd() erweitert um PKT_CtrlHook() um u.a. PKT-Updates zu ermoeglichen |
//# |
//# 16.05.2013 OG |
//# - add: USE_OSD_SCREEN_NAVIGATION, USE_OSD_SCREEN_ELECTRIC, USE_OSD_SCREEN_ELECTRIC_N, |
//# USE_OSD_SCREEN_MKSTATUS, USE_OSD_SCREEN_USERGPS, USE_OSD_SCREEN_3DLAGE, |
//# USE_OSD_SCREEN_STATISTIC |
//# - add: OSD_Screen_ElectricN() - zeigt BL-Stroeme mit Nachkomma an |
//# - del: define SHOW_OSD_BLCURRENT_10TH (ersetzt durch neue Screen-Variante) |
//# - chg: osd() umgestellt auf OSD Screen Controler; Anpassungen dafuer an allen Screens |
//# - add: Funktionen fuer Screen Controler (Screen_*()) |
//# |
//# 15.05.2013 OG |
//# - chg: OSD_Screen_Electric() zeigt BL-Strom mit Nachkomma an |
//# (einstellbar via define SHOW_OSD_BLCURRENT_10TH bzgl. neue/alte Anzeige) |
//# - add: define DEBUG_OSD_STAT_MOTORRUN erzwingt Statistik Aufzeichnung auch wenn |
//# die Motoren nicht laufen |
//# - fix: osd() Statistik-Ende Zeit wird nach Landung gesetzt |
//# - chg: diverse Aufraeumarbeiten |
//# - chg: OSD_Screen_Statistics() umgetsellt auf calc_BLmax(() |
//# - add: calc_BLmax() ermittelt max. BL Current & Temp |
//# - del: draw_symbol_degree(), draw_symbol_rc() - wurden ersetzt durch |
//# Zeichen im font 8x6 (SYMBOL_SMALLDEGREE, SYMBOL_RCQUALITY) |
//# |
//# 14.05.2013 OG |
//# - add: OSD_MK_Connect() vereinheitlicht MK-Verbindungsinitialisierung |
//# und MK-Abo-Renew |
//# - chg: OSD_MK_UTCTime() atomisiert via ATOMIC_BLOCK() |
//# - chg: OSD_Screen_Debug_RX() verschiedene Optimierungen und Beschreibungen |
//# |
//# 14.05.2013 OG |
//# - chg: OSD_MK_UTCTime() wird mittels define jetzt mit neuem oder mit altem |
//# Algorithmus einkompiliert. |
//# ALT bei: defined MKVERSION088n || defined MKVERSION090b || defined MKVERSION090e |
//# NEU bei: alles andere (also neuer): die neue Zeit/Datumsermittlung |
//# |
//# 13.05.2013 OG |
//# - fix: an allen Stellen mit naviData->CompassHeading ein Modulo 360 ergaenzt |
//# um Winkelangaben der FC geradezuziehen falls der Kopter beim Mixersetup |
//# 'verdreht' wurde (Problem von helitron im Forum - Winkelanzeige > 360 Grad) |
//# Ist ggf. ab Firmware NC 0.30h nicht mehr notwendig da Holger das |
//# korrigieren wollte (muesste noch geprueft werden) |
//# |
//# 11.05.2013 OG |
//# - add: OSD_MK_UTCTime_NEW() - ab NC 0.30g (Alpha, noch nicht im Einsatz) |
//# |
//# 05.05.2013 OG |
//# - chg: OSD_Popup_Info() & OSD_Popup_MKError() wurden vereinheitlicht |
//# mittels Popup_Draw() |
//# - chg: Anzeigezeiten der Popup's etwas verkuerzt |
//# |
//# 03.05.2013 OG |
//# - fix: OSD_MK_GetData() - griff beim lesen der BL's auf naviData fuer |
//# die Statistik - relevante naviData-Werte werden nun vor dem |
//# wechseln auf BL-Data gemerkt |
//# - chg: Erfassung der Statistik Start/Ende-Zeit verbessert |
//# - chg: bei Aufrufen von writex_datetime_time()/writex_datetime_time() den |
//# Parameter 'timeoffset' entfernt |
//# - add: define DEBUG_OSD_TIME um eine Fake-Zeit/Datum bei Gebrauch des |
//# NC-Simulators zu setzen |
//# |
//# 29.04.2013 OG |
//# - chg: Plausibilitaetscheck in OSD_MK_UTCTime() bzgl. des Datums |
//# |
//# 28.04.2013 OG |
//# - chg: die alten OSD-Screens angepasst auf define USE_FONT_BIG |
//# |
//# 24.04.2013 OG |
//# - chg: directions_p[] geaendert auf Kompatibilitaet mit Atmel Studio 6 |
//# |
//# 21.04.2013 OG |
//# - chg: define AltimeterAdjust nach osd.h verschoben |
//# |
//# 14.04.2013 OG |
//# - add: weitere Statistik-Aufzeichnungen |
//# - fix: MK_GetData() - Statistik-Aufzeichnung nur fuer wirklich vorhandene BL's |
//# |
//# 04.04.2013 OG |
//# - fix: 3 warnings |
//# |
//# 04.04.2013 OG |
//# - chg: MK-Errortext-Anzeige umgestellt auf naviData->Errorcode |
//# weniger Datenkomminkation mit dem MK und schnelleres Ansprechverhalten |
//# |
//# 03.04.2013 OG |
//# - chg: defines OSD_DEMO, OSD_SCREEN_DEBUG, OSD_SCREEN_OLD |
//# umbenannt nach: USE_OSD_DEMO, USE_OSD_SCREEN_DEBUG, USE_OSD_SCREEN_OLD |
//# und verschoben nach: main.h |
//# |
//# 28.03.2013 OG |
//# - fix: MKErr_Log_Init() - es fehlte Multiplikation mit MAX_MKERR_LOG |
//# - chg: Code Formatierungen |
//# |
//# 28.03.2013 CB |
//# - add: replace OSD_Statistic, GPS_User, MKErr_Log in EEProm structure variable |
//# |
//# 28.03.2013 OG |
//# - fix: abo_timer wieder aktiviert fuer 'o' und 'k' |
//# |
//# 28.03.2013 OG |
//# - chg: osd_statistic_t - erweitert um diverse Werte und Timestamps (werden apeter implementiert) |
//# - add: mkerror_t MKErr_Log[MAX_MKERR_LOG] - Vorbereitung um MK-Errors zu loggen |
//# |
//# 27.03.2013 OG |
//# - add: Datum / Zeit vom MK lesen |
//# - chg: Kommunikation mit dem MK optimiert |
//# - chg: auf neue messages.c angepasst |
//# - struct von den Statistiken auf PKTdatetime PKTdatetime_t |
//# - verschiedene andere Aenderungen |
//# |
//# 22.03.2013 OG |
//# erhebliche Aenderungen / Ergaenzungen - hier nur das Wichtigste |
//# - neue Funktion "User GPS" (UGPS) - mit langem Druck auf Taste KEY_ENTER werden die aktuellen GPS-Daten abgespeichert |
//# * gespeichert wird nur wenn wenn der MK GPS-Ok meldet |
//# * wenn Ok erfolgt ein bestaetigungs Beep; wenn nicht Ok erfolgt ein Error-Beep |
//# - neuer Screen "User GPS" - Anzeige der letzten der 3 UGPS-Koordinaten (intern wird mehr gespeichert) |
//# - Anzeige von MK-Error Messages als Popup mit einstellbarer Anzeigezeit (kann mit Taste abgebrochen werden) |
//# * kann getestet werden z.B. durch Ausschalten der Funke (= "RC Signal lost") |
//# * siehe: http://www.mikrokopter.de/ucwiki/ErrorCodes |
//# - OSD-Info ist nun ein Popup - autom. ausblenden nach einstellbarer Zeit; im Hintergrund werden weiterhin MK-Daten empfangen und ausgewertet |
//# - neuer Debug-Screen "Debug RXPackages" - zeigt die Anzahl empfangener Datenpakete der verschiedenen Bereiche (um z.B. Timings einzustellen) |
//# - erweiterte Kommunikation mit dem MK fuer BL-Daten und Error-Messages |
//# - Timings der MK-Datenkommunikation weitreichend einstellbar durch defines |
//# - Datenstrukturen fuer OSD-Statistiken und BL-Statistiken |
//# - neue timer: timer_get_erdata, timer_get_bldata, timer_osd_refresh, timer_pkt_uptime |
//# - mit dem define OSD_SCREEN_OLD koennen ggf. die alten OSD-Screens ausgeblendet werden (spart ein paar KByte's) |
//# - verschiedene Optimierungen |
//# |
//# 12.03.2013 OG |
//# - add: Get_BL_Data() - BL-Ctrl via NC auslesen (BETA) (siehe dort auch Kommentare im func-Header) |
//# - add: neuer Screen "Electric" |
//# - chg: Layout von Screen "Navigation" - Pixelverschiebungen |
//# - chg: Layout von Screen "MK-Status" - Pixelverschiebungen und Anzeige 'Strom' ersetzt durch 'entn. Kapazitaet' |
//# - add: in osd() LiPO-Cell Erkennung hinzugefuegt (fuer Screen "Electric") |
//# |
//# 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 TIME_OSD_REFRESH) |
//# - 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_MK_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: USE_OSD_DEMO (main.h) |
//# 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: USE_OSD_SCREEN_DEBUG (main.h) |
//# mit diesem define wird ein zusaetzlicher Screen "Debug" einkompiliert |
//# fuer Test / Experimente / Debug von OSD-Elementen |
//# |
//# 3. define: USE_OSD_SCREEN_OLD (main.h) |
//# ein-/ ausschalten der alten OSD-Screens OSD0, OSD1, OSD2 (spart ca. 3 KByte) |
//# |
//# 4. Timings der MK-Datenkommunikation |
//# die Timings sind weitreichend enstellbar ueber die define im Abschnitt 'Timings' |
//# der Debug-Screen 'Debug RXPackages' informiert ueber die Anzahl eingegangener |
//# Datenpakete der verschiedenen Bereiche (OSD, BL-Daten, Error-Message) |
//# |
//# 5. Informationen zum Display |
//# DOG: 128 x 64 Pixel with 6x8 Font => 21 x 8 |
//# |
//# 6. MK-Kommunikationsprotokoll Referenz |
//# 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 |
//############################################################################ |
|
#include "../cpu.h" |
#include <avr/io.h> |
#include <inttypes.h> |
#include <stdlib.h> |
#include <avr/pgmspace.h> |
#include <util/delay.h> |
#include <string.h> |
#include <util/atomic.h> |
|
#include "../main.h" |
#include "../lcd/lcd.h" |
#include "../timer/timer.h" |
#include "../uart/usart.h" |
#include "../eeprom/eeprom.h" |
#include "../messages.h" |
#include "../sound/pwmsine8bit.h" |
#include "../mk-data-structs.h" |
#include "../pkt/pkt.h" |
#include "../osd/osd.h" |
#include "../utils/xutils.h" |
#include "../mk/mkbase.h" |
#include "../osd/osdold_messages.h" |
#include "../osd/osdold_screens.h" |
|
|
//-------------------- |
// Funktionen ein-/ausbinden |
//-------------------- |
// -> siehe main.h |
|
|
//-------------------- |
// Timings |
//-------------------- |
#define TIME_OSD_REFRESH 45 // Screen Refresh (Steuerung via 'timer_osd_refresh') (n*10 = ms; 100 entspricht 1 Sekunde) |
#define TIME_POPUP_INFO 400 // 4 Sekunden Popup-Info zeigen (kann mit Taste abgebrochen werden) |
#define TIME_POPUP_MKERROR 700 // 7 Sekunden Popup-MK-Error zeigen (kann mit Taste abgebrochen werden) |
|
#define TXINTERVAL_OSDDATA 10 // Intervall mit der der MK OSD-Daten senden soll (n*10 = ms) |
|
#define TIME_GET_BLDATA 35 // Zeitintervall in der BL-Daten vom MK geholt werden (Steuerung via 'timer_get_bldata') (n*10 = ms; 100 entspricht 1 Sekunde) |
#define TIME_READ_BLDATA 20 // fuer n Zeit werden BL-Daten vom MK gelesen (Steuerung via timer) (n*10 = ms; 100 entspricht 1 Sekunde)) |
#define TXINTERVAL_BLDATA 7 // Intervall mit der der MK BL-Daten senden soll (n*10 = ms) |
|
#define TIME_GET_TIDATA 12000 // alles 120 Sekunden Zeit/Datum vom MK lesen (die Zwischenzeit wird von einem PKT-Timer uebernommen) |
|
#define TIME_GET_DISPLAYDATA 20 // fuer n Zeit werden BL-Daten vom MK gelesen (Steuerung via timer) (n*10 = ms; 100 entspricht 1 Sekunde)) |
|
|
//#define MK_TIMEOUT 300 // MK-Verbindungsfehler wenn fuer n Zeit keine gueltigen Daten hereinkommen (3 sec) |
#define MK_TIMEOUT 400 // MK-Verbindungsfehler wenn fuer n Zeit keine gueltigen Daten hereinkommen (4 sec) |
|
|
//-------------------- |
// weiteres |
//-------------------- |
#define OSD_POPUP_NONE 0 |
#define OSD_POPUP_INFO 1 |
#define OSD_POPUP_MKERROR 2 |
|
#define MK_CONNECT 1 |
#define MK_ABORENEW 2 |
|
|
|
// global definitions and global vars |
NaviData_t *naviData; |
uint16_t heading_home; |
uint8_t drawmode; |
uint8_t OSDScreenRefresh; |
|
|
// flags from last round to check for changes |
uint8_t old_AngleNick = 0; |
uint8_t old_AngleRoll = 0; |
uint16_t old_hh = 0; |
|
|
// aktuell nicht benoetigt - siehe Kommentar in osd.c |
//mk_param_struct_t *mk_param_struct; |
//uint8_t Flags_ExtraConfig; |
//uint8_t Flags_GlobalConfig; |
//uint8_t Flags_GlobalConfig3; |
|
|
// cache old vars for blinking attribute, checkup is faster than full |
// attribute write each time |
|
volatile uint8_t OSD_active = 0; |
|
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; |
|
uint8_t WP_old = 0; // Screen: "Waypoints" |
uint8_t WP_last = false; // Screen: "Waypoints" |
|
|
|
#define MAX_CELL_VOLTAGE 43 // max cell voltage for LiPO |
#define MIN_CELL_VOLTAGE 32 // min cell voltage for LiPO |
|
// Flags |
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; |
|
|
//----------------------------------------------------------- |
// Buffer |
//----------------------------------------------------------- |
BLData_t blData[OSD_MAX_MOTORS]; // speichert gelesene BL-Datenpakete |
pkt_gpspos_t GPS_Current; // aktuelle GPS-Position |
u8 old_PKTErrorcode; // speichert den letzen Errorcode vom PKT damit dieser nicht wiederholt gespeichert wird |
u8 old_MKErrorcode; // speichert den letzen Errorcode vom MK damit dieser nicht wiederholt angezeigt wird |
|
|
//----------------------------------------------------------- |
// OSD Daten |
//----------------------------------------------------------- |
NaviData_t osdData; // Buffer |
|
//----------------------------------------------------------- |
// MK-DISPLAY |
//----------------------------------------------------------- |
uint8_t mkdisplayMode = false; |
uint8_t mkdisplayCmd = 0xff; |
char mkdisplayData[81]; // Buffer (80 +1 fuer term. Char) |
|
|
//--------------------- |
// DEBUG |
//--------------------- |
#ifdef USE_OSD_SCREEN_DEBUG |
uint16_t readCounterOSD; // Anzahl gelesener Datenpakete von NC Modus 'o' (Request OSD-Data) |
uint16_t readCounterTIME; // Anzahl gelesener Datenpakete von NC (Time) |
uint16_t readCounterDISPLAY; |
uint16_t readCounterBL[OSD_MAX_MOTORS]; // Anzahl gelesener Datenpakete pro BL via NC Modus 'k' (BL Ctrl Status) |
#endif // USE_OSD_SCREEN_DEBUG |
|
|
//--------------------- |
// Strings & Co. |
//--------------------- |
static const char mkerror00[] PROGMEM = "No Error"; |
static const char mkerror01[] PROGMEM = "FC not compatible"; |
static const char mkerror02[] PROGMEM = "MK3Mag not compati."; |
static const char mkerror03[] PROGMEM = "no FC communication"; |
static const char mkerror04[] PROGMEM = "no MK3Mag communic."; |
static const char mkerror05[] PROGMEM = "no GPS communication"; |
static const char mkerror06[] PROGMEM = "bad compass value"; |
static const char mkerror07[] PROGMEM = "RC Signal lost"; |
static const char mkerror08[] PROGMEM = "FC spi rx error"; |
static const char mkerror09[] PROGMEM = "no NC communication"; |
static const char mkerror10[] PROGMEM = "FC Nick Gyro"; |
static const char mkerror11[] PROGMEM = "FC Roll Gyro"; |
static const char mkerror12[] PROGMEM = "FC Yaw Gyro"; |
static const char mkerror13[] PROGMEM = "FC Nick ACC"; |
static const char mkerror14[] PROGMEM = "FC Roll ACC"; |
static const char mkerror15[] PROGMEM = "FC Z-ACC"; |
static const char mkerror16[] PROGMEM = "Pressure sensor"; |
static const char mkerror17[] PROGMEM = "FC I2C"; |
static const char mkerror18[] PROGMEM = "Bl Missing"; |
static const char mkerror19[] PROGMEM = "Mixer Error"; |
static const char mkerror20[] PROGMEM = "Carefree Error"; |
static const char mkerror21[] PROGMEM = "GPS lost"; |
static const char mkerror22[] PROGMEM = "Magnet Error"; |
static const char mkerror23[] PROGMEM = "Motor restart"; |
static const char mkerror24[] PROGMEM = "BL Limitation"; |
static const char mkerror25[] PROGMEM = "Waypoint range"; |
static const char mkerror26[] PROGMEM = "No SD-Card"; |
static const char mkerror27[] PROGMEM = "SD Logging aborted"; |
static const char mkerror28[] PROGMEM = "Flying range!"; |
static const char mkerror29[] PROGMEM = "Max Altitude"; |
static const char mkerror30[] PROGMEM = "No GPS Fix"; |
static const char mkerror31[] PROGMEM = "compass not calibr."; |
static const char mkerror32[] PROGMEM = "BL selftest"; |
static const char mkerror33[] PROGMEM = "no ext. compass"; |
static const char mkerror34[] PROGMEM = "compass sensor"; |
|
#define MAX_MKERROR_NUM 34 // maximale Error-Nummer vom MK (verwendet in osd()) |
|
static const char mkerror35[] PROGMEM = ""; // free for MK |
static const char mkerror36[] PROGMEM = ""; // free for MK |
static const char mkerror37[] PROGMEM = ""; // free for MK |
static const char mkerror38[] PROGMEM = ""; // free for MK |
static const char mkerror39[] PROGMEM = ""; // free for MK |
|
static const char pkterror40[] PROGMEM = "PKT RX lost"; |
|
|
//--------------------------------------- |
// wenn die Liste erweitert wird, |
// MAX_MKERROR_NUM in osd.h anpassen! |
//--------------------------------------- |
const char * const mkerrortext[] PROGMEM= |
{ |
mkerror00, |
mkerror01, |
mkerror02, |
mkerror03, |
mkerror04, |
mkerror05, |
mkerror06, |
mkerror07, |
mkerror08, |
mkerror09, |
mkerror10, |
mkerror11, |
mkerror12, |
mkerror13, |
mkerror14, |
mkerror15, |
mkerror16, |
mkerror17, |
mkerror18, |
mkerror19, |
mkerror20, |
mkerror21, |
mkerror22, |
mkerror23, |
mkerror24, |
mkerror25, |
mkerror26, |
mkerror27, |
mkerror28, |
mkerror29, |
mkerror30, |
mkerror31, |
mkerror32, |
mkerror33, |
mkerror34, |
mkerror35, |
mkerror36, |
mkerror37, |
mkerror38, |
mkerror39, |
pkterror40 |
}; |
|
|
//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 |
static const char str_NE[] PROGMEM = "NE"; |
static const char str_E[] PROGMEM = "E "; |
static const char str_SE[] PROGMEM = "SE"; |
static const char str_S[] PROGMEM = "S "; |
static const char str_SW[] PROGMEM = "SW"; |
static const char str_W[] PROGMEM = "W "; |
static const char str_NW[] PROGMEM = "NW"; |
static const char str_N[] PROGMEM = "N "; |
|
const char * const directions_p[] PROGMEM= |
{ |
str_NE, |
str_E, |
str_SE, |
str_S, |
str_SW, |
str_W, |
str_NW, |
str_N |
}; |
|
|
//########################################################### |
//# OSD Screen Controler |
//########################################################### |
|
#define SCREENCTRL_MAX 15 // Anzahl max. zu verwaltender Screens |
|
//--------------------------- |
// typedef: einzelner Screen |
//--------------------------- |
typedef struct |
{ |
const char *screenname; |
void (*screen)(void); |
} screen_t; |
|
|
//--------------------------- |
// typedef: Screenliste |
//--------------------------- |
typedef struct |
{ |
uint8_t active; |
uint8_t count; |
screen_t screen[SCREENCTRL_MAX]; |
} screenlist_t; |
|
screenlist_t osdscreens; |
|
|
//-------------------------------------------------------------- |
// ScreenCtrl_Init() |
// |
// initialisiert die Screenliste - muss vor dem ersten |
// ScreenCtrl_Push() aufgerufen werden |
//-------------------------------------------------------------- |
void ScreenCtrl_Init( void ) |
{ |
osdscreens.active = 0; |
osdscreens.count = 0; |
} |
|
|
//-------------------------------------------------------------- |
// ScreenCtrl_Push( *screenname, *screenfunc) |
// |
// fuegt einen Screen der Screenliste hinzu (siehe osd()) |
//-------------------------------------------------------------- |
void ScreenCtrl_Push( uint8_t screenid, const char *screenname, void (*screenfunc)(void)) |
{ |
if( osdscreens.count < SCREENCTRL_MAX ) |
{ |
// wenn screenid = 0 dann immer anzeigen (Screen ist nicht vom Benutzer auswaehlbar) |
if( (screenid==0) || ((Config.OSD_UseScreen & (1 << screenid)) != 0) ) |
{ |
osdscreens.screen[osdscreens.count].screenname = screenname; |
osdscreens.screen[osdscreens.count].screen = screenfunc; |
osdscreens.count++; |
} |
} |
} |
|
|
//-------------------------------------------------------------- |
// ScreenCtrl_Set( screennum) |
// |
// aktiviert einen bestimmten Screen aus der Screenliste |
//-------------------------------------------------------------- |
void ScreenCtrl_Set( uint8_t screennum ) |
{ |
osdscreens.active = 0; |
if( screennum < osdscreens.count ) |
{ |
osdscreens.active = screennum; |
} |
} |
|
|
//-------------------------------------------------------------- |
// num = ScreenCtrl_GetNum() |
// |
// gibt die Nummer des aktuell aktivierten Screens zurueck |
//-------------------------------------------------------------- |
uint8_t ScreenCtrl_GetNum( void ) |
{ |
return osdscreens.active; |
} |
|
|
//-------------------------------------------------------------- |
// name = ScreenCtrl_GetName() |
// |
// gibt den Namen des aktuell aktivierten Screens zurueck |
// Rueckgabe ist ein Pointer auf einen String im PROGMEM |
//-------------------------------------------------------------- |
const char * ScreenCtrl_GetName( void ) |
{ |
return osdscreens.screen[osdscreens.active].screenname; |
} |
|
|
//-------------------------------------------------------------- |
// ScreenCtrl_Next() |
// |
// zum naechsten Screen wechseln |
//-------------------------------------------------------------- |
void ScreenCtrl_Next( void ) |
{ |
osdscreens.active++; |
if( osdscreens.active >= osdscreens.count ) |
{ |
osdscreens.active = 0; |
} |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
} |
|
|
//-------------------------------------------------------------- |
// ScreenCtrl_Previous() |
// |
// zum vorherigen Screen wechseln |
//-------------------------------------------------------------- |
void ScreenCtrl_Previous( void ) |
{ |
if( osdscreens.active == 0 ) |
{ |
osdscreens.active = osdscreens.count-1; |
} |
else |
{ |
osdscreens.active--; |
} |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
} |
|
|
//-------------------------------------------------------------- |
// ScreenCtrl_Show() |
// |
// ruft den aktuell Screen auf |
//-------------------------------------------------------------- |
void ScreenCtrl_Show( void ) |
{ |
osdscreens.screen[osdscreens.active].screen(); |
} |
|
|
//########################################################### |
//########################################################### |
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void calc_BLmax( osd_BLmax_t *blmax ) |
{ |
uint8_t i; |
|
memset( blmax, 0, sizeof(osd_BLmax_t) ); |
|
for( i=0; i<Config.OSD_Statistic.BL_Count; i++) |
{ |
if( Config.OSD_Statistic.BL[i].max_Current > blmax->max_BL_Current ) |
{ |
blmax->max_BL_Current = Config.OSD_Statistic.BL[i].max_Current; |
blmax->max_BL_Current_Index = i; |
} |
|
if( Config.OSD_Statistic.BL[i].max_Temp > blmax->max_BL_Temp ) |
{ |
blmax->max_BL_Temp = Config.OSD_Statistic.BL[i].max_Temp; |
blmax->max_BL_Temp_Index = i; |
} |
|
} |
} |
|
|
|
//-------------------------------------------------------------- |
// STAT_Init() |
// |
// initialisiert die Statistic Werte neu |
//-------------------------------------------------------------- |
void STAT_Init(void) |
{ |
// init: statistic |
memset( &Config.OSD_Statistic, 0, sizeof(osd_statistic_t) ); |
|
Config.OSD_Statistic.min_UBat = 255; |
Config.OSD_Statistic.min_RCQuality = 255; |
Config.OSD_Statistic.min_AngleNick = 126; |
Config.OSD_Statistic.min_AngleRoll = 126; |
} |
|
|
|
//-------------------------------------------------------------- |
// MKErr_Log_Init() |
// |
// initialisiert die MK Errorcodes neu |
//-------------------------------------------------------------- |
void MKErr_Log_Init(void) |
{ |
// init: MK Errorlog |
memset( &Config.MKErr_Log, 0, sizeof(mkerror_t)*MAX_MKERR_LOG ); |
|
} |
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void MkError_Save( uint8_t Errorcode ) |
{ |
uint8_t i; |
|
for( i=MAX_MKERR_LOG-1; i>0; i--) |
{ |
Config.MKErr_Log[i] = Config.MKErr_Log[i-1]; |
} |
|
Config.MKErr_Log[0].Errorcode = Errorcode; |
memcpy( &Config.MKErr_Log[0].set_Time, (char *)&UTCTime, sizeof(PKTdatetime_t) ); // sichern... |
} |
|
|
|
//-------------------------------------------------------------- |
// OSD_MK_Connect() |
// |
// Verbindung zum MK herstellen oder ABO-Renew |
// |
// modus: MK_CONNECT oder MK_ABORENEW |
//-------------------------------------------------------------- |
void OSD_MK_Connect( uint8_t modus ) |
{ |
uint8_t tx_interval; |
|
if( modus == MK_CONNECT ) |
{ |
SwitchToNC(); |
|
// switch off: 3d data => kompatibel mit SmartOSD???? |
//tx_interval = 0; |
//SendOutData ('c', ADDRESS_ANY, 1, &tx_interval, 1); |
//_delay_ms(25); |
|
tx_interval = 0; |
SendOutData( 'd', ADDRESS_ANY, 1, &tx_interval, 1); // switch off: debug |
|
timer = 3; while( timer > 0 ); // short delay |
} |
|
tx_interval = TXINTERVAL_OSDDATA; // switch on: sending osd-data |
SendOutData( 'o', ADDRESS_NC, 1, &tx_interval, 1); // request: OSD Data from NC every ..ms |
|
timer = 3; while( timer > 0 ); // short delay |
|
// switch on: sending bl-data |
tx_interval = TXINTERVAL_BLDATA; // 5 => 50 ms (send packet every n*10 ms) |
SendOutData( 'k', ADDRESS_ANY, 1, &tx_interval, 1); // request: BL Ctrl Status |
|
mode = 'O'; |
abo_timer = ABO_TIMEOUT; |
|
rxd_buffer_locked = FALSE; |
} |
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_MK_ShowTimeout( void ) |
{ |
if( old_PKTErrorcode != 40 ) |
{ |
MkError_Save( 40 ); // Logge: "PKT RX lost" |
old_PKTErrorcode = 40; |
} |
|
lcd_cls (); |
|
lcd_frect_round( 0, 0, 127,10, 1, R1); // Rect: Invers (Titel) |
lcdx_printp_center( 0, strGet(OSD_ERROR), MINVERS, 1,2); // "FEHLER: Datenverlust!" |
|
lcdx_printp_at(3, 1, strGet(START_LASTPOS) , MNORMAL, 0,6); // "Letzte Position" |
lcdx_printp_at(3, 2, strGet(START_LASTPOS3), MNORMAL, 0,6); // "Google Eingabe" |
|
//---- |
lcd_frect( 0, (4*7)+5, 127, 7, 1); // Rect: Invers |
lcdx_printp_at(1, 3, strGet(START_LASTPOS1), MINVERS, 0,9); // "Breitengr Längengr" |
|
writex_gpspos( 1, 4, Config.LastLatitude , MNORMAL, 0,11); // Anzeige: Breitengrad |
writex_gpspos( 12, 4, Config.LastLongitude, MNORMAL, -1,11); // Anzeige: Laengengrad |
|
lcd_rect( 0, (3*8)+8, 127, (2*8)+4, 1); // Rahmen |
|
lcd_printp_at(12, 7, strGet(ENDE) , MNORMAL); // Keyline: "Ende" |
|
set_beep ( 0, 0, BeepOff); // Falls Spannungswarnung an war Beeper aus (ist das notwendig?) |
} |
|
|
|
/*************************************************************************************************************************************** |
|
//-------------------------------------------------------------- |
// OSD_MK_UTCTime() |
// Fuer: defined MKVERSION088n || defined MKVERSION090b || defined MKVERSION090e |
// -> erstmal keine Unterstuetzung mehr... |
//-------------------------------------------------------------- |
|
//-------------------------------------------------------------- |
// OSD_MK_UTCTime() |
// |
// ALTE Funktion fuer FC < 0.90h (und dementsprechend NC < 0.30h) |
// |
// Setzt die PKT globale UTCTime mithilfe des MK. |
// |
// Foraussetzung: |
// - der NC-Modus muss aktiv sein (SwitchToNC) |
// - aktuell nur fuer osd.c |
// |
// Rueckgabe: |
// true = ok, UTCTime gespeichert |
// false = Zeit/Datum nicht gelesen |
// |
// Hack: |
// Gelesen wird die Seite 3 des NC-Display's. Dort wird Zeit |
// und Datum an den entsprechnenden Positionen via Zeichen an- |
// gezeigt. Die Zeichen werden ausgelesen und in die interne UTCTime |
// gespeichert. |
// |
// HINWEIS: |
// Ab NC > v0.30b (evtl. v0.30c) wird die NC ein neues Datenpaket |
// senden ("T") mit strukturierten Informationen zu Datum/Zeit. |
// Das wurde von Holger eingebaut. |
// Wird spaeter auch im PKT implementiert. |
//-------------------------------------------------------------- |
int OSD_MK_UTCTime( uint8_t readtime ) |
{ |
uint32_t sec; |
uint32_t min; |
uint32_t hour; |
uint16_t year; |
uint8_t month; |
uint8_t day; |
uint8_t page; |
uint8_t ok = false; |
|
|
mode = 'L'; // read: MK-Display Page |
page = 3; // anfordern von Seite 3 (der NC) |
SendOutData ('l', ADDRESS_ANY, 1, &page, 1); // request: MK-Display Page 3 |
|
rxd_buffer_locked = FALSE; |
|
timer = readtime; // fuer max. n*10 millisec versuchen Daten zu lesen |
while( timer>0 && !ok ); // lese Daten-Pakete fuer die angegebene Zeit oder gelesen |
{ |
if( rxd_buffer_locked ) |
{ |
Decode64(); |
|
#ifdef USE_OSD_SCREEN_DEBUG |
readCounterTIME++; |
#endif |
|
sec = (uint32_t)(pRxData[66+7+2] - '0') + 10 * (uint32_t)(pRxData[66+6+2] - '0'); // seconds: sec |
min = (uint32_t)(pRxData[66+4+2] - '0') + 10 * (uint32_t)(pRxData[66+3+2] - '0'); // seconds: min |
hour = (uint32_t)(pRxData[66+1+2] - '0') + 10 * (uint32_t)(pRxData[66+0+2] - '0'); // seconds: hour |
sec += (min * 60) + (hour * 3600); |
|
year = (uint16_t)(pRxData[46+9+2] - '0') + 10 * (uint16_t)(pRxData[46+8+2] - '0'); // year |
year += 100 * (uint16_t)(pRxData[46+7+2] - '0') + 1000 * (uint16_t)(pRxData[46+6+2] - '0'); // year |
|
day = (uint8_t)(pRxData[46+4+2] - '0') + 10 * (uint8_t)(pRxData[46+3+2] - '0'); // day |
|
month = (uint8_t)(pRxData[46+1+2] - '0') + 10 * (uint8_t)(pRxData[46+0+2] - '0'); // month |
|
// in der globalen UTCTime speichern (hoffentlich funkt kein timer dazwischen) |
if( year > 2000 && year < 2200 ) // plausibilitaets check |
{ |
ATOMIC_BLOCK(ATOMIC_FORCEON) |
{ |
UTCTime.seconds = sec; |
UTCTime.day = day; |
UTCTime.month = month; |
UTCTime.year = year; |
} |
} |
ok = true; |
} |
} |
|
return ok; // wenn erfolgreich gelesen dann true (kein timeout) |
} |
***************************************************************************************************************************************/ |
|
|
|
//-------------------------------------------------------------- |
// OSD_MK_UTCTime() |
// |
// NEUE Ermittlung der Zeit vom MK |
// ab NC v0.30g (bzw. NC 0.30h fuer FC 0.90h) |
// |
// TODO OG: auf neue MKVersion bzgl. Versionsprüfung anpassen! |
//-------------------------------------------------------------- |
int OSD_MK_UTCTime( uint8_t readtime ) |
{ |
DateTime_t *rx_DateTime; |
uint8_t tx_interval; |
uint8_t ok = false; |
|
mode = 'T'; // read: MK-Display Page |
tx_interval = 1; // |
SendOutData ('t', ADDRESS_NC, 1, &tx_interval, 1); // request: DateTime |
|
rxd_buffer_locked = FALSE; |
|
timer = readtime; // fuer max. n*10 millisec versuchen Daten zu lesen |
while( timer>0 && !ok ); // lese Daten-Pakete fuer die angegebene Zeit oder gelesen |
{ |
if( rxd_buffer_locked ) |
{ |
Decode64(); |
rx_DateTime = (DateTime_t *) (pRxData); |
|
#ifdef USE_OSD_SCREEN_DEBUG |
readCounterTIME++; |
#endif |
|
if( rx_DateTime->Year > 2000 && rx_DateTime->Year < 2200 ) // Plausibilitaets Check |
{ |
ATOMIC_BLOCK(ATOMIC_FORCEON) |
{ |
UTCTime.seconds = ((uint32_t)(rx_DateTime->Hour))*3600 + ((uint32_t)(rx_DateTime->Min))*60 + (uint32_t)(rx_DateTime->Sec); |
UTCTime.day = rx_DateTime->Day; |
UTCTime.month = rx_DateTime->Month; |
UTCTime.year = rx_DateTime->Year; |
} |
} |
|
ok = true; |
} |
} |
|
return ok; // wenn erfolgreich gelesen dann true (kein timeout) |
} |
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
int32_t calc_avg( int32_t avg, int32_t nvalue, int32_t count, int32_t factor) |
{ |
avg = avg + (( ( nvalue * factor) - avg) / count); |
return avg; |
} |
|
|
|
//-------------------------------------------------------------- |
// OSD_MK_GetData() |
// |
// Holt Daten der BL-Ctrl via NC. |
// |
// Die Werte der BL's 1-12 kommen in mehr oder weniger beliebiger |
// Reihenfolge an. Die Daten fuer vorhandene BL's werden oefter |
// gesendet als die von nicht vorhandenen BL's. |
// |
// Diese Funktioen liest fuer die Zeit BL_READ_TIME die BL-Daten |
// vom MK ein und ordnet diese der PKT-internen Speichstruktur zu. |
// |
// Hierbei ist nicht gewaehrleistet, dass die Daten von jedem BL |
// in einem festen Zeitrahmen ermittelt werden. Die Folge ist |
// ein 'zufaelliger' Aufbau der Anzeige der BL-Daten und auch |
// eine nicht exakt bestimmbare Refreshtime der Werte. |
// |
// Optimieren kann man ggf. die Refreshzeit aller BL-Werte durch |
// tx_intervall fuer Kommando "k" und durch BL_READ_TIME. |
// Brauchbare Startwerte sind (noch experimentell): |
// tx_interval = 5 (fuer "k") = 50 ms |
// BL_READ_TIME = 25 = 250 ms |
// |
// Wenn dieses Verhalten verbessert werden soll muss ggf. |
// die ISR() (usart.c) fuer Kommando "k" angepasst werden um |
// in einem Schwung mehrere gesendete BL-Pakete aufeinmal |
// aufzunehmen und als Paket zur Verfuegung zu stellen. |
//-------------------------------------------------------------- |
void OSD_MK_GetData( void ) |
{ |
BLData_t *rx_blData; |
uint8_t blIndex; |
uint8_t FCStatusFlags; |
uint8_t v; |
uint8_t skipBL = false; |
|
FCStatusFlags = naviData->FCStatusFlags; // save naviData->FCStatusFlags for use with BL-Data |
|
|
//###################################### |
//# ZEIT/DATUM |
//###################################### |
// lese UTC-Time vom MK |
//-------------------------------------- |
if( timer_get_tidata == 0 ) |
{ |
//-------------------------------------------------- |
// das 'T' Datenpaket der NC fuer OSD_MK_UTCTime() |
// gibt es erst ab NC v0.30g (!) |
// |
// --> Versionspruefung der NC-Firmware |
//-------------------------------------------------- |
|
v = MKVersion_Cmp( MKVersion.NCVer, 0,30,'g' ); // pruefe auf NC-Version >= "0.30g" |
|
if( v && (v >= GIVEN_VERSION) ) // wenn aktuelle NC-Version >= "0.30g"... |
{ |
if( !OSD_MK_UTCTime(20) ) |
timer_get_tidata = 50; // erfolglos: versuche es nach einer 1/2 Sekunde erneut |
else |
timer_get_tidata = TIME_GET_TIDATA; // alle 60 Sekunden refresh - den Rest uebernimmt ein Timer des PKT |
} |
} |
|
|
|
//###################################### |
//# MK-DISPLAY |
//###################################### |
// switch to: (h) |
//-------------------------------------- |
//if( timer_get_displaydata == 0 ) |
if( mkdisplayMode && timer_get_displaydata == 0 ) |
{ |
mode = 'H'; |
rxd_buffer_locked = FALSE; |
|
/* |
if( mkdisplayCmd != 0xff ) |
{ |
if( mkdisplayCmd == 0 ) mkdisplayCmd = 0xff; |
SendOutData( 'h', ADDRESS_ANY, 1, &mkdisplayCmd, 1); |
} |
*/ |
if( mkdisplayCmd == 0 ) mkdisplayCmd = 0xff; |
|
SendOutData( 'h', ADDRESS_ANY, 2, &mkdisplayCmd, 1, 0x00 ,1); // 05.04.2015 Cebra, 2.er Parameter wg NC 2.09i |
|
mkdisplayCmd = 0xff; // 0xff = aktuelle Seite |
|
timer = 20; while( (timer>0) && !rxd_buffer_locked ); // |
|
if( rxd_buffer_locked ) |
{ |
Decode64(); |
memcpy( mkdisplayData, (const void *)&rxd_buffer[3+ 0], 80 ); // sichern... |
|
#ifdef USE_OSD_SCREEN_DEBUG |
readCounterDISPLAY++; |
#endif // USE_OSD_SCREEN_DEBUG |
} |
|
timer_get_displaydata = TIME_GET_DISPLAYDATA; // n*10 ms |
skipBL = true; |
} // end: if( mkdisplayMode && timer_get_displaydata == 0 ) |
|
|
|
//###################################### |
//# BL-Daten |
//###################################### |
// switch to: 'BL Ctrl Status' (k) |
//-------------------------------------- |
if( !skipBL && timer_get_bldata == 0 ) |
{ |
mode = 'K'; // read: BL Ctrl Status |
rxd_buffer_locked = FALSE; |
|
timer = TIME_READ_BLDATA; // fuer x Zeit werden BL-Daten gelesen |
while( timer>0 ) // lese Daten-Pakete fuer die angegebene Zeit |
{ |
if( rxd_buffer_locked ) |
{ |
Decode64 (); |
rx_blData = (BLData_t *) (pRxData); |
|
// die BL-Daten kommen in beliebiger Reihenfolge an |
// Hier werden sie entsprechend ihres Index gesichert |
blIndex = rx_blData->Index; |
if( blIndex >= 0 && blIndex < OSD_MAX_MOTORS ) |
{ |
memcpy( &blData[blIndex], rx_blData, sizeof(BLData_t)); // sichern... |
|
#ifdef USE_OSD_SCREEN_DEBUG |
readCounterBL[blIndex]++; |
#endif // USE_OSD_SCREEN_DEBUG |
|
// Statistiken |
if( (blData[blIndex].Status & 0xf0) && (FCStatusFlags & FC_STATUS_MOTOR_RUN) ) // nur wenn BL/Motor vorhanden und Motoren laufen |
{ |
// BL Statistik: Anzahl empf. Datenpakete (fuer Mittelwert) |
Config.OSD_Statistic.BL[blIndex].count++; |
|
// int32_t calc_avg( int32_t avg, int32_t value, int32_t count, int32_t factor) |
Config.OSD_Statistic.BL[blIndex].avg_Current = (uint16_t) calc_avg( (int32_t)Config.OSD_Statistic.BL[blIndex].avg_Current, |
(int32_t)blData[blIndex].Current, |
(int32_t)Config.OSD_Statistic.BL[blIndex].count, |
100); |
|
// ALT |
// BL Statistik: Mittelwert: Strom (*100 um Rundungsfehler zu reduzieren) |
//avg = (int32_t)Config.OSD_Statistic.BL[blIndex].avg_Current; |
//avg = avg + (( ( (int32_t)blData[blIndex].Current * 100) - avg) / (int32_t)Config.OSD_Statistic.BL[blIndex].count); |
//Config.OSD_Statistic.BL[blIndex].avg_Current = (uint16_t)avg; |
|
// BL Statistik: Max: Strom |
if( blData[blIndex].Current > Config.OSD_Statistic.BL[blIndex].max_Current) Config.OSD_Statistic.BL[blIndex].max_Current = blData[blIndex].Current; |
|
// BL Statistik: Max: Temperatur |
if( blData[blIndex].Temperature > Config.OSD_Statistic.BL[blIndex].max_Temp) Config.OSD_Statistic.BL[blIndex].max_Temp = blData[blIndex].Temperature; |
if( blIndex+1 > Config.OSD_Statistic.BL_Count ) Config.OSD_Statistic.BL_Count = blIndex+1; |
} |
} |
rxd_buffer_locked = FALSE; |
} |
} |
timer_get_bldata = TIME_GET_BLDATA; // n*10 ms |
} // end: if( timer_get_bldata == 0 ) |
|
|
|
//-------------------------------------- |
// back to: OSD-Data |
//-------------------------------------- |
mode = 'O'; // read: OSD-Data |
rxd_buffer_locked = FALSE; // ready to receive new data |
timer_mk_timeout = MK_TIMEOUT; // reset osd MK_TIMEOUT timer |
} |
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void variobeep(int16_t vario) |
{ |
#ifdef USE_SOUND |
{ //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 |
#endif |
} |
|
|
//-------------------------------------------------------------- |
// 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 if( naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN ) |
{ |
// MK-Unterspannungs-Beep nur wenn Motoren laufen |
set_beep ( 1000, 0x0020, BeepSevere); |
} |
} |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void calc_heading_home(void) |
{ |
int16_t degree; |
|
//--------------------------------------- |
// warum modulo 360: |
// |
// die NC kann unter gewissen Umstaenden Winkel > 360 Grad |
// senden -> fragt H&I warum |
//--------------------------------------- |
degree = ((naviData->CompassHeading % 360) - (naviData->HomePositionDeviation.Bearing % 360)); |
|
if( degree < 0 ) |
heading_home = (int16_t)(360 + degree); |
else |
heading_home = (int16_t)degree; |
} |
|
|
//-------------------------------------------------------------- |
// 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, int8_t xoffs, int8_t yoffs) |
{ |
|
uint8_t front = 19 + (heading / 22); |
for (uint8_t i = 0; i < 9; i++) |
lcdx_putc (x++, y, pgm_read_byte(&rose[front - 4 + i]), MNORMAL, xoffs,yoffs); |
} |
|
|
//-------------------------------------------------------------- |
// 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); |
} |
|
|
//----------------------------------------------------------- |
//----------------------------------------------------------- |
void writex_altimeter( uint8_t x, uint8_t y, s32 Altimeter, uint8_t mode, int8_t xoffs, int8_t yoffs ) |
{ |
if (Altimeter > (300 / AltimeterAdjust) || Altimeter < (-300 / AltimeterAdjust)) // above 10m only write full meters |
writex_ndigit_number_s ( x, y, (Altimeter / (30 / AltimeterAdjust)), 4, 0, mode, xoffs,yoffs); |
else // up to 10m write meters.dm |
writex_ndigit_number_s_10th( x, y, (Altimeter / (3 / AltimeterAdjust)), 3, 0, mode, xoffs,yoffs); |
} |
|
|
|
//----------------------------------------------------------- |
//-------------------------------------------------------------- |
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 lcdx_o_circle( uint8_t x, uint8_t y, int8_t width, uint8_t mode) |
{ |
int8_t radius = width / 2; |
|
// 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, y, 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 lcdx_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); |
} |
|
|
|
//-------------------------------------------------------------- |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
void draw_icon_mk( uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
|
lcd_line( x+5, y+0, x+0, y+5, 1); // Dach oben Links |
lcd_line( x+5, y+0, x+10, y+5, 1); // Dach oben Rechts |
|
lcd_line( x+5, y+10, x+0, y+5, 1); // Dach unten Links |
lcd_line( x+5, y+10, x+10, y+5, 1); // Dach unten Rechts |
|
lcd_line( x+4, y+5, x+6, y+5, 1); // Innenkreuz Horizontal |
lcd_line( x+5, y+4, x+5, y+6, 1); // Innenkreuz Vertikal |
} |
|
|
|
//-------------------------------------------------------------- |
// Variante: rund |
// |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
void draw_icon_target_round( uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
|
lcd_ellipse( x+5, y+5, 5+1, 5, 1); // Aussenkreis |
|
//lcd_line( x+2, y+5, x+8, y+5, 1); // Innenkreuz Horizontal (laenger) |
lcd_line( x+3, y+5, x+7, y+5, 1); // Innenkreuz Horizontal (kuerzer) |
|
lcd_line( x+5, y+3, x+5, y+7, 1); // Innenkreuz Vertikal |
} |
|
|
|
//-------------------------------------------------------------- |
// Variante: eckig |
// |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
void draw_icon_target_diamond( uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
|
lcd_line( x+5, y+0, x+0, y+5, 1); // Dach oben Links |
lcd_line( x+5, y+0, x+10, y+5, 1); // Dach oben Rechts |
|
lcd_line( x+5, y+10, x+0, y+5, 1); // Dach unten Links |
lcd_line( x+5, y+10, x+10, y+5, 1); // Dach unten Rechts |
|
lcd_line( x+4, y+5, x+6, y+5, 1); // Innenkreuz Horizontal |
lcd_line( x+5, y+4, x+5, y+6, 1); // Innenkreuz Vertikal |
} |
|
|
|
//-------------------------------------------------------------- |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
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 |
|
} |
|
|
|
//-------------------------------------------------------------- |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
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 |
} |
|
|
|
//-------------------------------------------------------------- |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
void draw_icon_satmini( uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
|
//lcd_line( x+3, y+3, x+0, y+6, 1); // Strahl Links |
|
lcd_line( x+2, y+0, x+4, y+0, 1); // |
lcd_line( x+0, y+1, x+6, y+1, 1); // |
lcd_line( x+2, y+2, x+4, y+2, 1); // |
lcd_plot( x+3, y+1, 0); // |
|
lcd_line( x+3, y+3, x+1, y+5, 1); // Strahl Links |
lcd_line( x+3, y+3, x+5, y+5, 1); // Strahl Rechts |
lcd_line( x+0, y+6, x+6, y+6, 1); // Strahl Unten |
} |
|
|
|
//-------------------------------------------------------------- |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
void draw_icon_satmini2( uint8_t x, uint8_t y) |
{ |
//lcd_plot( x+0, y+0, 1); // Referenz 0,0 |
|
//lcd_line( x+3, y+3, x+0, y+6, 1); // Strahl Links |
|
lcd_line( x+2, y-1, x+4, y-1, 1); // |
//lcd_line( x+2, y+0, x+4, y+0, 1); // |
lcd_line( x+0, y+0, x+6, y+0, 1); // |
lcd_line( x+0, y+1, x+6, y+1, 1); // |
lcd_line( x+2, y+2, x+4, y+2, 1); // |
lcd_plot( x+3, y+0, 0); // |
lcd_plot( x+3, y+1, 0); // |
|
lcd_line( x+3, y+3, x+1, y+5, 1); // Strahl Links |
lcd_line( x+3, y+3, x+5, y+5, 1); // Strahl Rechts |
lcd_line( x+0, y+6, x+6, y+6, 1); // Strahl Unten |
} |
|
|
//-------------------------------------------------------------- |
// PARAMETER: |
// x,y : in Pixel |
//-------------------------------------------------------------- |
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 |
} |
|
|
|
//-------------------------------------------------------------- |
// 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); |
} |
|
|
|
|
//############################################################## |
//# spezielle Beeps |
//############################################################## |
|
//-------------------------------------------------------------- |
// Beep_Waypoint() |
// |
// Beep bei Waypoint Wechsel und wenn die WP-Liste abgearbeitet |
// ist |
//-------------------------------------------------------------- |
void Beep_Waypoint( void ) |
{ |
//----------------- |
// BEEP: WP erreicht |
//----------------- |
if( naviData->WaypointIndex > WP_old ) |
{ |
set_beep( 30, 0xffff, BeepNormal ); // kurzer Bestaetigungs-Beep |
} |
|
if( (naviData->WaypointIndex == naviData->WaypointNumber) |
&& (naviData->NCFlags & NC_FLAG_TARGET_REACHED) |
&& (!WP_last) |
) |
{ |
set_beep( 400, 0xffff, BeepNormal ); // langer Bestaetigungs-Beep |
WP_last = true; |
} |
|
if( naviData->WaypointIndex != WP_old ) |
{ |
WP_old = naviData->WaypointIndex; |
} |
|
if( (naviData->WaypointIndex != naviData->WaypointNumber) // wenn aktueller WP != WP-Anzahl -> WP_last abschalten |
|| !(naviData->NCFlags & NC_FLAG_TARGET_REACHED) // wenn kein TR mehr an ist -> WP_last abschalten |
) |
{ |
WP_last = false; |
} |
|
|
// alter Code zur Orientierung |
//if( OldWP != naviData->WaypointIndex ) |
//{ |
// OldWP = naviData->WaypointIndex; |
// NextWP = true; |
//} |
// |
//if( (NextWP==true) && (naviData->NCFlags & NC_FLAG_TARGET_REACHED) ) |
//{ |
// set_beep( 25, 0xffff, BeepNormal ); // kurzer Bestaetigungs-Beep |
// NextWP = false; |
//} |
} |
|
|
|
//############################################################## |
//# 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 && yoffs<=0 ) { y = 0; h = 7; } |
if( xC==0 && xoffs<=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); |
} |
|
|
//-------------------------------------------------------------- |
// 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 ) |
{ |
|
#ifdef USE_FONT_BIG |
|
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; |
} |
|
#else |
|
if( nStyle == 2 ) |
{ |
lcd_printp_at (x, y, PSTR("Höhe"), MNORMAL); |
x += 4; |
} |
else |
{ |
lcd_putc (x+5, y, 0x09, 0); // Hoehensymbol |
} |
|
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); |
|
#endif |
|
} |
|
|
//-------------------------------------------------------------- |
// 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); |
|
if( Config.OSD_ShowCellU ) |
{ |
// kalk. Einzelzellen Spannungsanzeige |
writex_ndigit_number_u_100th( x, y, (uint16_t)((naviData->UBat*10)/cells), 3, 0, drawmode, xoffs,yoffs); |
lcdx_printp_at( x+4, y, PSTR("v"), drawmode, xoffs+1,yoffs); // Einheit (Einzelzellenanzeige ca., berechnet) |
} |
else |
{ |
// Gesamtspannungsanzeige |
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 (Gesamtspannung) |
} |
|
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 ) |
{ |
#ifdef USE_FONT_BIG |
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); |
} |
#else |
drawmode = (naviData->UBat < BattLowVoltageWarning ? 2 : 0); // Normal-Schrift |
|
if( nStyle == 2) |
x += 3; |
write_ndigit_number_u_10th (x, y, naviData->UBat, 3, 0, drawmode); |
lcd_printp_at (x+4, y, PSTR("V"), drawmode); |
#endif |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Element_Battery_Bar( x, y, length, width, orientation) |
// |
// neue Variante (OG 06/2013) |
// |
// Parameter: |
// length : Gesamtlaenge des Bar's |
// width : Breite in Pixel (fest) |
// orientation: ORIENTATION_V - Vertikal (x,y oberer,linker Punkt) |
// ORIENTATION_H |
//-------------------------------------------------------------- |
void OSD_Element_Battery_Bar( uint8_t x, uint8_t y, uint8_t length, uint8_t width, uint8_t orientation) |
{ |
uint8_t bat_umax; |
uint8_t bat_umin; |
uint8_t bat_uact; |
int8_t bat_p; |
|
// die Min/Max Spannungswerte sind jetzt erstmal fest vorgegeben bzw. berechnet, eine individuelle |
// Anpassung waere moeglich aber wenn besser ist es, wenn der User das nicht machen muesste... |
bat_umax = cells * 42; |
//bat_umin = cells * 32; |
bat_umin = cells * 34; // 3.4 Volt pro Zelle Minimum |
|
bat_uact = naviData->UBat; |
|
bat_p = length * (bat_uact-bat_umin) / (bat_umax-bat_umin); |
|
if( bat_p < 0 ) bat_p = 0; |
if( bat_p > length ) bat_p = length; |
|
if( width == 1 ) width = 0; // eine kleine Eigenart von frect um es zu ueberreden eine Linie zu zeichnen |
|
if( orientation == ORIENTATION_V ) |
{ |
lcd_frect( x, y , width, length-bat_p, 0); // clear: vertical |
lcd_frect( x, y+length-bat_p, width, bat_p, 1); // draw: vertical |
} |
else |
{ |
lcd_frect( x+bat_p, y, length-bat_p, width, 0); // clear: |
lcd_frect( x , y, bat_p , width, 1); // draw: |
} |
} |
|
|
//-------------------------------------------------------------- |
// 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_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)%360, 3, 0,MNORMAL); |
x += 3; |
break; |
|
case 2 : |
#ifdef USE_FONT_BIG |
write_ndigit_number_u (x, y, (naviData->CompassHeading)%360, 3, 0,MBIG); |
#else |
write_ndigit_number_u (x+5, y, (naviData->CompassHeading)%360, 3, 0,MNORMAL); |
#endif |
|
x += 8; |
break; |
} |
lcd_putc( x, y, 0x1E, MNORMAL); // degree symbol |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_CompassDirection( uint8_t x, uint8_t y, int8_t xoffs, int8_t yoffs ) |
{ |
lcdx_printp_at (x, y, (const char *) (pgm_read_word ( &(directions_p[heading_conv((naviData->CompassHeading)%360)]))), MNORMAL, xoffs,yoffs); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void OSD_Element_CompassRose( uint8_t x, uint8_t y ) |
{ |
draw_compass (x, y, (naviData->CompassHeading)%360, 0,0); |
} |
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
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 ) |
{ |
calc_heading_home(); |
|
lcd_o_circle( x, y, breite, 1, xoffs,yoffs); |
lcd_o_circ_line( x, y, breite, (old_hh + 180), rOffset, 0, xoffs,yoffs); |
lcd_o_circ_line( x, y, breite, (heading_home + 180), rOffset, 1, xoffs,yoffs); |
|
old_hh = heading_home; |
} |
|
|
|
//-------------------------------------------------------------- |
// NEU! 22.04.2014 OG |
// soll das alte OSD_Element_HomeCircle() komplett ersetzen wenn |
// die alten OSD-Screens endgueltig rausfliegen |
//-------------------------------------------------------------- |
void OSD_Element_HomeCircleX( uint8_t px, uint8_t py, uint8_t rx, int8_t ry ) |
{ |
calc_heading_home(); |
lcd_ellipse_line( px, py, rx, ry, (old_hh + 180), 0); |
lcd_ellipse_line( px, py, rx, ry, (heading_home + 180), 1); |
lcd_ellipse( px, py, rx, ry, 1); |
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 |
|
lcd_fcircle (x * 6 + 5, y * 8 + 3, Config.OSD_LEDform, lOn); |
lcd_circle (x * 6 + 5, y * 8 + 3, 3, 1); |
} |
|
|
//-------------------------------------------------------------- |
// 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_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_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" |
// |
// OSDScreenRefresh: 0 = update values |
// 1 = redraw labels and update values |
//-------------------------------------------------------------- |
void OSD_Screen_General( void ) |
{ |
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == 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( 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); |
lcdx_putc( 20, 1, SYMBOL_SMALLDEGREE, MNORMAL, 1,1); |
lcdx_printp_at( 12, 2, PSTR(" I:") , MNORMAL, 0,2); |
lcdx_putc( 20, 2, '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_putc( 20, 4, 'm', MNORMAL, 2,0); |
lcdx_putc( 20, 5, SYMBOL_SMALLDEGREE, MNORMAL, 1,1); |
|
//----------------------------------------- |
// unterste Zeile |
//----------------------------------------- |
draw_symbol_rc( 20, 7); // RC-transmitter |
//lcdx_putc( 20, 7, SYMBOL_RCQUALITY, MNORMAL, 2,0); |
} |
|
//----------------- |
// Batt Level (Graph) |
//----------------- |
OSD_Element_Battery_Bar( 2, 8, 11, 2, ORIENTATION_V); |
|
//----------------- |
// 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 |
//----------------- |
writex_altimeter( 16, 0, naviData->Altimeter, MNORMAL, 0,0 ); |
/* |
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)%360, 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 USE_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 |
} |
|
|
|
//-------------------------------------------------------------- |
// OSD-Screen "Navigation" |
// |
// OSDScreenRefresh: 0 = update values |
// 1 = redraw labels and update values |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_NAVIGATION |
void OSD_Screen_Navigation( void ) |
{ |
int8_t xoffs, yoffs; |
int16_t degree; |
uint8_t minus; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
|
lcd_line( (6*6-3), 0, (6*6-3), 11, 1); // Linie Vertikal links |
lcd_line( (15*6+5), 0, (15*6+5), 11, 1); // Linie Vertikal rechts |
lcd_line( 0, 12, 127, 12, 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: Batt Level Bar |
//----------------- |
//OSD_Element_Battery_Bar( x, y, length, width, orientation) |
OSD_Element_Battery_Bar( 0, 9, 30, 1, ORIENTATION_H); |
|
//----------------- |
// Oben: Kompass Rose |
//----------------- |
draw_compass( 6, 0, (naviData->CompassHeading)%360, 2,0); |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
writex_time(16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
//----------------- |
// Hoehe |
//----------------- |
xoffs = 0; |
yoffs = 3; |
writex_altimeter( 0, 3, naviData->Altimeter, MNORMAL, 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 |
//----------------- |
|
//void OSD_Element_HomeCircleX( uint8_t px, uint8_t py, uint8_t rx, int8_t ry ) |
|
xoffs = 2; |
yoffs = 3; |
|
//OSD_Element_HomeCircleX( 64, 38, 25, 22 ); // entspricht dem ehemaligem Huellkreis |
OSD_Element_HomeCircleX( 64, 38, 26, 22 ); // leicht erweiterter Huellkreis |
|
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 |
|
degree = (int16_t)heading_home; |
minus = false; |
if( degree >= 180 ) degree = 360 - degree; |
else minus = true; |
|
writex_ndigit_number_u( 9, 4, degree, 3, 0,MNORMAL, xoffs+1,yoffs); // Degree (Winkel) |
|
if( minus && degree != 0 ) |
lcd_line( (9*6)-2+xoffs, (4*8)+3+yoffs, (9*6)-1+xoffs, (4*8)+3+yoffs, 1); |
|
|
//----------------- |
// Variometer |
//----------------- |
// OG: Variometer wird erstmal nicht angezeigt weil es den Screen zu voll macht |
// wenn doch muessen erst grafische Anpassungen an den Variometer-Code gemacht |
// werden |
//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 USE_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 |
} |
#endif // USE_OSD_SCREEN_NAVIGATION |
|
|
|
|
//-------------------------------------------------------------- |
// OSD-Screen "OSD_Screen_Waypoints_OLD" |
// |
// alte, alternative Variante - wenn sich die neue Variante |
// durchsetzt kann das hier geloescht werden |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_WAYPOINTS |
/* |
void OSD_Screen_Waypoints_OLD( void ) |
{ |
int8_t xoffs, yoffs; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
|
lcd_line( (6*6-3), 0, (6*6-3), 11, 1); // Linie Vertikal links |
lcd_line( (15*6+5), 0, (15*6+5), 11, 1); // Linie Vertikal rechts |
//lcd_line( 0, 12, 127, 12, 1); // Linie Horizontal |
|
lcd_rect_round( 0, 12, 127, 63-19+7, 1, R2); // Rahmen |
|
lcd_line( 0, 12+25, 127, 12+25, 1); // Trennlinie in der Mitte |
|
draw_icon_home( 7, 18); |
draw_icon_target_round( 7, 45); |
//draw_icon_target_diamond( 7, 45); // Alternative fuer draw_icon_target_round() |
} |
|
|
//----------------- |
// Oben: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Oben: Batt Level Bar |
//----------------- |
//OSD_Element_Battery_Bar( x, y, length, width, orientation) |
OSD_Element_Battery_Bar( 0, 9, 30, 1, ORIENTATION_H); |
|
//----------------- |
// Oben: Kompass Rose |
//----------------- |
//draw_compass( 6, 0, (naviData->CompassHeading)%360, 2,0); |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
writex_time(16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
//----------------- |
// Home: Hoehe |
//----------------- |
xoffs = 6; |
yoffs = 0; |
writex_altimeter( 7, 2, naviData->Altimeter, MNORMAL, xoffs,yoffs ); |
lcdx_printp_at( 3, 2, PSTR("Al:"), MNORMAL, xoffs+2,yoffs); |
|
//----------------- |
// Home: Steigen / Sinken |
//----------------- |
OSD_Element_UpDown( 13, 2, -2,yoffs); |
|
//----------------- |
// Home: Distance |
//----------------- |
yoffs = 2; |
lcdx_printp_at( 3, 3, PSTR("Ho:"), MNORMAL, xoffs+2,yoffs); |
writex_ndigit_number_u( 7, 3, naviData->HomePositionDeviation.Distance / 10, 4, 0,MNORMAL, xoffs,yoffs); |
lcdx_printp_at(11, 3, PSTR("m"), MNORMAL, xoffs+4,yoffs); // Home |
|
//----------------- |
// Home: Circle |
//----------------- |
xoffs = 2; |
yoffs = 3; |
|
//OSD_Element_HomeCircleX( px, py, rx, ry ) |
//OSD_Element_HomeCircleX( 64, 38, 26, 22 ); // leicht erweiterter Huellkreis |
OSD_Element_HomeCircleX( 112, 24, 10, 8 ); // leicht erweiterter Huellkreis |
|
//lcd_frect( 112-1, 33, 2, 1, 1); // bottom mini rect |
lcd_frect( 112-1, 33, 2, 0, 1); // bottom mini rect |
lcd_frect( 112-0, 33, 0, 1, 1); // bottom mini rect |
|
|
//----------------- |
// WP: Waypoint-Index und Anzahl der Waypoint's |
//----------------- |
xoffs = 6; |
yoffs = 2; |
lcdx_printp_at( 3, 5, PSTR("WP:"), MNORMAL, xoffs+2,yoffs); |
|
uint8_t wpindex = naviData->WaypointIndex; |
if( naviData->WaypointNumber==0 ) wpindex = 0; |
|
lcdx_printf_at_P( 7, 5, MNORMAL, xoffs,yoffs, PSTR("%2d/%2d"), wpindex, naviData->WaypointNumber ); |
|
|
//----------------- |
// Sat Anzahl |
//----------------- |
writex_ndigit_number_u( 17, 5, naviData->SatsInUse, 2, 0,MNORMAL, 0,2); |
draw_icon_satmini( 117, 42); |
|
|
//----------------- |
// WP: Distance |
//----------------- |
yoffs = 4; |
lcdx_printp_at( 3, 6, PSTR("Di:"), MNORMAL, xoffs+2,yoffs); |
writex_ndigit_number_u( 7, 6, naviData->TargetPositionDeviation.Distance / 10, 4, 0,MNORMAL, xoffs,yoffs); |
lcdx_printp_at( 11, 6, PSTR("m"), MNORMAL, xoffs+4,yoffs); // |
|
//----------------- |
// WP: Hoehe |
// Anmerkung OG: macht nicht so wirklich Sinn denke ich |
//----------------- |
//writex_ndigit_number_u( 14, 6, naviData->TargetPosition.Altitude / 1000, 4, 0,MNORMAL, xoffs,yoffs); |
//lcdx_printp_at( 18, 6, PSTR("m"), MNORMAL, xoffs+4,yoffs); // |
|
|
//----------------- |
// Oben: Flags |
//----------------- |
// Variante 1: PH, CH, CF |
//OSD_Element_Flag( 7, 0, OSD_FLAG_PH, -2,1); // Position Hold |
//OSD_Element_Flag( 9, 0, OSD_FLAG_CH, 5,1); // Coming Home |
//OSD_Element_Flag( 12, 0, OSD_FLAG_CF, 6,1); // Carefree |
|
// Variante 2: CF, CH, TR |
OSD_Element_Flag( 7, 0, OSD_FLAG_CF, -2,1); // Carefree |
OSD_Element_Flag( 9, 0, OSD_FLAG_CH, 5,1); // Coming Home |
OSD_Element_Flag( 12, 0, OSD_FLAG_TR, 6,1); // Target Reached |
|
|
// Variante: TR neben Waypoint-Anzahl |
//OSD_Element_Flag( 13, 5, OSD_FLAG_TR, 6,2); // Target Reached |
|
|
//----------------- |
// ggf. BEEP wenn WP erreicht |
//----------------- |
Beep_Waypoint(); |
} |
*/ |
#endif // USE_OSD_SCREEN_WAYPOINTS |
|
|
|
//-------------------------------------------------------------- |
// OSD-Screen "Waypoints" |
// |
// aktuelle Variante! |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_WAYPOINTS |
void OSD_Screen_Waypoints( void ) |
{ |
int8_t xoffs, yoffs; |
uint8_t v; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
|
lcd_line( (6*6-3), 0, (6*6-3), 11, 1); // Linie Vertikal links |
lcd_line( (15*6+5), 0, (15*6+5), 11, 1); // Linie Vertikal rechts |
//lcd_line( 0, 12, 127, 12, 1); // Linie Horizontal |
|
lcd_rect_round( 0, 12, 127, 63-19+7, 1, R2); // Rahmen |
|
lcd_line( 0, 12+25, (15*6+5), 12+25, 1); // Trennlinie in der Mitte |
lcd_line( (15*6+5), 12+25, (15*6+5), 63, 1); // Linie Vertikal rechts, unten |
lcd_plot ((15*6+5), 12+25, 0); |
|
draw_icon_home( 7, 18); |
draw_icon_target_round( 7, 45); |
//draw_icon_target_diamond( 7, 45); // Alternative fuer draw_icon_target_round() |
} |
|
|
//----------------- |
// Oben,Links: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Oben,Links: Batt Level Bar |
//----------------- |
//OSD_Element_Battery_Bar( x, y, length, width, orientation) |
OSD_Element_Battery_Bar( 0, 9, 30, 1, ORIENTATION_H); |
|
//----------------- |
// Oben,Rechts: Flugzeit |
//----------------- |
writex_time(16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
//----------------- |
// Oben,Mitte: Flags |
//----------------- |
// Variante 1: PH, CH, CF |
//OSD_Element_Flag( 7, 0, OSD_FLAG_PH, -2,1); // Position Hold |
//OSD_Element_Flag( 9, 0, OSD_FLAG_CH, 5,1); // Coming Home |
//OSD_Element_Flag( 12, 0, OSD_FLAG_CF, 6,1); // Carefree |
|
// Variante 2: CF, CH, TR |
OSD_Element_Flag( 7, 0, OSD_FLAG_CF, -2,1); // Carefree |
OSD_Element_Flag( 9, 0, OSD_FLAG_CH, 5,1); // Coming Home |
OSD_Element_Flag( 12, 0, OSD_FLAG_TR, 6,1); // Target Reached |
|
|
|
//----------------- |
// Home: Hoehe |
//----------------- |
xoffs = 5; |
yoffs = 0; |
writex_altimeter( 7, 2, naviData->Altimeter, MNORMAL, xoffs,yoffs ); |
lcdx_printp_at( 3, 2, PSTR("Al:"), MNORMAL, xoffs+3,yoffs); |
|
//----------------- |
// Home: Steigen / Sinken |
//----------------- |
OSD_Element_UpDown( 13, 2, -3,yoffs); |
|
//----------------- |
// Home: Distance |
//----------------- |
yoffs = 2; |
lcdx_printp_at( 3, 3, PSTR("Ho:"), MNORMAL, xoffs+3,yoffs); |
writex_ndigit_number_u( 7, 3, naviData->HomePositionDeviation.Distance / 10, 4, 0,MNORMAL, xoffs,yoffs); |
lcdx_printp_at(11, 3, PSTR("m"), MNORMAL, xoffs+4,yoffs); // Home |
|
//----------------- |
// Home: Circle |
//----------------- |
// orginal |
//OSD_Element_HomeCircleX( 110, 25, 11, 9 ); // leicht erweiterter Huellkreis |
//lcd_frect( 112-3, 35, 2, 1, 1); // bottom mini rect |
|
// 1 pixel weiter links |
OSD_Element_HomeCircleX( 109, 25, 11, 9 ); // leicht erweiterter Huellkreis |
lcd_frect( 112-4, 35, 2, 1, 1); // bottom mini rect |
|
// etwas groesser |
//OSD_Element_HomeCircleX( 109, 26, 12, 10 ); // leicht erweiterter Huellkreis |
//lcd_frect( 112-4, 37, 2, 1, 1); // bottom mini rect |
|
//----------------- |
// Home: Sat Anzahl |
//----------------- |
//yoffs = -2; // alternativ |
yoffs = 0; |
//naviData->SatsInUse = 10; |
writex_ndigit_number_u( 17, 5, naviData->SatsInUse, 2, 0,MNORMAL, -1,2+yoffs); |
draw_icon_satmini( 115, 42+yoffs); |
|
|
|
//----------------- |
// WP: Waypoint-Index und Anzahl der Waypoint's |
//----------------- |
xoffs = 5; |
yoffs = 2; |
lcdx_printp_at( 3, 5, PSTR("WP:"), MNORMAL, xoffs+3,yoffs); |
|
v = naviData->WaypointIndex; |
if( naviData->WaypointNumber==0 ) v = 0; |
|
lcdx_printf_at_P( 7, 5, MNORMAL, xoffs,yoffs, PSTR("%2d/%2d"), v, naviData->WaypointNumber ); |
|
|
//----------------- |
// WP: Countdown Target-Holdtime |
//----------------- |
xoffs = 6; |
yoffs = 2; |
|
v = naviData->TargetHoldTime; |
if( v > 0 ) |
{ |
lcdx_printf_at_P( 12, 5, MINVERS, xoffs+2,yoffs, PSTR("%2d"), v ); |
lcd_line( (12*6)+xoffs+2, (5*8)+yoffs-1, (12*6)+xoffs+2+11, (5*8)+yoffs-1, 1); |
lcd_line( (12*6)+xoffs+1, (5*8)+yoffs-1, (12*6)+xoffs+1, (5*8)+yoffs+7, 1); |
} |
else |
{ |
lcd_frect( (12*6)+xoffs+1, (5*8)+yoffs-1, (2*8)-3, 8, 0); |
} |
|
|
//----------------- |
// WP: Distance |
//----------------- |
xoffs = 5; |
yoffs = 4; |
lcdx_printp_at( 3, 6, PSTR("Di:"), MNORMAL, xoffs+3,yoffs); |
writex_ndigit_number_u( 7, 6, naviData->TargetPositionDeviation.Distance / 10, 4, 0,MNORMAL, xoffs,yoffs); |
lcdx_printp_at( 11, 6, PSTR("m"), MNORMAL, xoffs+4,yoffs); // |
|
//----------------- |
// WP: Hoehe |
// Anmerkung OG: macht nicht so wirklich Sinn denke ich |
//----------------- |
//writex_ndigit_number_u( 14, 6, naviData->TargetPosition.Altitude / 1000, 4, 0,MNORMAL, xoffs,yoffs); |
//lcdx_printp_at( 18, 6, PSTR("m"), MNORMAL, xoffs+4,yoffs); // |
|
|
|
|
//----------------- |
// ggf. BEEP wenn WP erreicht |
//----------------- |
Beep_Waypoint(); |
} |
#endif // USE_OSD_SCREEN_WAYPOINTS |
|
|
|
//-------------------------------------------------------------- |
// OSD-Screen "User GPS" |
// |
// OSDScreenRefresh: OSD_SCREEN_REFESH = update values |
// OSD_SCREEN_REDRAW = redraw labels and update values |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_USERGPS |
void OSD_Screen_UserGPS( void ) |
{ |
uint8_t y, i; |
int8_t yoffs; |
uint8_t show_gps_altitude = 0; // 1=GPS-Höhe anzeigen; 0=barymetrische Höhe anzeigen |
|
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == 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 oben, links |
lcd_line( (15*6+3), 0, (15*6+3), 9, 1); // Linie vertikal oben, rechts |
lcd_rect_round( 0, 9, 127, 63-9, 1, R2); // Rahmen |
lcdx_printp_at( 6, 0, PSTR("UGPS"), MNORMAL, 2,0); |
} |
|
|
//----------------- |
// Oben: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Oben: Sat Ok |
//----------------- |
OSD_Element_Flag( 12, 0, OSD_FLAG_S0, 5,0); // GPS-Sat not ok (GPS NOT ok) |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
writex_time( 16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
//----------------- |
// die letzen 3 User-GPS Daten anzeigen |
//----------------- |
yoffs = -4; |
for(i=0; i<3; i++) |
{ |
y = (i*2)+2; |
lcd_frect( 0, (y*8)+yoffs-1, 127, 7, 1); // inverser Hintergrund |
|
writex_ndigit_number_u( 0, y+0, (i+1), 1, 0 , MINVERS, 4,yoffs); // Index |
writex_datetime_time( 4, y+0, Config.GPS_User[i].timestamp, MINVERS, 0,yoffs); |
|
//writex_time( 3, y+0, GPS_User[i].time_pkt, MINVERS, 0,yoffs); |
//lcdx_printp_at( 12, y+0, PSTR("Alt:") , MINVERS, 0,yoffs); |
lcdx_printp_at( 20, y+0, PSTR("m") , MINVERS, 0,yoffs); |
|
if( show_gps_altitude ) // GPS-Hoehe oder barymetrische Hoehe? |
{ |
// GPS Hoehe |
//lcdx_printp_at( 10, y+0, PSTR("G"), MINVERS, 2,yoffs); |
//lcd_frect( (12*6)-4, (y*8)+3+yoffs, 1, 1, 0); |
writex_ndigit_number_s( 16, y+0, Config.GPS_User[i].GPSData.Altitude/1000, 4, 0, MINVERS, 0,yoffs); // GPS Hoehe in Meter |
} |
else |
{ |
// barymetrische Hoehe |
//lcdx_printp_at( 10, y+0, PSTR("B"), MINVERS, 2,yoffs); |
//lcd_frect( (12*6)-4, (y*8)+3+yoffs, 1, 1, 0); |
writex_altimeter( 16, y+0, Config.GPS_User[i].Altimeter, MINVERS, 0,yoffs ); |
} |
|
lcd_line( 1, (y*8)+yoffs+7, 125, (y*8)+yoffs+7, 0); // clear: Invers unterste Linie |
|
writex_gpspos( 1, y+1, Config.GPS_User[i].GPSData.Latitude , MNORMAL, 0,yoffs); // GPS Lat |
writex_gpspos( 12, y+1, Config.GPS_User[i].GPSData.Longitude, MNORMAL, 0,yoffs); // GPS Long |
//writex_gpspos( 1, y+1, GPS_User[i].GPSData.Latitude + 12867000, MNORMAL, 0,yoffs); // DUMMY DATEN! DEMO! |
//writex_gpspos( 12, y+1, GPS_User[i].GPSData.Longitude+ 8568000, MNORMAL, 0,yoffs); // DUMMY DATEN! DEMO! |
|
yoffs++; |
} |
} |
#endif // USE_OSD_SCREEN_USERGPS |
|
|
|
//-------------------------------------------------------------- |
// OSD-Screen "Status" |
// |
// OSDScreenRefresh: 0 = update values |
// 1 = redraw labels and update values |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_MKSTATUS |
void OSD_Screen_MKStatus( void ) |
{ |
int8_t xoffs, yoffs; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == 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 oben, links |
lcd_line( (15*6+3), 0, (15*6+3), 9, 1); // Linie vertikal oben, rechts |
lcd_rect_round( 0, 10, 127, 63-10, 1, R2); // Rahmen |
|
lcdx_printp_at( 12,0 , PSTR("mAh"), MNORMAL, -1,0); // "mAh" (entnommene Kapazität) |
} |
|
|
//----------------- |
// 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 |
|
//----------------- |
// entnommene Kapazitaet (mAh) |
//----------------- |
drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL); |
//writex_ndigit_number_u( 7, 0, naviData->UsedCapacity * 10, 5, 0, drawmode, -3,0); // DEBUG |
writex_ndigit_number_u( 7, 0, naviData->UsedCapacity, 5, 0, drawmode, -3,0); |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
writex_time( 16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
//----------------- |
// Flags |
//----------------- |
yoffs = -2; |
xoffs = -7; |
OSD_Element_Flag( 19, 2, OSD_FLAG_CF, 0+xoffs, 0+yoffs); // Carefree |
OSD_Element_Flag( 19, 4, OSD_FLAG_AH, 0+xoffs,-3+yoffs); // Altitude Hold |
OSD_Element_Flag( 19, 6, OSD_FLAG_PH, 0+xoffs,-6+yoffs); // Position Hold |
OSD_Element_Flag( 19, 7, OSD_FLAG_CH, 0+xoffs,-1+yoffs); // Coming Home |
|
xoffs -= 4; |
OSD_Element_Flag( 16, 2, OSD_FLAG_BA, -3+xoffs, 0+yoffs); // MK Batt Warning |
OSD_Element_Flag( 16, 4, OSD_FLAG_EL, -3+xoffs,-3+yoffs); // Emergency Landing |
OSD_Element_Flag( 16, 6, OSD_FLAG_RL, -3+xoffs,-6+yoffs); // Range Limit |
OSD_Element_Flag( 16, 7, OSD_FLAG_S0, -3+xoffs,-1+yoffs); // GPS-Sat not ok (GPS NOT ok) |
|
xoffs -= 4; |
OSD_Element_Flag( 12, 2, OSD_FLAG_CA, 0+xoffs, 0+yoffs); // Calibrate |
OSD_Element_Flag( 12, 4, OSD_FLAG_ST, 0+xoffs,-3+yoffs); // Start |
OSD_Element_Flag( 12, 6, OSD_FLAG_MR, 0+xoffs,-6+yoffs); // Motor Run |
OSD_Element_Flag( 12, 7, OSD_FLAG_FY, 0+xoffs,-1+yoffs); // Fly |
|
xoffs -= 4; |
OSD_Element_Flag( 9, 2, OSD_FLAG_O1, -2+xoffs, 0+yoffs); // Out1 |
OSD_Element_Flag( 9, 4, OSD_FLAG_O2, -2+xoffs,-3+yoffs); // Out2 |
OSD_Element_Flag( 9, 6, OSD_FLAG_TR, -2+xoffs,-6+yoffs); // Target Reached |
OSD_Element_Flag( 9, 7, OSD_FLAG_MC, -2+xoffs,-1+yoffs); // Manual Control |
|
xoffs -= 4; |
OSD_Element_Flag( 6, 2, OSD_FLAG_TU, -4+xoffs, 0+yoffs); // Vario Trim Up |
OSD_Element_Flag( 6, 4, OSD_FLAG_TD, -4+xoffs,-3+yoffs); // Vario Trim Down |
OSD_Element_Flag( 6, 6, OSD_FLAG_FR, -4+xoffs,-6+yoffs); // Free |
OSD_Element_Flag( 6, 7, OSD_FLAG_SL, -4+xoffs,-1+yoffs); // No Serial Link |
|
|
#ifdef USE_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 |
*/ |
yoffs = -2; |
xoffs = -7; |
OSD_Element_Flag_Label( 19, 2, OSD_FLAG_CF, true, 0+xoffs, 0+yoffs); // DEMO: Carefree |
OSD_Element_Flag_Label( 19, 4, OSD_FLAG_AH, true, 0+xoffs,-3+yoffs); // DEMO: Altitude Hold |
OSD_Element_Flag_Label( 19, 6, OSD_FLAG_PH, true, 0+xoffs,-6+yoffs); // DEMO: Position Hold |
OSD_Element_Flag_Label( 19, 7, OSD_FLAG_CH, true, 0+xoffs,-1+yoffs); // DEMO: Coming Home |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 16, 2, OSD_FLAG_BA, true, -3+xoffs, 0+yoffs); // DEMO: MK Batt Warning |
OSD_Element_Flag_Label( 16, 4, OSD_FLAG_EL, true, -3+xoffs,-3+yoffs); // DEMO: Emergency Landing |
OSD_Element_Flag_Label( 16, 6, OSD_FLAG_RL, true, -3+xoffs,-6+yoffs); // DEMO: Range Limit |
OSD_Element_Flag_Label( 16, 7, OSD_FLAG_S0, true, -3+xoffs,-1+yoffs); // DEMO: GPS-Sat not ok (GPS NOT ok) |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 12, 2, OSD_FLAG_CA, true, 0+xoffs, 0+yoffs); // DEMO: Calibrate |
OSD_Element_Flag_Label( 12, 4, OSD_FLAG_ST, true, 0+xoffs,-3+yoffs); // DEMO: Start |
OSD_Element_Flag_Label( 12, 6, OSD_FLAG_MR, true, 0+xoffs,-6+yoffs); // DEMO: Motor Run |
OSD_Element_Flag_Label( 12, 7, OSD_FLAG_FY, true, 0+xoffs,-1+yoffs); // DEMO: Fly |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 9, 2, OSD_FLAG_O1, true, -2+xoffs, 0+yoffs); // DEMO: Out1 |
OSD_Element_Flag_Label( 9, 4, OSD_FLAG_O2, true, -2+xoffs,-3+yoffs); // DEMO: Out2 |
OSD_Element_Flag_Label( 9, 6, OSD_FLAG_TR, true, -2+xoffs,-6+yoffs); // DEMO: Target Reached |
OSD_Element_Flag_Label( 9, 7, OSD_FLAG_MC, true, -2+xoffs,-1+yoffs); // DEMO: Manual Control |
|
xoffs -= 4; |
OSD_Element_Flag_Label( 6, 2, OSD_FLAG_TU, true, -4+xoffs, 0+yoffs); // DEMO: Vario Trim Up |
OSD_Element_Flag_Label( 6, 4, OSD_FLAG_TD, true, -4+xoffs,-3+yoffs); // DEMO: Vario Trim Down |
OSD_Element_Flag_Label( 6, 6, OSD_FLAG_FR, true, -4+xoffs,-6+yoffs); // DEMO: Free |
OSD_Element_Flag_Label( 6, 7, OSD_FLAG_SL, true, -4+xoffs,-1+yoffs); // DEMO: No Serial Link |
|
#endif |
} |
#endif // USE_OSD_SCREEN_MKSTATUS |
|
|
|
//-------------------------------------------------------------- |
// OSD_Screen_Electric() |
// |
// Anzeige BL-Temperaturen und Stroeme |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_ELECTRIC |
void OSD_Screen_Electric( void ) |
{ |
uint8_t x, y, x0, y0; |
int8_t yoffs; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
lcd_line (33, 0, 33, 19, 1); // Linie vertikal oben, links |
lcd_line (93, 0, 93, 19, 1); // Linie vertikal oben, rechts |
|
lcd_rect_round( 0, 19, 127, 63-19, 1, R2); // Rahmen |
lcd_line (0, 41, 127, 41, 1); // Linie horizontal mitte |
|
lcdx_printp_at( 12,0 , PSTR("mAh"), MNORMAL, -1,0); // entnommene Kapazität |
lcdx_printp_at( 12,1 , PSTR("A") , MNORMAL, -1,2); // aktueller Strom |
|
writex_ndigit_number_u( 19, 1, cells, 1, 0, MNORMAL, 2,2); // LiPO Cells Wert |
lcdx_printp_at( 20,1 , PSTR("s") , MNORMAL, 2,2); // LiPO Cells "s" |
|
} // end: if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
//----------------------------------------- |
|
|
//----------------- |
// Oben: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Oben: Batt Level Bar |
//----------------- |
//OSD_Element_Battery_Bar( x, y, length, width, orientation) |
OSD_Element_Battery_Bar( 0, 9, 30, 1, ORIENTATION_H); |
|
//----------------- |
// Oben: entnommene Kapazitaet (mAh) |
//----------------- |
drawmode = (naviData->UsedCapacity > Config.OSD_mAh_Warning ? MINVERS : MNORMAL); |
writex_ndigit_number_u( 7, 0, naviData->UsedCapacity, 5, 0, drawmode, -3,0); |
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
//writex_time(16, 0, naviData->FlyingTime+900, MNORMAL, 2,0); // DEBUG |
writex_time( 16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
//----------------- |
// Strom |
//----------------- |
writex_ndigit_number_u_10th( 7, 1, naviData->Current, 4, 0,MNORMAL, -3,2); // Strom mit Nachkomma |
|
//----------------- |
// BL 1-8 Temp & Strom |
//----------------- |
x0 = 1; |
y0 = 4; |
for( y=0; y<2; y++) // 2 Zeilen (mit je 4 BL's/Motoren) |
{ |
if( y==0 ) yoffs = -9; |
else yoffs = -3; |
|
for( x=0; x<4; x++) // und 4 BL's/Motoren pro Zeile |
{ |
if( blData[y*4+x].Status & 0xf0 ) // BL/Motor vorhanden? |
{ |
if( blData[y*4+x].Temperature != 0 ) // Anzeige nur wenn Temp != 0 wegen BL-Ctrl v1 die keine Temperatur senden |
{ |
writex_ndigit_number_u( (x*5)+x0, (y*2)+y0+0, ( blData[y*4+x].Temperature ), 3, 0,MNORMAL, 0,yoffs); // Temperatur |
lcdx_putc ( (x*5)+3+x0, (y*2)+y0+0, SYMBOL_SMALLDEGREE ,MNORMAL, 1,yoffs); |
} |
|
// Variante: mit Nachkommastellen |
writex_ndigit_number_u_10th ( (x*5)+x0, (y*2)+y0+1, ( blData[y*4+x].Current), 3, 0, MNORMAL, 0,yoffs); // Strom |
} |
} |
} |
|
#ifdef USE_OSD_DEMO |
OSD_Element_Flag_Label( 19, 1, OSD_FLAG_BA, true, 0,1); // DEMO |
#endif |
} |
#endif // USE_OSD_SCREEN_ELECTRIC_N |
|
|
|
|
//-------------------------------------------------------------- |
// OSD_Screen_Statistics() |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_STATISTIC |
void OSD_Screen_Statistics( void ) |
{ |
osd_BLmax_t blmax; |
uint8_t line = 0; |
|
|
// max. der BL's ermitteln |
calc_BLmax( &blmax ); |
|
|
//--------------------------- |
// max Altitude |
lcd_printp_at (0, line, strGet(STATS_ITEM_0), MNORMAL); |
write_ndigit_number_s (14, line, Config.OSD_Statistic.max_Altimeter / (30 / AltimeterAdjust), 4, 0,MNORMAL); |
lcdx_putc (18, line, 'm', MNORMAL, 2,0); |
|
//--------------------------- |
// max Speed |
// max_GroundSpeed = 1; |
lcd_printp_at (0, ++line, strGet(STATS_ITEM_1), MNORMAL); |
write_ndigit_number_u (15, line, (uint16_t) (((uint32_t) Config.OSD_Statistic.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_printp_at (0, ++line, strGet(STATS_ITEM_2), MNORMAL); |
write_ndigit_number_u (14, line, Config.OSD_Statistic.max_Distance / 10, 4, 0,MNORMAL); |
lcdx_putc (18, line, 'm', MNORMAL, 2,0); |
|
//--------------------------- |
// min voltage |
lcd_printp_at (0, ++line, strGet(STATS_ITEM_3), MNORMAL); |
if( Config.OSD_Statistic.min_UBat==255 ) |
lcd_printp_at(14, line, PSTR(" 0"), MNORMAL); |
else |
write_ndigit_number_u_10th (14, line, Config.OSD_Statistic.min_UBat, 3, 0,MNORMAL); |
lcdx_putc (18, line, 'V', MNORMAL, 2,0); |
|
//--------------------------- |
// Used Capacity |
lcd_printp_at (0, ++line, strGet(STATS_ITEM_6), MNORMAL); |
write_ndigit_number_u (14, line, Config.OSD_Statistic.max_Capacity, 4, 0,MNORMAL); |
lcdx_printp_at(18, line, PSTR("mAh"), MNORMAL, 2,0); |
|
|
//--------------------------- |
// max Current |
// max_Current = 1000; |
lcd_printp_at (0, ++line, strGet(STATS_ITEM_5), MNORMAL); |
write_ndigit_number_u_10th (13, line, Config.OSD_Statistic.max_Current, 4, 0,MNORMAL); |
lcdx_putc (18, line, 'A', MNORMAL, 2,0); |
|
|
//--------------------------- |
// max BL-Current |
line++; |
lcd_printp_at( 0, line, PSTR("max BL Curr:"), MNORMAL); |
write_ndigit_number_u( 6, line, blmax.max_BL_Current_Index+1, 1, 0,MNORMAL); |
write_ndigit_number_u_10th (14, line, blmax.max_BL_Current, 3, 0,MNORMAL); |
lcdx_putc (18, line, 'A', MNORMAL, 2,0); |
|
//--------------------------- |
// max BL-Temp |
line++; |
lcd_printp_at( 0, line, PSTR("max BL Temp:"), MNORMAL); |
write_ndigit_number_u( 6, line, blmax.max_BL_Temp_Index+1, 1, 0,MNORMAL); |
write_ndigit_number_u (14, line, blmax.max_BL_Temp, 4, 0,MNORMAL); |
lcdx_printp_at( 18, line, PSTR("\013C"), MNORMAL, 2,0); |
} |
#endif // USE_OSD_SCREEN_STATISTIC |
|
|
|
//-------------------------------------------------------------- |
// OSD_Screen_3DLage() |
//-------------------------------------------------------------- |
#ifdef USE_OSD_SCREEN_3DLAGE |
void OSD_Screen_3DLage( void ) |
{ |
uint16_t head_home; |
uint8_t Nick; |
uint8_t Roll; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
lcd_rect_round( 0, 0, 127, 63-0, 1, R2); // Rahmen |
} |
|
|
head_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360; |
|
lcd_line(26,32,100,32,1); // horizontal // |
lcd_line(63,0,63,63,1); // vertical // |
|
// 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); // -- // |
|
lcdx_printp_at( 9, 0, strGet(OSD_3D_V), MNORMAL, 0,4); // V |
lcdx_printp_at( 3, 3, strGet(OSD_3D_L), MNORMAL, 0,0); // L |
lcdx_printp_at(17, 3, strGet(OSD_3D_R), MNORMAL, 0,0); // R |
lcdx_printp_at( 9, 7, strGet(OSD_3D_H), MNORMAL, 0,-3); // H |
|
// Oben, Links: Ni |
lcdx_printp_at(0, 0, strGet(OSD_3D_NICK), MNORMAL, 5,4); // Ni |
writex_ndigit_number_s (2, 0, naviData->AngleNick, 3, 0, MNORMAL, 7,4); |
lcdx_putc (5, 0, SYMBOL_SMALLDEGREE, MNORMAL, 7,4); |
|
// Unten, Links: Ro |
lcdx_printp_at(0, 7, strGet(OSD_3D_ROLL), MNORMAL, 5,-3); // Ro |
writex_ndigit_number_s (2, 7, naviData->AngleRoll, 3, 0, MNORMAL, 7,-3); |
lcdx_putc (5, 7, SYMBOL_SMALLDEGREE, MNORMAL, 7,-3); |
|
// Oben, Rechts: Ko |
//lcdx_printp_at(13, 0, strGet(OSD_3D_COMPASS), MNORMAL, -4,3); // Ko |
writex_ndigit_number_u (15, 0, (naviData->CompassHeading)%360, 3, 0, MNORMAL, -4,4); |
lcdx_putc (18, 0, SYMBOL_SMALLDEGREE, MNORMAL, -4,4); |
OSD_Element_CompassDirection( 19, 0, -2,4 ); |
|
Roll = ((-naviData->AngleRoll/2)+63); |
Nick = ((-naviData->AngleNick/2)+32); |
|
if( Roll < (9+1) ) Roll = (9+1); // nicht ausserhalb des Screens zeichnen! |
if( Roll > 127-(9+1) ) Roll = 127-(9+1); // nicht ausserhalb des Screens zeichnen! |
|
if( Nick < (8+1) ) Nick = (8+1); // nicht ausserhalb des Screens zeichnen! |
if( Nick > 63-(8+1) ) Nick = 63-(8+1); // nicht ausserhalb des Screens zeichnen! |
|
if( old_AngleRoll != 0 ) // nicht ausserhalb des Screens zeichnen! |
{ |
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; |
} |
#endif // USE_OSD_SCREEN_3DLAGE |
|
|
|
|
//-------------------------------------------------------------- |
// OSD_Screen_MKDisplay() |
// |
// das ist ein Spezialscreen der ausserhalb der regulaeren |
// OSD-Screens aufgerufen und bedient wird! |
//-------------------------------------------------------------- |
//#ifdef USE_OSD_SCREEN_MKDISPLAY |
void OSD_Screen_MKDisplay( void ) |
{ |
uint8_t wpindex; |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
lcd_line( (6*6-3), 0, (6*6-3), 11, 1); // Linie Vertikal Oben: links |
lcd_line( (15*6+5), 0, (15*6+5), 11, 1); // Linie Vertikal Oben: rechts |
lcd_rect_round( 0, 2*7-2, 127, 5*7+3+3, 1, R2); // Rahmen unten fuer Inhalt Display |
|
//lcd_frect_round( 6*6+0, 0, 9*6+2, 9, 1, R1); // Umrahmung fuer "OSD-Displ" |
//lcdx_printp_at( 7, 0, PSTR("OSD-Disp"), MINVERS, -3,1); // "OSD-Displ" |
//lcdx_printp_at(15, 0, PSTR("l"), MINVERS, -4,1); // das "l" von "OSD-Displ" (1 Pixel nach links) |
|
lcdx_printp_at( 2, 7, PSTR("\x18 \x19"), MNORMAL, 0,0); // Keyline: Links / Rechts |
PKT_KeylineUpDown( 18, 13, 0,0); // Keyline: Down / Up |
|
} // end: if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
//----------------------------------------- |
|
|
//----------------- |
// Oben: Waypoint-Index und Anzahl der Waypoint's |
//----------------- |
wpindex = naviData->WaypointIndex; |
if( naviData->WaypointNumber==0 ) wpindex = 0; |
|
lcdx_printf_at_P( 7, 0, MNORMAL, -1,0, PSTR("WP:%2d/%2d"), wpindex, naviData->WaypointNumber ); |
|
|
//lcdx_printf_at_P(13, 0, MNORMAL, -3,1, PSTR("R:%d"), (naviData->NCFlags & NC_FLAG_TARGET_REACHED) ); |
//if ((NextWP==true)&& naviData->NCFlags & NC_FLAG_TARGET_REACHED) |
//lcd_printf_at_P( 0, 2, MNORMAL, PSTR("WP:%d"), naviData->WaypointIndex); |
//write_ndigit_number_u (x+2, y, naviData->WaypointIndex , 2, 0,0); |
//lcd_printp_at (x, y, PSTR("WP"), 0); |
//if ((NextWP==true)&& naviData->NCFlags & NC_FLAG_TARGET_REACHED) |
|
|
|
//----------------- |
// Oben: Batt Level (Volt) |
//----------------- |
OSD_Element_BattLevel2( 0, 0, 0,0 ); |
|
//----------------- |
// Oben: Batt Level Bar |
//----------------- |
//OSD_Element_Battery_Bar( x, y, length, width, orientation) |
OSD_Element_Battery_Bar( 0, 9, 30, 1, ORIENTATION_H); |
|
//----------------- |
// Oben: Navi-Kreis |
//----------------- |
//OSD_Element_HomeCircleX( 64, 5, 6, 5, true ); |
|
|
//----------------- |
// Oben: Flugzeit |
//----------------- |
writex_time(16, 0, naviData->FlyingTime, MNORMAL, 2,0); |
|
|
//------------------------------------------ |
// Ausgabe auf PKT-Anzeige |
// 4 Zeilen a 20 Zeichen |
//------------------------------------------ |
mkdisplayData[80] = 0; |
lcdx_print_at( 0,5, (uint8_t *) &mkdisplayData[60], MNORMAL, 5,3); |
|
mkdisplayData[60] = 0; |
lcdx_print_at( 0,4, (uint8_t *) &mkdisplayData[40], MNORMAL, 5,2); |
|
mkdisplayData[40] = 0; |
lcdx_print_at( 0,3, (uint8_t *) &mkdisplayData[20], MNORMAL, 5,1); |
|
mkdisplayData[20] = 0; |
lcdx_print_at( 0,2, (uint8_t *) &mkdisplayData[0], MNORMAL, 5,0); |
|
Beep_Waypoint(); |
} |
//#endif // USE_OSD_SCREEN_MKDISPLAY |
|
|
|
//############################################################## |
#ifdef USE_OSD_SCREEN_DEBUG |
//############################################################## |
|
//************************************************************** |
//* OSD_DEBUG_SCREEN - Experimental-Code usw. |
//* - nicht fuer die Oeffentlichkeit bestimmt |
//* - gesteuert ueber define OSD_DEBUG_SCREEN |
//************************************************************** |
|
//-------------------------------------------------------------- |
// OSD_Screen_Debug() |
//-------------------------------------------------------------- |
void OSD_Screen_Debug( void ) |
{ |
//char buffer[80]; |
static uint16_t debug_count = 0; |
//char buffer[30]; |
//uint8_t y, i; |
|
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
lcd_printp_at( 0, 0, PSTR("Debug"), 0); |
//timer_pkt_uptime = 0; |
} |
|
debug_count++; |
write_ndigit_number_u( 17, 0, (debug_count), 4, 0,MNORMAL); // |
|
|
// act. Current |
lcd_printf_at_P( 0, 2, MNORMAL, PSTR("act Current%3.1u A"), naviData->Current); |
|
// max. Current |
lcd_printf_at_P( 0, 3, MNORMAL, PSTR("max Current%3.1u A"), Config.OSD_Statistic.max_Current); |
|
// avg. Current |
lcd_printf_at_P( 0, 4, MNORMAL, PSTR("avg Current%3.1u A"), (uint8_t)(Config.OSD_Statistic.avg_Current/100)); |
|
// avg. Current DEBUG |
//lcd_printf_at_P( 0, 5, MNORMAL, PSTR("avgD Current%3.1u A"), (uint8_t)(Config.OSD_Statistic.avg_Altimeter/100)); |
|
// stat. Packages |
lcd_printf_at_P( 0, 6, MNORMAL, PSTR("stat Pkg's%7u"), Config.OSD_Statistic.count_osd); |
|
|
/* |
// DEBUG: Heading |
lcd_printf_at_P( 0, 1, MNORMAL, PSTR("NC-Errorcode:%3u"), naviData->Errorcode); |
|
//heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360; |
|
lcd_printf_at_P( 0, 3, MNORMAL, PSTR("CH:%6d%6d"), naviData->CompassHeading, naviData->CompassHeading%360); |
lcd_printf_at_P( 0, 4, MNORMAL, PSTR("HD:%6d%6d"), naviData->HomePositionDeviation.Bearing, naviData->HomePositionDeviation.Bearing%360); |
|
//heading_home = (naviData->HomePositionDeviation.Bearing + 360 - naviData->CompassHeading) % 360; |
|
//heading_home = ((naviData->CompassHeading % 360) - (naviData->HomePositionDeviation.Bearing % 360)) + 180; |
//heading_home = ((naviData->CompassHeading % 360) - (naviData->HomePositionDeviation.Bearing % 360)); |
|
calc_heading_home(); |
|
lcd_printf_at_P( 0, 6, MNORMAL, PSTR("xx:%6d"), heading_home); |
*/ |
|
/* |
lcd_putc( 0, 3, 0x08, MNORMAL); // ASCII - 8 08 SAT Symbol |
lcd_putc( 2, 3, 0x09, MNORMAL); // ASCII - 9 09 Altitude Symbol |
lcd_putc( 4, 3, 0x0C, MNORMAL); // ASCII - 12 0C Enter Symbol |
lcd_putc( 6, 3, 0x1F, MNORMAL); // ASCII - 31 1F Antenne |
lcd_putc( 8, 3, 10, MNORMAL); // 'o' |
lcd_putc(10, 3, 13, MNORMAL); // 'o' |
//lcd_putc(10, 3, 0x06, MNORMAL); |
//lcd_putc(12, 3, 0x07, MNORMAL); |
|
lcd_putc( 0, 5, 0x1E, MNORMAL); |
lcd_putc( 4, 5, 0x7e, MNORMAL); |
lcd_putc( 6, 5, 0x7f, MNORMAL); |
lcd_putc( 8, 5, 0x18, MNORMAL); |
lcd_putc(10, 5, 0x19, MNORMAL); |
*/ |
|
//lcd_printp_at( 0, 1, PSTR("Free RAM:"), 0); |
//writex_ndigit_number_u ( 9, 1, get_freeRam(), 9, 0,MNORMAL, 0,0); // |
} |
|
|
//-------------------------------------------------------------- |
// OSD_Screen_Debug_RX() |
// |
// Anzeige gelesener Datenpakete (fuer Feinabstimmung) und weitere |
// Werte wie Zeit/Datum (mit/ohne Abgleich zur NC) |
// |
// Anzeige oben 1. Zeile: |
// Screenname : "Debug-RX" |
// PKT-Uptime : Minuten, Sekunden die das PKT aktuell eingeschaltet ist |
// Screen-Count: Anzahl der Aufrufe des Screens (abhaengig von der Refreshtime) |
// |
// Anzeige Zeit: |
// "N" oder "O": neuer(N) oder alter(O) Zeit-Algo fuer die NC (OSD_MK_UTCTime()) |
// 00:00:00 : Stunde, Minute, Sekunde (korrigiert mittels PKT-Einstellung bzgl. Zeitzone/Sommerzeit) |
// dd.mm.yyyy : Tag, Monat, Jahr (korrigiert mittels PKT-Einstellung bzgl. Zeitzone/Sommerzeit) |
// Solange keine richtige Zeit von der NC gemeldet wird, wird die PKT-Uptime |
// seit einschalten des PKT angezeigt. |
// |
// Anzeige unten: |
// OSD: Anzahl gelesener OSD-Pakete der NC |
// Time: Anzahl gelesener Time-Pakete der NC (Aktualisierung ca. jede Minute) |
// |
// BL: es werden die gelesenen Datenpakete der BL's angezeigt |
// von BL1 (links oben) bis BL8 (rechts unten) |
//-------------------------------------------------------------- |
void OSD_Screen_Debug_RX( void ) |
{ |
static uint16_t debug_count = 0; |
uint8_t y; |
int8_t yoffs; |
|
//uint8_t status; // FC Kommunikation |
|
//----------------------------------------- |
// REDRAW |
// statische Screen Elemente die nicht |
// jedesmal neu gezeichnet werden muessen |
//----------------------------------------- |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) |
{ |
// do things here for static screen elements like labels and so.... |
lcd_frect( 0, 0, 1, 8, 1); // title spacer |
lcdx_printp_at( 0, 0, PSTR("Debug-RX"), MINVERS, 1,0); // title |
lcd_line (0, 9, 127, 9, 1); // Linie horizontal |
lcd_line (0, 22, 127, 22, 1); // Linie horizontal |
//lcd_line (0, 31, 127, 31, 1); // Linie horizontal |
} |
|
//----------------------- |
// Zeile 0 |
//----------------------- |
writex_time( 11, 0, timer_pkt_uptime/100, MNORMAL, 0,0); |
debug_count++; |
write_ndigit_number_u ( 17, 0, (debug_count), 4, 0,MNORMAL); // |
|
|
//----------------------- |
// Anzeige Zeit / Datum |
//----------------------- |
yoffs = 5; |
writex_datetime_time( 1, 1, UTCTime, MNORMAL, 5,yoffs); // Zeit |
writex_datetime_date( 11, 1, UTCTime, MNORMAL, 0,yoffs); // Datum |
|
//----------------------- |
// gelesene Pakete: OSD und Zeit |
//----------------------- |
y = 4; |
yoffs = -5; |
|
lcdx_printp_at( 0, y+0, PSTR("OSD:"), MNORMAL, 0,yoffs); |
writex_ndigit_number_u ( 4, y+0, ( readCounterOSD), 5, 0,MNORMAL, 0,yoffs); // |
|
lcdx_printp_at( 13, y+0, PSTR("Time:"), MNORMAL, 0,yoffs); |
writex_ndigit_number_u ( 18, y+0, ( readCounterTIME), 3, 0,MNORMAL, 0,yoffs); // |
|
|
//---- |
lcdx_printp_at( 0, y+1, PSTR("Dis:"), MNORMAL, 0,yoffs); |
writex_ndigit_number_u ( 4, y+1, ( readCounterDISPLAY), 5, 0,MNORMAL, 0,yoffs); // |
|
|
//----------------------- |
// gelesene Pakete: BL |
//----------------------- |
y = 6; |
lcd_frect( 0, y*8-1, 8, 17, 1); // Box |
|
lcdx_printp_at( 0, y+0, PSTR("B"), MINVERS, 2,0); |
lcdx_printp_at( 0, y+1, PSTR("L"), MINVERS, 2,0); |
write_ndigit_number_u ( 2, y+0, ( readCounterBL[0]), 4, 0,MNORMAL); // |
write_ndigit_number_u ( 7, y+0, ( readCounterBL[1]), 4, 0,MNORMAL); // |
write_ndigit_number_u ( 12, y+0, ( readCounterBL[2]), 4, 0,MNORMAL); // |
write_ndigit_number_u ( 17, y+0, ( readCounterBL[3]), 4, 0,MNORMAL); // |
|
write_ndigit_number_u ( 2, y+1, ( readCounterBL[4]), 4, 0,MNORMAL); // |
write_ndigit_number_u ( 7, y+1, ( readCounterBL[5]), 4, 0,MNORMAL); // |
write_ndigit_number_u ( 12, y+1, ( readCounterBL[6]), 4, 0,MNORMAL); // |
write_ndigit_number_u ( 17, y+1, ( readCounterBL[7]), 4, 0,MNORMAL); // |
} |
|
//############################################################## |
#endif // USE_OSD_SCREEN_DEBUG |
//############################################################## |
|
|
|
//----------------------------------------------------------- |
// ok = OSD_Popup_MKSetting() |
// |
// zeigt das aktuelle FC-Setting beim Start vom OSD an |
// |
// RUECKGABE: |
// true = Setting konnte gelesen werden |
// false = Fehler |
//----------------------------------------------------------- |
uint8_t OSD_Popup_MKSetting( void ) |
{ |
Popup_Draw( 3 ); // 3 Zeilen von unten nach oben fuer's Popup |
lcdx_printp_center( 2, PSTR("PKT OSD") , MNORMAL, 0, 0); |
lcdx_printp_center( 6, PSTR("MK Setting"), MINVERS, 0,-8); |
|
MK_Setting_load( 0xff, 9 ); // 0xff == aktuelles Parameterset holen; 9 == timeout |
|
MKVersion_Setting_print( 7, MINVERS, 0,-4); // aus: mkbase.c |
|
if( MKVersion.mksetting == 0 ) |
set_beep( 500, 0xffff, BeepNormal ); // kein Setting - langer Beep ERROR |
|
|
clear_key_all(); |
timer = 300; // ca. 3 Sekunden zeigen; Abbruch mit einer Taste moeglich |
while( timer > 0 && !get_key_press(0xff) ); |
|
clear_key_all(); |
lcd_cls(); |
|
return (MKVersion.mksetting != 0); |
} |
|
|
|
//----------------------------------------------------------- |
//----------------------------------------------------------- |
void OSD_Popup_MKError( u8 mkerrorcode ) |
{ |
Popup_Draw( 3 ); // 3 Zeilen von unten nach oben fuer's Popup |
|
lcdx_printf_center_P( 6, MINVERS, 0,-8, PSTR("** MK-%S %02d **"), strGet(STR_ERROR), mkerrorcode ); // "MK-FEHLER" und Fehlernummer |
|
lcdx_printp_center( 7, (const char*) pgm_read_word(&mkerrortext[mkerrorcode]), MINVERS, 0,-4); // MK-Fehlertext |
} |
|
|
|
//----------------------------------------------------------- |
//----------------------------------------------------------- |
void OSD_Popup_Info( uint8_t ScreenNum, const char *ScreenName) |
{ |
Popup_Draw( 5 ); // 5 Zeilen von unten nach oben fuer's Popup |
|
lcd_line( 3, 53-21, 124, 53-21, 0); // Linie: oben |
lcd_line( 3, 53, 124, 53, 0); // Linie: unten |
|
//----------------------- |
// ScreenNummer: ScreenName |
//----------------------- |
lcdx_printf_at_P( 0, 3, MINVERS, 5,-2, PSTR("%02d: %S"), ScreenNum, ScreenName ); |
|
//----------------------- |
// longpress Key's |
//----------------------- |
lcdx_printp_at( 0, 4, strGet(STR_LONGPRESS), MINVERS, 6,3); // "langer Tastendruck:" |
lcdx_printp_at(12, 5, PSTR("Disp"), MINVERS, 0,4); |
lcdx_printp_at(17, 5, PSTR("UGps"), MINVERS, 0,4); |
|
//----------------------- |
// shortpress Key's |
//----------------------- |
lcd_printp_at( 0, 7, strGet(KEYLINE3), MINVERS); |
lcd_printp_at(17, 7, PSTR("Info") , MINVERS); |
} |
|
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void GPS_Pos_Save( pkt_gpspos_t *pGPS ) |
{ |
pGPS->Altimeter = naviData->Altimeter; // barymetrische Hoehe |
pGPS->HomeDistance = naviData->HomePositionDeviation.Distance; // Entfernung Home |
|
memcpy( &pGPS->GPSData, &naviData->CurrentPosition, sizeof(GPS_Pos_t) ); // sichern... |
memcpy( &pGPS->timestamp, (char *)&UTCTime, sizeof(PKTdatetime_t) ); // sichern... |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
|
//-------------------------------------------------------------- |
// GPS_User_Init() |
// |
// initialisiert die GPS Positionen neu |
//-------------------------------------------------------------- |
|
void GPS_User_Init( void ) |
{ |
memset( Config.GPS_User, 0, sizeof(pkt_gpspos_t)*MAX_GPS_USER ); |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void GPS_User_Save( void ) |
{ |
uint8_t i; |
|
if( naviData->NCFlags & NC_FLAG_GPS_OK ) // nur wenn MK-GPS ok ist |
{ |
for( i=MAX_GPS_USER-1; i>0; i--) |
{ |
Config.GPS_User[i] = Config.GPS_User[i-1]; |
} |
GPS_Pos_Save( &Config.GPS_User[0] ); |
|
set_beep( 160, 0xffff, BeepNormal ); // Beep Ok |
} |
else |
{ |
set_beep( 600, 0x000f, BeepNormal ); // Beep Error (keine gueeltigen GPS-Daten) |
} |
} |
|
|
|
//############################################################## |
//############################################################## |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void MKLiPoCells_Init( void ) |
{ |
CellIsChecked = 0; |
cells = 0; |
} |
|
|
//-------------------------------------------------------------- |
//-------------------------------------------------------------- |
void MKLiPoCells_Check( void ) |
{ |
if( cells == 0 ) // Zellenzahl noch nicht ermittelt? |
{ |
// up to 6s LiPo, less than 2s is technical impossible |
for( cells = 2; cells < 7; cells++) |
{ |
if( naviData->UBat < cells * MAX_CELL_VOLTAGE ) break; |
} |
Config.OSD_Statistic.LiPoCells = cells; |
} |
} |
|
|
|
//############################################################## |
//# OSD MAIN LOOP |
//############################################################## |
|
//-------------------------------------------------------------- |
// OSD MAIN LOOP |
//-------------------------------------------------------------- |
void osd( void ) |
{ |
uint8_t osdexit = false; |
uint8_t mktimeout = false; |
uint8_t flying = false; |
uint8_t popup_state = OSD_POPUP_NONE; |
|
|
lcd_cls(); |
|
#ifdef DEBUG_OSD_TIME |
// Fake-Zeit/Datum setzen wenn der NC-Simulator verwendet wird |
if( UTCTime.year < 2000 ) |
{ |
UTCTime.seconds = ((uint32_t)13*3600)+(15*60)+42; // 13:15:42 |
UTCTime.day = 01; |
UTCTime.month = 05; |
UTCTime.year = 2013; |
} |
#endif |
|
|
//---------------------------------------- |
// Anzeige: aktuelles MK-Setting |
//---------------------------------------- |
if( (Config.OSD_ShowMKSetting) ) |
{ |
if( !OSD_Popup_MKSetting() ) |
return; |
} |
|
|
/* |
//----------------------------------------------------------------------------------------------- |
// 07.03.2013 OG: del |
// Dieser Teil hat immer wieder Probleme bereitet bei der Verbindung des PKT-OSD zum MK da |
// MK_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 MK_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_printp_at(0, 0, PSTR("Keine 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 |
*/ |
|
|
|
//------------------------- |
// MK-Display initialisieren |
//------------------------- |
memset( mkdisplayData, 0, 81 ); |
mkdisplayMode = false; |
mkdisplayCmd = 0xff; |
|
|
//------------------------- |
// BL-DATA initialisieren |
//------------------------- |
memset( blData, 0, sizeof(BLData_t)*OSD_MAX_MOTORS ); |
|
|
//------------------------- |
// Debug initialisieren |
//------------------------- |
#ifdef USE_OSD_SCREEN_DEBUG |
readCounterOSD = 0; |
readCounterTIME = 0; |
readCounterDISPLAY = 0; |
memset( readCounterBL, 0, sizeof(uint16_t)*OSD_MAX_MOTORS ); |
#endif // USE_OSD_SCREEN_DEBUG |
|
|
|
//------------------------- |
// NC Datenkommunikation starten |
//------------------------- |
OSD_MK_Connect( MK_CONNECT ); |
|
OSD_active = true; // benoetigt fuer Navidata Ausgabe an SV2 |
|
|
//------------------------- |
// Clear statistics |
//------------------------- |
//STAT_Init(); |
|
CellIsChecked = 0; |
cells = 0; |
AkkuWarnThreshold = 0; |
OldWP = 0; |
NextWP = false; |
old_PKTErrorcode = 0; |
old_MKErrorcode = 0; |
|
|
|
//------------------------- |
// Init: OSD-Screens |
//------------------------- |
ScreenCtrl_Init(); |
ScreenCtrl_Push( OSDSCREEN_GENERAL , strGet(STR_OSDSCREEN_GENERAL) , &OSD_Screen_General ); |
|
#ifdef USE_OSD_SCREEN_NAVIGATION |
ScreenCtrl_Push( OSDSCREEN_NAVIGATION , strGet(STR_OSDSCREEN_NAVIGATION), &OSD_Screen_Navigation ); |
#endif |
|
#ifdef USE_OSD_SCREEN_WAYPOINTS |
ScreenCtrl_Push( OSDSCREEN_WAYPOINTS , strGet(STR_OSDSCREEN_WAYPOINTS) , &OSD_Screen_Waypoints ); |
#endif |
|
// *ALTERNATIVE* |
//#ifdef USE_OSD_SCREEN_WAYPOINTS |
//ScreenCtrl_Push( OSDSCREEN_WAYPOINTS , strGet(STR_OSDSCREEN_WAYPOINTS) , &OSD_Screen_Waypoints0 ); |
//#endif |
|
#ifdef USE_OSD_SCREEN_ELECTRIC |
ScreenCtrl_Push( OSDSCREEN_ELECTRIC , strGet(STR_OSDSCREEN_ELECTRIC) , &OSD_Screen_Electric ); |
#endif |
|
#ifdef USE_OSD_SCREEN_MKSTATUS |
ScreenCtrl_Push( OSDSCREEN_MKSTATUS , strGet(STR_OSDSCREEN_MKSTATUS) , &OSD_Screen_MKStatus ); |
#endif |
|
#ifdef USE_OSD_SCREEN_USERGPS |
ScreenCtrl_Push( OSDSCREEN_USERGPS , strGet(STR_OSDSCREEN_USERGPS) , &OSD_Screen_UserGPS ); |
#endif |
|
#ifdef USE_OSD_SCREEN_3DLAGE |
ScreenCtrl_Push( OSDSCREEN_3DLAGE , strGet(STR_OSDSCREEN_3DLAGE) , &OSD_Screen_3DLage ); |
#endif |
|
#ifdef USE_OSD_SCREEN_STATISTIC |
ScreenCtrl_Push( OSDSCREEN_STATISTICS , strGet(STR_OSDSCREEN_STATISTIC) , &OSD_Screen_Statistics ); |
#endif |
|
#ifdef USE_OSD_SCREEN_OLD |
ScreenCtrl_Push( OSDSCREEN_OSD0 , strGet(STR_OSDSCREEN_OSD0) , &OSD_Screen_OSD0 ); |
ScreenCtrl_Push( OSDSCREEN_OSD1 , strGet(STR_OSDSCREEN_OSD1) , &OSD_Screen_OSD1 ); |
ScreenCtrl_Push( OSDSCREEN_OSD2 , strGet(STR_OSDSCREEN_OSD2) , &OSD_Screen_OSD2 ); |
#endif |
|
#ifdef USE_OSD_SCREEN_DEBUG |
ScreenCtrl_Push( 0 , PSTR("Debug") , &OSD_Screen_Debug ); |
ScreenCtrl_Push( 0 , PSTR("Debug-RX") , &OSD_Screen_Debug_RX ); |
#endif |
|
ScreenCtrl_Set( Config.OSD_ScreenMode ); |
|
|
//------------------------- |
// Init: Timer & Flags |
//------------------------- |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
timer_mk_timeout = MK_TIMEOUT; |
timer_osd_refresh = TIME_OSD_REFRESH; |
timer_get_bldata = 0; |
timer_get_tidata = 0; |
timer_get_displaydata = 0; |
|
|
//-------------------------------- |
// OSD Main-Loop |
//-------------------------------- |
while( !osdexit ) |
{ |
//################################ |
//# Empfange/verarbeite: OSD-Daten |
//################################ |
if( rxd_buffer_locked ) // naviData Ok? |
{ |
Decode64(); |
memcpy( &osdData, (const void *)pRxData, sizeof(NaviData_t) ); // sichern in: osdData |
naviData = &osdData; |
|
#ifdef USE_OSD_SCREEN_DEBUG |
readCounterOSD++; // gelesene Datenpakete |
#endif |
|
mktimeout = false; |
|
|
//---------------------------------- |
// LiPo Cell Check |
//---------------------------------- |
if( cells == 0 ) // Zellenzahl noch nicht ermittelt? |
{ |
// up to 6s LiPo, less than 2s is technical impossible |
for( cells = 2; cells < 7; cells++) |
{ |
if( naviData->UBat < cells * MAX_CELL_VOLTAGE ) break; |
} |
Config.OSD_Statistic.LiPoCells = cells; |
} |
|
|
//---------------------------------- |
// Winkel zu Home |
//---------------------------------- |
calc_heading_home(); |
|
|
//---------------------------------- |
// speichere letzte GPS-Positionen |
//---------------------------------- |
GPS_Pos_Save( &GPS_Current ); |
Config.LastLatitude = GPS_Current.GPSData.Latitude; // speichere letzte Position in Config |
Config.LastLongitude = GPS_Current.GPSData.Longitude; // speichere letzte Position in Config |
|
|
//---------------------------------- |
// PKT Fehler reset |
//---------------------------------- |
if( old_PKTErrorcode == 40 ) // 40 = PKT Empfangsausfall ("PKT RX lost") |
{ |
// PKT-Verbindungsfehler zuruecksetzen |
// da an dieser Stelle ja bereits wieder ein gueltiges Datenpaket |
// von der NaviCtrl empfangen wurde |
old_PKTErrorcode = 0; |
clear_key_all(); |
} |
|
|
//---------------------------------- |
// remember statistics (only when engines running) |
//---------------------------------- |
#ifdef DEBUG_OSD_STAT_MOTORRUN |
if( true ) |
#else |
if( naviData->FCStatusFlags & FC_STATUS_MOTOR_RUN ) // AM FLIEGEN -> Statistik aufzeichnen |
#endif |
{ |
flying = true; |
|
// --- gueltige Zeit von der NC vorhanden und noch keine Start-Zeit gesetzt? |
if( UTCTime.year != 0 && Config.OSD_Statistic.begin_StatTime.year == 0 ) |
{ |
memcpy( &Config.OSD_Statistic.begin_StatTime, (char *)&UTCTime, sizeof(PKTdatetime_t) ); // Start Zeit/Datum sichern... |
} |
|
Config.OSD_Statistic.last_FlyTime = naviData->FlyingTime; |
|
Config.OSD_Statistic.count_osd++; // Anzahl OSD-Statistik Pakete |
|
// int32_t calc_avg( int32_t avg, int32_t value, int32_t count, int32_t factor) |
Config.OSD_Statistic.avg_Current = (uint16_t)calc_avg( (int32_t)Config.OSD_Statistic.avg_Current, |
(int32_t)naviData->Current, |
(int32_t)Config.OSD_Statistic.count_osd, |
(int32_t)100 ); |
|
if( naviData->Altimeter > Config.OSD_Statistic.max_Altimeter ) Config.OSD_Statistic.max_Altimeter = naviData->Altimeter; |
if( naviData->GroundSpeed > Config.OSD_Statistic.max_GroundSpeed ) Config.OSD_Statistic.max_GroundSpeed = naviData->GroundSpeed; |
if( naviData->HomePositionDeviation.Distance > Config.OSD_Statistic.max_Distance ) Config.OSD_Statistic.max_Distance = naviData->HomePositionDeviation.Distance; |
if( naviData->Current > Config.OSD_Statistic.max_Current ) Config.OSD_Statistic.max_Current = naviData->Current; |
if( naviData->UsedCapacity > Config.OSD_Statistic.max_Capacity ) Config.OSD_Statistic.max_Capacity = naviData->UsedCapacity; |
if( naviData->UBat < Config.OSD_Statistic.min_UBat ) Config.OSD_Statistic.min_UBat = naviData->UBat; |
|
if( naviData->TopSpeed > Config.OSD_Statistic.max_TopSpeed ) Config.OSD_Statistic.max_TopSpeed = naviData->TopSpeed; |
if( naviData->RC_Quality > Config.OSD_Statistic.max_RCQuality ) Config.OSD_Statistic.max_RCQuality = naviData->RC_Quality; |
if( naviData->RC_Quality < Config.OSD_Statistic.min_RCQuality ) Config.OSD_Statistic.min_RCQuality = naviData->RC_Quality; |
|
if( naviData->AngleNick < Config.OSD_Statistic.min_AngleNick ) Config.OSD_Statistic.min_AngleNick = naviData->AngleNick; |
if( naviData->AngleNick > Config.OSD_Statistic.max_AngleNick ) Config.OSD_Statistic.max_AngleNick = naviData->AngleNick; |
|
if( naviData->AngleRoll < Config.OSD_Statistic.min_AngleRoll ) Config.OSD_Statistic.min_AngleRoll = naviData->AngleRoll; |
if( naviData->AngleRoll > Config.OSD_Statistic.max_AngleRoll ) Config.OSD_Statistic.max_AngleRoll = naviData->AngleRoll; |
} |
else if( flying && UTCTime.year != 0 ) // GELANDET -> Statistik beenden |
{ |
// --- Ende Zeit/Datum Statistik sichern |
memcpy( &Config.OSD_Statistic.end_StatTime, (char *)&UTCTime, sizeof(PKTdatetime_t) ); // Ende Zeit/Datum sichern... |
flying = false; |
} |
|
|
//----------------------- |
// Check: Akku Warnung |
//----------------------- |
CheckMKLipo(); |
|
|
//---------------------------------- |
// Show: OSD-Screens |
//---------------------------------- |
if( popup_state == OSD_POPUP_NONE && (timer_osd_refresh == 0 || OSDScreenRefresh == OSD_SCREEN_REDRAW) ) |
{ |
if( OSDScreenRefresh == OSD_SCREEN_REDRAW ) lcd_cls(); |
|
if( !mkdisplayMode ) |
ScreenCtrl_Show(); |
else |
OSD_Screen_MKDisplay(); |
|
timer_osd_refresh = TIME_OSD_REFRESH; |
} |
OSDScreenRefresh = OSD_SCREEN_REFRESH; |
|
|
//---------------------------------- |
// Check: MK-Error |
//---------------------------------- |
if( naviData->Errorcode != old_MKErrorcode && naviData->Errorcode <= MAX_MKERROR_NUM ) |
{ |
if( naviData->Errorcode > 0 ) // raise Error |
{ |
// Fehler aufzeichnen |
MkError_Save( naviData->Errorcode ); |
|
// Fehler Anzeigen |
OSD_Popup_MKError( naviData->Errorcode ); |
set_beep( 1000, 0x000f, BeepNormal); // Beep Error (MK-Error vorhanden) |
timer2 = TIME_POPUP_MKERROR; |
popup_state = OSD_POPUP_MKERROR; |
} |
else // reset Error |
{ |
popup_state = OSD_POPUP_NONE; |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
} |
old_MKErrorcode = naviData->Errorcode; |
} |
|
rxd_buffer_locked = FALSE; // ready to receive new data |
|
|
//------------------------------------------- |
// hole weitere Daten vom MK (BL, Time, ...) |
// |
// muss am Schluss stehen da naviData-Buffer |
// dabei ueberschrieben wird! |
//------------------------------------------- |
OSD_MK_GetData(); // holt BL-Daten und NC-Zeit |
|
|
timer_mk_timeout = MK_TIMEOUT; |
|
} //end: if( rxd_buffer_locked ) // OSD-Daten |
|
|
|
//################################ |
//# der Rest... |
//################################ |
|
//-------------------------------- |
// TASTEN: MK-Timeout |
//-------------------------------- |
if( mktimeout ) |
{ |
if( get_key_short(1 << KEY_ESC) ) // PKT OSD EXIT |
{ |
osdexit = true; |
} |
} |
|
|
//-------------------------------- |
// Popup beenden |
// wenn irgendeine Taste gedrückt oder Popup-Timeout |
//-------------------------------- |
if( !mktimeout && (popup_state != OSD_POPUP_NONE) && (get_key_press(255) || !timer2) ) // get_key_press(255) == alles an Tasten abfangen was moeglich ist |
{ |
popup_state = OSD_POPUP_NONE; |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
clear_key_all(); |
} |
|
|
//-------------------------------- |
// TASTEN: KEIN mkdisplay (OSD Modus) |
//-------------------------------- |
if( !osdexit && !mktimeout && !mkdisplayMode ) |
{ |
if( get_key_short(1 << KEY_ESC) ) // PKT OSD EXIT |
{ |
osdexit = true; |
} |
|
if( get_key_long(1 << KEY_ESC) ) // ÊINSCHALTEN: mkdisplayMode |
{ |
set_beep( 25, 0xffff, BeepNormal ); // kurzer Bestaetigungs-Beep |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
mkdisplayMode = true; |
mkdisplayCmd = 0; // lesen display-Daten erzwingen |
} |
|
if( get_key_long (1 << KEY_ENTER) ) // User GPS-Position sichern |
{ |
GPS_User_Save(); |
} |
|
if( get_key_short (1 << KEY_ENTER) ) // Popup: Info |
{ |
if( popup_state == OSD_POPUP_NONE ) |
{ |
popup_state = OSD_POPUP_INFO; |
OSD_Popup_Info( ScreenCtrl_GetNum(), ScreenCtrl_GetName() ); |
timer2 = TIME_POPUP_INFO; |
} |
} |
|
if( get_key_press (1 << KEY_MINUS)) // previous screen |
{ |
ScreenCtrl_Previous(); |
} |
|
if( get_key_press (1 << KEY_PLUS)) // next Screen |
{ |
ScreenCtrl_Next(); |
} |
|
} |
|
|
|
//-------------------------------- |
// TASTEN: mkdisplay AKTIV |
//-------------------------------- |
if( !osdexit && !mktimeout && mkdisplayMode ) |
{ |
/* |
if( get_key_long(1 << KEY_ENTER) // ABSCHALTEN mkdisplayMode: longpress ENTER, ESC, MINUS, PLUS schaltet mkdisplay aus |
|| get_key_long(1 << KEY_ESC) |
|| get_key_long(1 << KEY_MINUS) |
|| get_key_long(1 << KEY_PLUS) ) |
{ |
*/ |
|
if( get_key_long(1 << KEY_ESC) ) // ABSCHALTEN mkdisplayMode: longpress ESC (Taste 3 von links) |
{ |
set_beep( 25, 0xffff, BeepNormal ); // kurzer Bestaetigungs-Beep beim Modus-Wechsel |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
mkdisplayMode = false; |
clear_key_all(); |
} |
|
if( get_key_short (1 << KEY_MINUS) ) mkdisplayCmd = 0xfe; // MK-Key: rechts (next page) |
if( get_key_short (1 << KEY_PLUS) ) mkdisplayCmd = 0xfd; // MK-Key: links (previous page) |
if( get_key_short (1 << KEY_ESC) ) mkdisplayCmd = 0xfb; // MK-Key: runter |
if( get_key_short (1 << KEY_ENTER) ) mkdisplayCmd = 0xf7; // MK-Key: hoch |
|
if( mkdisplayCmd != 0xff ) // wenn eine MK-Display Taste gedrueckt worde sofort Daten |
{ // holen und darstellen um Anzeigereaktion fuer Benutzer zu verbessern |
timer_get_displaydata = 0; // lesen erzwingen |
OSD_MK_GetData(); // Daten holen |
OSD_Screen_MKDisplay(); // MK-Display Anzeigen |
} |
} |
|
|
|
//----------------------- |
// abo_timer |
//----------------------- |
if( abo_timer == 0 ) |
{ |
OSD_MK_Connect( MK_ABORENEW ); |
} |
|
|
//-------------------------- |
// Daten Timeout vom MK? |
//-------------------------- |
if( timer_mk_timeout == 0 ) |
{ |
if( !mktimeout ) OSD_MK_ShowTimeout(); // nur anzeigen wenn noch nicht im mktimeout-Modus |
set_beep ( 200, 0x0080, BeepNormal); // Beep |
mktimeout = true; |
timer_mk_timeout = MK_TIMEOUT; |
OSDScreenRefresh = OSD_SCREEN_REDRAW; |
OSD_MK_Connect( MK_CONNECT ); // 21.06.2014 OG: wieder aktviert wegen Umschaltung auf NC |
} |
|
|
|
//-------------------------- |
// Pruefe auf PKT-Update und |
// andere interne PKT-Aktionen |
//-------------------------- |
#ifdef USE_OSD_PKTHOOK |
if( PKT_CtrlHook() ) OSDScreenRefresh = OSD_SCREEN_REDRAW; // Update vom Updatetool angefordert? |
#endif |
|
} // END: while( !osdexit ) |
|
|
|
//------------------------------------------ |
// PKT-OSD beenden |
//------------------------------------------ |
Config.OSD_ScreenMode = ScreenCtrl_GetNum(); // merken letzter Screen |
|
|
//------------------------------------------ |
// ggf. Statistik Ende Zeit/Datum sichern |
//------------------------------------------ |
if( flying && UTCTime.year != 0 ) // wenn noch am fliegen |
{ |
// --- Ende Zeit/Datum Statistik sichern |
memcpy( &Config.OSD_Statistic.end_StatTime, (char *)&UTCTime, sizeof(PKTdatetime_t) ); // Ende Zeit/Datum sichern... |
} |
|
|
OSD_active = false; |
} |
|
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |