diff --git a/images/dev/satelliteinfo.jpg b/images/dev/satelliteinfo.jpg index 167f4326..63d22375 100644 Binary files a/images/dev/satelliteinfo.jpg and b/images/dev/satelliteinfo.jpg differ diff --git a/lib/gps/gps.cpp b/lib/gps/gps.cpp index 2a46889c..45660fed 100644 --- a/lib/gps/gps.cpp +++ b/lib/gps/gps.cpp @@ -173,6 +173,9 @@ void getGPSData() satTracker[i].snr = (uint8_t)GPS.satellites[i].snr; satTracker[i].active = GPS.satellites[i].tracked; strncpy(satTracker[i].talker_id, GPS.satellites[i].talker_id, 3); + int H = canvasRadius * (90 - satTracker[i].elev) / 90; + satTracker[i].posX = canvasCenter_X + H * sin(DEG2RAD(satTracker[i].azim)); + satTracker[i].posY = canvasCenter_Y - H * cos(DEG2RAD(satTracker[i].azim)); } } diff --git a/lib/gps/gps.hpp b/lib/gps/gps.hpp index e0a22d82..9d7ada9d 100644 --- a/lib/gps/gps.hpp +++ b/lib/gps/gps.hpp @@ -14,6 +14,9 @@ #include "settings.hpp" #include "timezone.hpp" +#define DEG2RAD(a) ((a) / (180 / M_PI)) // Convert degrees to radians +#define RAD2DEG(a) ((a) * (180 / M_PI)) // Convert radians to degrees + extern uint8_t GPS_TX; extern uint8_t GPS_RX; @@ -82,4 +85,14 @@ void getGPSData(); long detectRate(int rxPin); long autoBaudGPS(); +/** + * @brief Satellite Constellation Canvas Definition + * + */ +static const uint8_t canvasOffset = 15; +static const uint8_t canvasSize = 180; +static const uint8_t canvasCenter_X = canvasSize / 2; +static const uint8_t canvasCenter_Y = canvasSize / 2; +static const uint8_t canvasRadius = canvasCenter_X - canvasOffset; + #endif diff --git a/lib/gui/src/mainScr.cpp b/lib/gui/src/mainScr.cpp index acc2399e..8871b682 100644 --- a/lib/gui/src/mainScr.cpp +++ b/lib/gui/src/mainScr.cpp @@ -150,7 +150,6 @@ void scrollTile(lv_event_t *event) } deleteMapScrSprites(); - deleteSatInfoSprites(); } /** @@ -190,7 +189,6 @@ void updateMainScreen(lv_timer_t *t) break; case SATTRACK: - constelSprite.pushSprite(150 * scale, 40 * scale); lv_obj_send_event(satTrackTile, LV_EVENT_VALUE_CHANGED, NULL); break; @@ -276,7 +274,8 @@ void updateSatTrack(lv_event_t *event) lv_label_set_text_fmt(altLabel, "ALT: %4dm.", gpsData.altitude); - fillSatInView(); + drawSatSNR(); + drawSatSky(); } /** @@ -539,6 +538,18 @@ void createMainScr() // Satellite Tracking and info Tile satelliteScr(satTrackTile); + #ifdef BOARD_HAS_PSRAM + #ifndef TDECK_ESP32S3 + createConstCanvas(satTrackTile); + drawSatConst(); + lv_obj_set_pos(constCanvas,( TFT_WIDTH / 2 ) - canvasCenter_X, 240); + #endif + #ifdef TDECK_ESP32S3 + createConstCanvas(constMsg); + lv_obj_align(constCanvas,LV_ALIGN_CENTER,0,0); + drawSatConst(); + #endif + #endif // Satellite Tracking Event lv_obj_add_event_cb(satTrackTile, updateSatTrack, LV_EVENT_VALUE_CHANGED, NULL); diff --git a/lib/gui/src/mainScr.hpp b/lib/gui/src/mainScr.hpp index c1595926..a092bfe1 100644 --- a/lib/gui/src/mainScr.hpp +++ b/lib/gui/src/mainScr.hpp @@ -12,7 +12,6 @@ #include "globalGuiDef.h" #include "lvglFuncs.hpp" #include "misc/lv_color.h" -#include "satInfo.hpp" #include "notifyBar.hpp" #include "buttonBar.hpp" #include "renderMaps.hpp" diff --git a/lib/gui/src/satInfo.cpp b/lib/gui/src/satInfo.cpp deleted file mode 100644 index fdd67aac..00000000 --- a/lib/gui/src/satInfo.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @file satInfo.cpp - * @author Jordi Gauchía (jgauchia@gmx.es) - * @brief Satellites info screen functions - * @version 0.1.8_Alpha - * @date 2024-10 - */ - -#include "satInfo.hpp" -#include "globalGuiDef.h" - -// GSV GPS_GSV; // GPS Satellites in view -// GSV GL_GSV; // GLONASS Satellites in view -// GSV BD_GSV; // BEIDOU Satellites in view - -SatPos satPos; // Satellite position X,Y in constellation map - -TFT_eSprite spriteSat = TFT_eSprite(&tft); // Sprite for satellite position in map -TFT_eSprite constelSprite = TFT_eSprite(&tft); // Sprite for Satellite Constellation - -lv_obj_t *satelliteBar; // Satellite Signal Graphics Bars -lv_chart_series_t *satelliteBarSerie; // Satellite Signal Graphics Bars - -/** - * @brief Get the Satellite position for constellation map - * - * @param elev -> elevation - * @param azim -> Azimuth - * @return SatPos -> Satellite position - */ -SatPos getSatPos(uint8_t elev, uint16_t azim) -{ - SatPos pos; - int H = (60 * cos(DEG2RAD(elev))); - pos.x = 75 + (H * sin(DEG2RAD(azim))); - pos.y = 75 - (H * cos(DEG2RAD(azim))); - return pos; -} - -/** - * @brief Delete sat info screen sprites and release PSRAM - * - */ -void deleteSatInfoSprites() -{ - spriteSat.deleteSprite(); - constelSprite.deleteSprite(); -} - -/** - * @brief Create Constellation sprite - * - * @param spr -> Sprite - */ -void createConstelSprite(TFT_eSprite &spr) -{ - spr.createSprite(150 * scale, 150 * scale); - spr.fillScreen(TFT_BLACK); - spr.drawCircle(75 * scale, 75 * scale, 60 * scale, TFT_WHITE); - spr.drawCircle(75 * scale, 75 * scale, 30 * scale, TFT_WHITE); - spr.drawCircle(75 * scale, 75 * scale, 1, TFT_WHITE); - #ifdef LARGE_SCREEN - spr.setTextFont(2); - #else - spr.setTextFont(1); - #endif - spr.setTextColor(TFT_WHITE, TFT_BLACK); - spr.drawString("N", 72 * scale, 7); - spr.drawString("S", 72 * scale, 127 * scale); - spr.drawString("W", 12 * scale, 67 * scale); - spr.drawString("E", 132 * scale, 67 * scale); - spr.setTextFont(1); -} - -/** - * @brief Create satellite sprite - * - * @param spr -> Sprite - */ -void createSatSprite(TFT_eSprite &spr) -{ - spr.deleteSprite(); - spr.createSprite(16, 20); - spr.setColorDepth(16); - spr.fillScreen(TFT_TRANSPARENT); -} - -/** - * @brief Draw SNR bar and satellite number - * - * @param bar -> Bar Control - * @param barSer -> Bar Control Serie - * @param id -> Active Sat - * @param satNum -> Sat ID - * @param snr -> Sat SNR - */ -void drawSNRBar(lv_obj_t *bar, lv_chart_series_t *barSer, uint8_t id, uint8_t satNum, uint8_t snr) -{ - lv_chart_get_y_array(bar, barSer); - lv_chart_set_value_by_id(bar, barSer, id, snr); -} - -/** - * @brief Clear Satellite in View found - * - */ -void clearSatInView() -{ - // createConstelSprite(constelSprite); -} - -/** - * @brief Display satellite in view info - * - * - */ -void fillSatInView() -{ - - lv_chart_refresh(satelliteBar); - - - for (int i = 0; i < MAX_SATELLLITES_IN_VIEW ; i++) - { - lv_chart_set_value_by_id(satelliteBar, satelliteBarSerie, i, LV_CHART_POINT_NONE); - } - - for (int i = 0; i < gpsData.satInView; ++i) - { - - drawSNRBar(satelliteBar, satelliteBarSerie, i, satTracker[i].satNum, satTracker[i].snr); - - satPos = getSatPos(satTracker[i].elev, satTracker[i].azim); - - // spriteSat.fillCircle(6, 4, 2, TFT_GREEN); - // spriteSat.setCursor(0 , 8); - // spriteSat.print(satTracker[i].satNum); - // spriteSat.pushSprite(&constelSprite,satPos.x, satPos.y, TFT_TRANSPARENT); - - // if ( satTracker[i].posX != satPos.x || satTracker[i].posY != satPos.y) - // { - // spriteSat.fillScreen(TFT_TRANSPARENT); - // spriteSat.pushSprite(&constelSprite, satTracker[i].posX, satTracker[i].posY, TFT_TRANSPARENT); - // } - - satTracker[i].posX = satPos.x; - satTracker[i].posY = satPos.y; - - // spriteSat.fillScreen(TFT_TRANSPARENT); - // spriteSat.pushSprite(&constelSprite, satTracker[i].posX, satTracker[i].posY, TFT_TRANSPARENT); - } - - lv_chart_refresh(satelliteBar); - -} diff --git a/lib/gui/src/satInfo.hpp b/lib/gui/src/satInfo.hpp deleted file mode 100644 index 47e94227..00000000 --- a/lib/gui/src/satInfo.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file satInfo.hpp - * @author Jordi Gauchía (jgauchia@gmx.es) - * @brief Satellites info screen functions - * @version 0.1.8_Alpha - * @date 2024-10 - */ - -#ifndef SATINFO_HPP -#define SATINFO_HPP - -#include -#include "tft.hpp" -#include "gpsMath.hpp" -#include "gps.hpp" -#include - -struct SatPos // Structure to store satellite position in constellation map -{ - uint16_t x; - uint16_t y; -}; - -extern SatPos satPos; // Satellite position X,Y in constellation map - -extern TFT_eSprite spriteSat; // Sprite for satellite position in map -extern TFT_eSprite constelSprite; // Sprite for Satellite Constellation - -extern lv_obj_t *satelliteBar; // Satellite Signal Graphics Bars -extern lv_chart_series_t *satelliteBarSerie; // Satellite Signal Graphics Bars - -SatPos getSatPos(uint8_t elev, uint16_t azim); -void deleteSatInfoSprites(); -void createConstelSprite(TFT_eSprite &spr); -void createSatSprite(TFT_eSprite &spr); -void drawSNRBar(lv_obj_t *bar, lv_chart_series_t *barSer, uint8_t id, uint8_t satNum, uint8_t snr); -void clearSatInView(); -void fillSatInView(); -#endif diff --git a/lib/gui/src/satInfoScr.cpp b/lib/gui/src/satInfoScr.cpp index 0a46e94f..5e320ade 100644 --- a/lib/gui/src/satInfoScr.cpp +++ b/lib/gui/src/satInfoScr.cpp @@ -12,7 +12,12 @@ lv_obj_t *pdopLabel; lv_obj_t *hdopLabel; lv_obj_t *vdopLabel; lv_obj_t *altLabel; - +lv_obj_t *constCanvas; +lv_layer_t canvasLayer; +lv_layer_t satLayer; +lv_obj_t *satelliteBar; +lv_chart_series_t *satelliteBarSerie; +lv_obj_t *constMsg; /** * @brief Draw Text on SNR Chart @@ -69,11 +74,11 @@ void satelliteBarDrawEvent(lv_event_t * event) if(fill_dsc) { if ( strcmp(satTracker[dscId].talker_id,"GP") == 0 ) - fill_dsc->color = satTracker[dscId].active == true ? lv_color_hex(0x229954) : lv_color_hex(0x104828); + fill_dsc->color = satTracker[dscId].active == true ? GP_INACTIVE_COLOR : GP_ACTIVE_COLOR; if ( strcmp(satTracker[dscId].talker_id,"GL") == 0 ) - fill_dsc->color = satTracker[dscId].active == true ? lv_color_hex(0x2471a3) : lv_color_hex(0x11364d); + fill_dsc->color = satTracker[dscId].active == true ? GL_INACTIVE_COLOR : GL_ACTIVE_COLOR; if ( strcmp(satTracker[dscId].talker_id,"BD") == 0 ) - fill_dsc->color = satTracker[dscId].active == true ? lv_color_hex(0x7d3c98) : lv_color_hex(0x3b1c48); + fill_dsc->color = satTracker[dscId].active == true ? BD_INACTIVE_COLOR : BD_ACTIVE_COLOR; } } } @@ -105,14 +110,53 @@ void satelliteBarDrawEvent(lv_event_t * event) } } +/** + * @brief SNR Long press event for show constellation Map (only for T-DECK) + * + * @param event + */ +void constSatEvent(lv_event_t *event) +{ + lv_event_code_t code = lv_event_get_code(event); + + if (code == LV_EVENT_LONG_PRESSED) + lv_obj_clear_flag(constMsg,LV_OBJ_FLAG_HIDDEN); +} +/** + * @brief Event for hide constellation Map (only for T-DECK) + * + * @param event + */ +void closeConstSatEvent(lv_event_t *event) +{ + lv_event_code_t code = lv_event_get_code(event); + + if (code == LV_EVENT_LONG_PRESSED) + lv_obj_add_flag(constMsg,LV_OBJ_FLAG_HIDDEN); +} + + /** + * @brief Create Canvas for Satellite Constellation + * + * @param screen + */ +void createConstCanvas(_lv_obj_t *screen) +{ + static lv_color_t *cbuf = (lv_color_t*)heap_caps_aligned_alloc(16, (canvasSize*canvasSize*sizeof(lv_color_t)), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);; + constCanvas = lv_canvas_create(screen); + lv_canvas_set_buffer(constCanvas, cbuf, canvasSize, canvasSize, LV_COLOR_FORMAT_RGB565); + lv_canvas_fill_bg(constCanvas, lv_color_black(), LV_OPA_100); + + lv_canvas_init_layer(constCanvas, &canvasLayer); +} /** * @brief Satellite info screen * * @param screen */ - #ifndef TDECK_ESP32S3 +#ifndef TDECK_ESP32S3 void satelliteScr(_lv_obj_t *screen) { lv_obj_t *infoGrid = lv_obj_create(screen); @@ -156,9 +200,9 @@ void satelliteBarDrawEvent(lv_event_t * event) lv_obj_set_style_text_font(gnssLabel, fontSatInfo, 0); lv_obj_set_pos(gnssLabel, 0, 127); lv_obj_set_width(gnssLabel,90); - lv_obj_set_style_bg_color(gnssLabel, lv_color_hex(0x104828), 0); + lv_obj_set_style_bg_color(gnssLabel, GP_ACTIVE_COLOR, 0); lv_obj_set_style_bg_opa(gnssLabel, LV_OPA_100, 0); - lv_obj_set_style_border_color(gnssLabel, lv_color_hex(0x229954), 0); + lv_obj_set_style_border_color(gnssLabel, GP_INACTIVE_COLOR, 0); lv_obj_set_style_border_width(gnssLabel, 1, 0); lv_obj_set_style_border_opa(gnssLabel, LV_OPA_100, 0); lv_label_set_text(gnssLabel, "GPS"); @@ -168,9 +212,9 @@ void satelliteBarDrawEvent(lv_event_t * event) lv_obj_set_style_text_font(gnssLabel, fontSatInfo, 0); lv_obj_set_pos(gnssLabel, 95, 127); lv_obj_set_width(gnssLabel,90); - lv_obj_set_style_bg_color(gnssLabel, lv_color_hex(0x11364d), 0); + lv_obj_set_style_bg_color(gnssLabel, GL_ACTIVE_COLOR, 0); lv_obj_set_style_bg_opa(gnssLabel, LV_OPA_100, 0); - lv_obj_set_style_border_color(gnssLabel, lv_color_hex(0x2471a3), 0); + lv_obj_set_style_border_color(gnssLabel, GL_INACTIVE_COLOR, 0); lv_obj_set_style_border_width(gnssLabel, 1, 0); lv_obj_set_style_border_opa(gnssLabel, LV_OPA_100, 0); lv_label_set_text(gnssLabel, "GLONASS"); @@ -180,9 +224,9 @@ void satelliteBarDrawEvent(lv_event_t * event) lv_obj_set_style_text_font(gnssLabel, fontSatInfo, 0); lv_obj_set_pos(gnssLabel, 190, 127); lv_obj_set_width(gnssLabel,90); - lv_obj_set_style_bg_color(gnssLabel, lv_color_hex(0x3b1c48), 0); + lv_obj_set_style_bg_color(gnssLabel, BD_ACTIVE_COLOR, 0); lv_obj_set_style_bg_opa(gnssLabel, LV_OPA_100, 0); - lv_obj_set_style_border_color(gnssLabel, lv_color_hex(0x7d3c98), 0); + lv_obj_set_style_border_color(gnssLabel, BD_INACTIVE_COLOR, 0); lv_obj_set_style_border_width(gnssLabel, 1, 0); lv_obj_set_style_border_opa(gnssLabel, LV_OPA_100, 0); lv_label_set_text(gnssLabel, "BEIDOU"); @@ -205,7 +249,7 @@ void satelliteBarDrawEvent(lv_event_t * event) #endif #ifdef TDECK_ESP32S3 -void satelliteScr(_lv_obj_t *screen) + void satelliteScr(_lv_obj_t *screen) { lv_obj_t *infoGrid = lv_obj_create(screen); lv_obj_set_width(infoGrid,TFT_WIDTH); @@ -249,9 +293,9 @@ void satelliteScr(_lv_obj_t *screen) lv_obj_set_style_text_font(gnssLabel, fontSatInfo, 0); lv_obj_set_pos(gnssLabel, 0, 102); lv_obj_set_width(gnssLabel,90); - lv_obj_set_style_bg_color(gnssLabel, lv_color_hex(0x104828), 0); + lv_obj_set_style_bg_color(gnssLabel, GP_ACTIVE_COLOR, 0); lv_obj_set_style_bg_opa(gnssLabel, LV_OPA_100, 0); - lv_obj_set_style_border_color(gnssLabel, lv_color_hex(0x229954), 0); + lv_obj_set_style_border_color(gnssLabel, GP_INACTIVE_COLOR, 0); lv_obj_set_style_border_width(gnssLabel, 1, 0); lv_obj_set_style_border_opa(gnssLabel, LV_OPA_100, 0); lv_label_set_text(gnssLabel, "GPS"); @@ -261,9 +305,9 @@ void satelliteScr(_lv_obj_t *screen) lv_obj_set_style_text_font(gnssLabel, fontSatInfo, 0); lv_obj_set_pos(gnssLabel, 95, 102); lv_obj_set_width(gnssLabel,90); - lv_obj_set_style_bg_color(gnssLabel, lv_color_hex(0x11364d), 0); + lv_obj_set_style_bg_color(gnssLabel, GL_ACTIVE_COLOR, 0); lv_obj_set_style_bg_opa(gnssLabel, LV_OPA_100, 0); - lv_obj_set_style_border_color(gnssLabel, lv_color_hex(0x2471a3), 0); + lv_obj_set_style_border_color(gnssLabel, GL_INACTIVE_COLOR, 0); lv_obj_set_style_border_width(gnssLabel, 1, 0); lv_obj_set_style_border_opa(gnssLabel, LV_OPA_100, 0); lv_label_set_text(gnssLabel, "GLONASS"); @@ -273,9 +317,9 @@ void satelliteScr(_lv_obj_t *screen) lv_obj_set_style_text_font(gnssLabel, fontSatInfo, 0); lv_obj_set_pos(gnssLabel, 190, 102); lv_obj_set_width(gnssLabel,90); - lv_obj_set_style_bg_color(gnssLabel, lv_color_hex(0x3b1c48), 0); + lv_obj_set_style_bg_color(gnssLabel, BD_ACTIVE_COLOR, 0); lv_obj_set_style_bg_opa(gnssLabel, LV_OPA_100, 0); - lv_obj_set_style_border_color(gnssLabel, lv_color_hex(0x7d3c98), 0); + lv_obj_set_style_border_color(gnssLabel, BD_INACTIVE_COLOR, 0); lv_obj_set_style_border_width(gnssLabel, 1, 0); lv_obj_set_style_border_opa(gnssLabel, LV_OPA_100, 0); lv_label_set_text(gnssLabel, "BEIDOU"); @@ -294,5 +338,156 @@ void satelliteScr(_lv_obj_t *screen) lv_obj_add_event_cb(satelliteBar, satelliteBarDrawEvent, LV_EVENT_DRAW_TASK_ADDED, NULL); lv_obj_add_event_cb(satelliteBar, satelliteBarDrawEvent, LV_EVENT_DRAW_POST_END, NULL); lv_obj_add_flag(satelliteBar, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + lv_obj_add_event_cb(satelliteBar, constSatEvent, LV_EVENT_LONG_PRESSED, NULL); + + constMsg = lv_msgbox_create(screen); + lv_obj_set_size(constMsg, 180, 185); + lv_obj_set_align(constMsg,LV_ALIGN_CENTER); + lv_obj_add_flag(constMsg,LV_OBJ_FLAG_HIDDEN); + lv_obj_add_event_cb(constMsg, closeConstSatEvent, LV_EVENT_LONG_PRESSED, NULL); + } +#endif + +/** + * @brief Draw Satellite SNR Bars + * + * + */ +void drawSatSNR() +{ + for (int i = 0; i < MAX_SATELLLITES_IN_VIEW ; i++) + { + lv_chart_set_value_by_id(satelliteBar, satelliteBarSerie, i, LV_CHART_POINT_NONE); + } + + for (int i = 0; i < gpsData.satInView; ++i) + { + lv_chart_set_value_by_id(satelliteBar, satelliteBarSerie, i, satTracker[i].snr); + } + + lv_chart_refresh(satelliteBar); +} + +/** + * @brief Draw Satellite Constellation + * + * + */ +void drawSatConst() +{ + // Draw Circles + lv_draw_arc_dsc_t dscArc; + lv_draw_arc_dsc_init(&dscArc); + dscArc.color = CONSTEL_COLOR; + dscArc.width = 2; + dscArc.center.x = canvasCenter_X; + dscArc.center.y = canvasCenter_Y; + dscArc.start_angle = 0; + dscArc.end_angle = 360; + dscArc.radius = canvasRadius; + lv_draw_arc(&canvasLayer, &dscArc); + dscArc.radius = ( canvasRadius * 2 ) / 3; + lv_draw_arc(&canvasLayer, &dscArc); + dscArc.radius = canvasRadius / 3 ; + lv_draw_arc(&canvasLayer, &dscArc); + + // Draw Lines + lv_draw_line_dsc_t dscLine; + lv_draw_line_dsc_init(&dscLine); + dscLine.color = CONSTEL_COLOR; + dscLine.width = 2; + dscLine.round_end = 1; + dscLine.round_start = 1; + dscLine.p1.x = canvasCenter_X; + dscLine.p1.y = canvasOffset; + dscLine.p2.x = canvasCenter_X; + dscLine.p2.y = canvasSize-canvasOffset; + lv_draw_line(&canvasLayer, &dscLine); + dscLine.p1.x = canvasOffset; + dscLine.p1.y = canvasCenter_Y; + dscLine.p2.x = canvasSize-canvasOffset; + dscLine.p2.y = canvasCenter_Y; + lv_draw_line(&canvasLayer, &dscLine); + + // Draw Text Coordinates + lv_draw_label_dsc_t dscLabel; + lv_draw_label_dsc_init(&dscLabel); + dscLabel.color = CONSTEL_COLOR; + dscLabel.opa = LV_OPA_100; + dscLabel.font = &lv_font_montserrat_12; + dscLabel.text = "N"; + lv_area_t labelPos = {canvasCenter_X-5, 0, canvasCenter_X+5, 0}; + lv_draw_label(&canvasLayer, &dscLabel, &labelPos); + dscLabel.text = "S"; + labelPos = {canvasCenter_X-4, canvasSize-15, canvasCenter_X+4, canvasSize}; + lv_draw_label(&canvasLayer, &dscLabel, &labelPos); + dscLabel.text = "E"; + labelPos = {canvasSize-12, canvasCenter_Y-7 , canvasSize, canvasCenter_Y+7}; + lv_draw_label(&canvasLayer, &dscLabel, &labelPos); + dscLabel.text = "W"; + labelPos = {0, canvasCenter_Y-7, canvasSize - 10, canvasCenter_Y+7}; + lv_draw_label(&canvasLayer, &dscLabel, &labelPos); + + // Finish Canvas Draw + lv_canvas_finish_layer(constCanvas, &canvasLayer); +} + +/** + * @brief Draw Satellite Position in Constellation + * + * + */ +void drawSatSky() +{ + lv_canvas_fill_bg(constCanvas, lv_color_black(), LV_OPA_100); + drawSatConst(); + + lv_layer_t satPosLayer; + lv_canvas_init_layer(constCanvas, &satPosLayer); + + // Draw Satellite + lv_draw_arc_dsc_t dscSat; + lv_draw_arc_dsc_init(&dscSat); + dscSat.width = 8; + dscSat.start_angle = 0; + dscSat.end_angle = 360; + dscSat.radius = 8; + dscSat.opa = LV_OPA_70; + + for (int i = 0; i < gpsData.satInView; i++) + { + if ( strcmp(satTracker[i].talker_id,"GP") == 0 ) + dscSat.color = satTracker[i].active == true ? GP_INACTIVE_COLOR : GP_ACTIVE_COLOR; + if ( strcmp(satTracker[i].talker_id,"GL") == 0 ) + dscSat.color = satTracker[i].active == true ? GL_INACTIVE_COLOR : GL_ACTIVE_COLOR; + if ( strcmp(satTracker[i].talker_id,"BD") == 0 ) + dscSat.color = satTracker[i].active == true ? BD_INACTIVE_COLOR : BD_ACTIVE_COLOR; + dscSat.center.x = satTracker[i].posX; + dscSat.center.y = satTracker[i].posY; + lv_draw_arc(&satPosLayer, &dscSat); + + // Draw Satellite Number + char buf[16]; + lv_draw_rect_dsc_t draw_rect_dsc; + lv_draw_rect_dsc_init(&draw_rect_dsc); + + lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"%d", satTracker[i].satNum); + + draw_rect_dsc.bg_opa = LV_OPA_TRANSP; + draw_rect_dsc.radius = 0; + draw_rect_dsc.bg_image_symbol_font = &lv_font_montserrat_8; + draw_rect_dsc.bg_image_src = buf; + draw_rect_dsc.bg_image_recolor = lv_color_white(); + + lv_area_t a; + a.x1 = satTracker[i].posX-8; + a.x2 = satTracker[i].posX+8; + a.y1 = satTracker[i].posY-5; + a.y2 = satTracker[i].posY+4; + + lv_draw_rect(&satPosLayer, &draw_rect_dsc, &a); + + // Finish Canvas Draw + lv_canvas_finish_layer(constCanvas, &satPosLayer); } -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/lib/gui/src/satInfoScr.hpp b/lib/gui/src/satInfoScr.hpp index 2203b598..6dd62a13 100644 --- a/lib/gui/src/satInfoScr.hpp +++ b/lib/gui/src/satInfoScr.hpp @@ -12,7 +12,20 @@ #include "lvgl.h" #include "globalGuiDef.h" #include "gps.hpp" -#include "satInfo.hpp" + +/** + * @brief Satellite SV Colors + * + */ +// GPS +#define GP_ACTIVE_COLOR lv_color_hex(0x104828) +#define GP_INACTIVE_COLOR lv_color_hex(0x229954) +// GLONASS +#define GL_ACTIVE_COLOR lv_color_hex(0x11364d) +#define GL_INACTIVE_COLOR lv_color_hex(0x2471a3) +// BEIDOU +#define BD_ACTIVE_COLOR lv_color_hex(0x3b1c48) +#define BD_INACTIVE_COLOR lv_color_hex(0x7d3c98) /** * @brief Satellite Tracking Tile screen objects @@ -22,9 +35,27 @@ extern lv_obj_t *pdopLabel; extern lv_obj_t *hdopLabel; extern lv_obj_t *vdopLabel; extern lv_obj_t *altLabel; +extern lv_obj_t *constCanvas; +extern lv_obj_t *satelliteBar; +extern lv_chart_series_t *satelliteBarSerie; +extern lv_obj_t *constMsg; + +/** + * @brief Satellite Constellation Layer Canvas Definition + * + */ + #define CONSTEL_COLOR lv_color_hex(0x515a5a) + extern lv_layer_t canvasLayer; + extern lv_layer_t satLayer; + void drawTextOnLayer(const char * text, lv_layer_t * layer, lv_point_t * p, lv_area_t * coords, lv_color_t color, const void * font, int16_t offset); -void satelliteBarDrawEvent(lv_event_t * event); +void satelliteBarDrawEvent(lv_event_t *event); +void constSatEvent(lv_event_t *event); +void closeConstSatEvent(lv_event_t *event); +void createConstCanvas(_lv_obj_t *screen); void satelliteScr(_lv_obj_t *screen); - +void drawSatSNR(); +void drawSatConst(); +void drawSatSky(); #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 19af32c3..0ef3f908 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,7 +16,7 @@ default_envs = ICENAV_BOARD platform = espressif32 framework = arduino version = 0.1.8_Alpha -revision = 75 +revision = 76 monitor_speed = 115200 ;monitor_rts = 0 ;monitor_dtr = 0 diff --git a/test/TEST.cpp b/test/TEST.cpp deleted file mode 100644 index 2f4d6f7b..00000000 --- a/test/TEST.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include -#define NMEAGPS_PARSE_GGA -#define NMEAGPS_PARSE_GLL -#define NMEAGPS_PARSE_GSA -#define NMEAGPS_PARSE_GSV -#define NMEAGPS_PARSE_GST -#define NMEAGPS_PARSE_RMC -#define NMEAGPS_PARSE_VTG -#define NMEAGPS_PARSE_ZDA -#define NMEAGPS_PARSE_SATELLITES -#define NMEAGPS_PARSE_SATELLITE_INFO - -#include -#include "settings.hpp" -#include "tasks.hpp" -#include - -#define DEBUG_PORT Serial -#define gpsPort Serial2 -#define GPS_PORT_NAME "Serial2" - - - - -NMEAGPS GPS; // This parses the GPS characters -gps_fix fix; // This holds on to the latest values - - -#ifndef NMEAGPS_PARSE_GSV - #error You must define NMEAGPS_PARSE_GSV in NMEAGPS_cfg.h! -#endif - -#ifndef NMEAGPS_PARSE_SATELLITES - #error You must define NMEAGPS_PARSE_SATELLITE in NMEAGPS_cfg.h! -#endif - -#ifndef NMEAGPS_PARSE_SATELLITE_INFO - #error You must define NMEAGPS_PARSE_SATELLITE_INFO in NMEAGPS_cfg.h! -#endif - - -void displaySatellitesInView() -{ - DEBUG_PORT.print( GPS.sat_count ); - DEBUG_PORT.print( ',' ); - - for (uint8_t i=0; i < GPS.sat_count; i++) { - DEBUG_PORT.print( GPS.satellites[i].id ); - DEBUG_PORT.print( ' ' ); - DEBUG_PORT.print( GPS.satellites[i].elevation ); - DEBUG_PORT.print( '/' ); - DEBUG_PORT.print( GPS.satellites[i].azimuth ); - DEBUG_PORT.print( '@' ); - if (GPS.satellites[i].tracked) - DEBUG_PORT.print( GPS.satellites[i].snr ); - else - DEBUG_PORT.print( '-' ); - DEBUG_PORT.print( F(", ") ); - } - - DEBUG_PORT.println(); - -} // displaySatellitesInView - - - -//----------------- - -void setup() -{ - DEBUG_PORT.begin(115200); - - while (!DEBUG_PORT) - ; - - DEBUG_PORT.print( F("NeoGPS GSV example started\n") ); - - gpsPort.begin( 9600, SERIAL_8N1, 18, 17); - - initCLI(); - initCLITask(); - -} // setup - -//----------------- - -void loop() -{ - while (GPS.available( gpsPort )) { - fix = GPS.read(); - displaySatellitesInView(); - } - -} // loop - -//----------------- - diff --git a/test/skyview.cpp b/test/skyview.cpp new file mode 100644 index 00000000..ab429761 --- /dev/null +++ b/test/skyview.cpp @@ -0,0 +1,263 @@ +#include // Librería TFT_eSPI + +TFT_eSPI tft = TFT_eSPI(); // Crear el objeto para la pantalla TFT + +// Estructura para las coordenadas del satélite +struct SatPos { + int x; + int y; +}; + +// Dimensiones de la pantalla TFT y centro +const int SCREEN_WIDTH = 240; +const int SCREEN_HEIGHT = 240; +const int CENTER_X = SCREEN_WIDTH / 2; +const int CENTER_Y = SCREEN_HEIGHT / 2; +const int MAX_RADIUS = 100; // Radio máximo en función de la elevación máxima (ajustable) + +// Función para calcular la posición en pantalla de un satélite dado su elevación y azimut +SatPos getSatPos(uint8_t elev, uint16_t azim) { + SatPos pos; + + // Calcular el radio en función de la elevación: mayor elevación = más cerca del centro + int H = MAX_RADIUS * (90 - elev) / 90; // Escalar elevación a un rango de 0 a MAX_RADIUS + + // Convertir azimut y calcular coordenadas + pos.x = CENTER_X + H * sin(DEG2RAD(azim)); + pos.y = CENTER_Y - H * cos(DEG2RAD(azim)); // Se invierte Y para adaptarse al sistema de coordenadas de TFT + + return pos; +} + +void setup() { + tft.init(); + tft.setRotation(1); // Ajusta la rotación de la pantalla si es necesario + tft.fillScreen(TFT_BLACK); // Limpiar la pantalla + + // Dibuja círculos concéntricos para representar elevaciones (opcional) + tft.drawCircle(CENTER_X, CENTER_Y, MAX_RADIUS, TFT_WHITE); // Horizonte (0°) + tft.drawCircle(CENTER_X, CENTER_Y, MAX_RADIUS * 2 / 3, TFT_WHITE); // 30° de elevación + tft.drawCircle(CENTER_X, CENTER_Y, MAX_RADIUS / 3, TFT_WHITE); // 60° de elevación + tft.drawPixel(CENTER_X, CENTER_Y, TFT_WHITE); // Cénit (90°) + + // Ejemplo de uso de getSatPos con varios satélites + uint8_t elevaciones[] = {10, 20, 30, 40, 50, 60, 70, 80}; // Ejemplo de elevaciones + uint16_t azimuts[] = {0, 45, 90, 135, 180, 225, 270, 315}; // Ejemplo de azimuts + int numSatellites = sizeof(elevaciones) / sizeof(elevaciones[0]); + + for (int i = 0; i < numSatellites; i++) { + SatPos pos = getSatPos(elevaciones[i], azimuts[i]); + tft.fillCircle(pos.x, pos.y, 5, TFT_GREEN); // Dibujar satélite como un círculo verde + tft.setTextColor(TFT_WHITE); + tft.drawNumber(i + 1, pos.x + 6, pos.y - 6); // Etiqueta opcional con el número del satélite + } +} + +void loop() { + // Aquí puedes actualizar las posiciones de los satélites si tienes datos en tiempo real +} + + + + +//******************************************************************************* + +#include + +// Tamaño del canvas y centro +const int CANVAS_SIZE = 240; // Tamaño del canvas (asumimos que el display es cuadrado) +const int CENTER_X = CANVAS_SIZE / 2; +const int CENTER_Y = CANVAS_SIZE / 2; +const int MAX_RADIUS = 100; // Radio máximo para representar el horizonte (0° elevación) + +// Estructura para la posición de un satélite +struct SatPos { + int x; + int y; +}; + +// Función para calcular la posición en pantalla de un satélite dado su elevación y azimut +SatPos getSatPos(uint8_t elev, uint16_t azim) { + SatPos pos; + int H = MAX_RADIUS * (90 - elev) / 90; // Escalar elevación en un rango de 0 a MAX_RADIUS + pos.x = CENTER_X + H * sin(DEG2RAD(azim)); + pos.y = CENTER_Y - H * cos(DEG2RAD(azim)); // Invertir Y para el sistema de coordenadas de LVGL + return pos; +} + +void setup() { + lv_init(); + + // Inicializar el canvas + static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_SIZE, CANVAS_SIZE)]; + lv_obj_t *canvas = lv_canvas_create(lv_scr_act()); + lv_canvas_set_buffer(canvas, cbuf, CANVAS_SIZE, CANVAS_SIZE, LV_IMG_CF_TRUE_COLOR); + lv_canvas_fill_bg(canvas, LV_COLOR_BLACK, LV_OPA_COVER); // Fondo negro + + // Dibujar círculos de elevación en el canvas + lv_color_t circle_color = LV_COLOR_WHITE; + lv_canvas_draw_circle(canvas, CENTER_X, CENTER_Y, MAX_RADIUS, circle_color); // Horizonte (0° elevación) + lv_canvas_draw_circle(canvas, CENTER_X, CENTER_Y, MAX_RADIUS * 2 / 3, circle_color); // 30° elevación + lv_canvas_draw_circle(canvas, CENTER_X, CENTER_Y, MAX_RADIUS / 3, circle_color); // 60° elevación + lv_canvas_draw_pixel(canvas, CENTER_X, CENTER_Y, circle_color); // Cénit (90° elevación) + + // Datos de ejemplo: azimut y elevación de algunos satélites + uint8_t elevaciones[] = {10, 20, 30, 40, 50, 60, 70, 80}; // Elevación en grados + uint16_t azimuts[] = {0, 45, 90, 135, 180, 225, 270, 315}; // Azimut en grados + int numSatellites = sizeof(elevaciones) / sizeof(elevaciones[0]); + + // Dibujar satélites en el canvas + lv_color_t sat_color = LV_COLOR_GREEN; + for (int i = 0; i < numSatellites; i++) { + SatPos pos = getSatPos(elevaciones[i], azimuts[i]); + lv_canvas_draw_circle(canvas, pos.x, pos.y, 3, sat_color); // Dibuja el satélite como un pequeño círculo + } + + // Agregar etiquetas N, S, E, W para las direcciones + lv_style_t style_label; + lv_style_init(&style_label); + lv_style_set_text_color(&style_label, LV_STATE_DEFAULT, LV_COLOR_WHITE); + + // Etiqueta Norte (N) + lv_obj_t *label_n = lv_label_create(canvas); + lv_obj_add_style(label_n, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_n, "N"); + lv_obj_align(label_n, NULL, LV_ALIGN_CENTER, 0, -MAX_RADIUS - 10); // Posición hacia el norte + + // Etiqueta Sur (S) + lv_obj_t *label_s = lv_label_create(canvas); + lv_obj_add_style(label_s, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_s, "S"); + lv_obj_align(label_s, NULL, LV_ALIGN_CENTER, 0, MAX_RADIUS + 10); // Posición hacia el sur + + // Etiqueta Este (E) + lv_obj_t *label_e = lv_label_create(canvas); + lv_obj_add_style(label_e, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_e, "E"); + lv_obj_align(label_e, NULL, LV_ALIGN_CENTER, MAX_RADIUS + 10, 0); // Posición hacia el este + + // Etiqueta Oeste (W) + lv_obj_t *label_w = lv_label_create(canvas); + lv_obj_add_style(label_w, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_w, "W"); + lv_obj_align(label_w, NULL, LV_ALIGN_CENTER, -MAX_RADIUS - 10, 0); // Posición hacia el oeste + + // Opcional: Agregar etiquetas a los satélites + for (int i = 0; i < numSatellites; i++) { + SatPos pos = getSatPos(elevaciones[i], azimuts[i]); + lv_obj_t *label = lv_label_create(canvas); + lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text_fmt(label, "%d", i + 1); // Etiqueta con el número de satélite + lv_obj_align(label, NULL, LV_ALIGN_CENTER, pos.x - CENTER_X, pos.y - CENTER_Y); // Posicionar etiqueta + } +} + +void loop() { + lv_task_handler(); // Necesario para que LVGL maneje sus tareas + delay(5); // Pequeño retraso +} + + +/************************************************************************* */ + +#include + +// Tamaño del canvas y centro +const int CANVAS_SIZE = 240; // Tamaño del canvas (asumimos que el display es cuadrado) +const int CENTER_X = CANVAS_SIZE / 2; +const int CENTER_Y = CANVAS_SIZE / 2; +const int MAX_RADIUS = 100; // Radio máximo para representar el horizonte (0° elevación) + +// Estructura para la posición de un satélite +struct SatPos { + int x; + int y; +}; + +// Datos de ejemplo (podrías reemplazar estos arreglos por datos en tiempo real) +uint8_t elevaciones[] = {10, 20, 30, 40, 50, 60, 70, 80}; // Elevación en grados +uint16_t azimuts[] = {0, 45, 90, 135, 180, 225, 270, 315}; // Azimut en grados +int numSatellites = sizeof(elevaciones) / sizeof(elevaciones[0]); + +// Canvas de LVGL y su búfer +lv_obj_t *canvas; +static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_SIZE, CANVAS_SIZE)]; + +// Función para calcular la posición en pantalla de un satélite dado su elevación y azimut +SatPos getSatPos(uint8_t elev, uint16_t azim) { + SatPos pos; + int H = MAX_RADIUS * (90 - elev) / 90; // Escalar elevación en un rango de 0 a MAX_RADIUS + pos.x = CENTER_X + H * sin(DEG2RAD(azim)); + pos.y = CENTER_Y - H * cos(DEG2RAD(azim)); // Invertir Y para el sistema de coordenadas de LVGL + return pos; +} + +// Función para dibujar el gráfico completo en el canvas +void draw_skyview() { + // Limpiar el canvas (rellenar con color negro) + lv_canvas_fill_bg(canvas, LV_COLOR_BLACK, LV_OPA_COVER); + + // Dibujar círculos de elevación en el canvas + lv_color_t circle_color = LV_COLOR_WHITE; + lv_canvas_draw_circle(canvas, CENTER_X, CENTER_Y, MAX_RADIUS, circle_color); // Horizonte (0° elevación) + lv_canvas_draw_circle(canvas, CENTER_X, CENTER_Y, MAX_RADIUS * 2 / 3, circle_color); // 30° elevación + lv_canvas_draw_circle(canvas, CENTER_X, CENTER_Y, MAX_RADIUS / 3, circle_color); // 60° elevación + lv_canvas_draw_pixel(canvas, CENTER_X, CENTER_Y, circle_color); // Cénit (90° elevación) + + // Dibujar las etiquetas de dirección N, S, E, W + lv_style_t style_label; + lv_style_init(&style_label); + lv_style_set_text_color(&style_label, LV_STATE_DEFAULT, LV_COLOR_WHITE); + + // Norte (N) + lv_obj_t *label_n = lv_label_create(canvas); + lv_obj_add_style(label_n, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_n, "N"); + lv_obj_align(label_n, NULL, LV_ALIGN_CENTER, 0, -MAX_RADIUS - 10); + + // Sur (S) + lv_obj_t *label_s = lv_label_create(canvas); + lv_obj_add_style(label_s, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_s, "S"); + lv_obj_align(label_s, NULL, LV_ALIGN_CENTER, 0, MAX_RADIUS + 10); + + // Este (E) + lv_obj_t *label_e = lv_label_create(canvas); + lv_obj_add_style(label_e, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_e, "E"); + lv_obj_align(label_e, NULL, LV_ALIGN_CENTER, MAX_RADIUS + 10, 0); + + // Oeste (W) + lv_obj_t *label_w = lv_label_create(canvas); + lv_obj_add_style(label_w, LV_LABEL_PART_MAIN, &style_label); + lv_label_set_text(label_w, "W"); + lv_obj_align(label_w, NULL, LV_ALIGN_CENTER, -MAX_RADIUS - 10, 0); + + // Dibujar los satélites en el canvas en su posición actual + lv_color_t sat_color = LV_COLOR_GREEN; + for (int i = 0; i < numSatellites; i++) { + SatPos pos = getSatPos(elevaciones[i], azimuts[i]); + lv_canvas_draw_circle(canvas, pos.x, pos.y, 3, sat_color); // Dibuja el satélite como un pequeño círculo + } +} + +void setup() { + lv_init(); + + // Crear e inicializar el canvas + canvas = lv_canvas_create(lv_scr_act()); + lv_canvas_set_buffer(canvas, cbuf, CANVAS_SIZE, CANVAS_SIZE, LV_IMG_CF_TRUE_COLOR); + lv_obj_set_pos(canvas, 0, 0); // Colocar el canvas en la esquina superior izquierda +} + +void loop() { + // Actualizar las posiciones de los satélites (puedes usar datos en tiempo real aquí) + // Por ejemplo, podrías actualizar `elevaciones` y `azimuts` con datos nuevos + + // Llamar a la función que redibuja el skyview + draw_skyview(); + + // Deja que LVGL maneje sus tareas + lv_task_handler(); + delay(500); // Actualizar cada 500 ms +}