diff --git a/data/turn.png b/data/turn.png new file mode 100644 index 00000000..af0e2c58 Binary files /dev/null and b/data/turn.png differ diff --git a/lib/lv_CUSTOMBOARD_conf.h b/lib/lv_CUSTOMBOARD_conf.h index 74ef1a98..34370fed 100644 --- a/lib/lv_CUSTOMBOARD_conf.h +++ b/lib/lv_CUSTOMBOARD_conf.h @@ -84,7 +84,7 @@ #define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ /*Input device read period in milliseconds*/ -#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/ +#define LV_INDEV_DEF_READ_PERIOD 60 /*[ms]*/ /*Use a custom tick source that tells the elapsed time in milliseconds. *It removes the need to manually update the tick with `lv_tick_inc()`)*/ diff --git a/platformio.ini b/platformio.ini index 50c25c7a..43629318 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,7 +16,7 @@ default_envs = CUSTOMBOARD platform = espressif32 framework = arduino version = 0.1.6 -revision = 35 +revision = 36 monitor_speed = 115200 monitor_rts = 0 monitor_dtr = 0 diff --git a/src/gui/screens/Main/events/main_scr.h b/src/gui/screens/Main/events/main_scr.h index 9a6a0498..be7673fa 100644 --- a/src/gui/screens/Main/events/main_scr.h +++ b/src/gui/screens/Main/events/main_scr.h @@ -132,7 +132,7 @@ static void update_main_screen(lv_timer_t *t) { case COMPASS: #ifdef ENABLE_COMPASS - heading = read_compass(); + heading = get_heading(); lv_event_send(compass_heading, LV_EVENT_VALUE_CHANGED, NULL); #endif diff --git a/src/gui/screens/Main/events/map.h b/src/gui/screens/Main/events/map.h index 88d64d15..57c1879f 100644 --- a/src/gui/screens/Main/events/map.h +++ b/src/gui/screens/Main/events/map.h @@ -191,7 +191,7 @@ static void update_map(lv_event_t *event) map_rot.pushSprite(0, 27); #ifdef ENABLE_COMPASS - heading = read_compass(); + heading = get_heading(); map_spr.pushRotated(&map_rot, 360 - heading, TFT_TRANSPARENT); map_rot.fillRectAlpha(TFT_WIDTH - 48, 0, 48, 48, 95, TFT_BLACK); map_rot.pushImageRotateZoom(TFT_WIDTH - 24, 24, 24, 24, 360 - heading, 1, 1, 48, 48, (uint16_t *)mini_compass, TFT_BLACK); diff --git a/src/gui/screens/Notify_Bar/events/notify_bar.h b/src/gui/screens/Notify_Bar/events/notify_bar.h index a3d2ba7d..57760597 100644 --- a/src/gui/screens/Notify_Bar/events/notify_bar.h +++ b/src/gui/screens/Notify_Bar/events/notify_bar.h @@ -38,22 +38,24 @@ static void update_batt(lv_event_t *event) */ static void update_fix_mode(lv_event_t *event) { - switch (atoi(fix_mode.value())) + lv_obj_t *mode = lv_event_get_target(event); + if (fix_mode.isValid()) { - case 1: - lv_label_set_text(gps_fix_mode, "--"); - lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", 0); - break; - case 2: - lv_label_set_text(gps_fix_mode, "2D"); - break; - case 3: - lv_label_set_text(gps_fix_mode, "3D"); - break; - default: - lv_label_set_text(gps_fix_mode, "--"); - lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", 0); - break; + switch (atoi(fix_mode.value())) + { + case 1: + lv_label_set_text(mode, "--"); + break; + case 2: + lv_label_set_text(mode, "2D"); + break; + case 3: + lv_label_set_text(mode, "3D"); + break; + default: + lv_label_set_text(mode, "--"); + break; + } } } @@ -77,7 +79,11 @@ static void update_time(lv_event_t *event) */ static void update_gps_count(lv_event_t *event) { - lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", GPS.satellites.value()); + lv_obj_t *gps_num = lv_event_get_target(event); + if (GPS.satellites.isValid()) + lv_label_set_text_fmt(gps_num, LV_SYMBOL_GPS "%2d", GPS.satellites.value()); + else + lv_label_set_text_fmt(gps_num, LV_SYMBOL_GPS "%2d", 0); } /** @@ -87,32 +93,8 @@ static void update_gps_count(lv_event_t *event) void update_notify_bar(lv_timer_t *t) { lv_event_send(gps_time, LV_EVENT_VALUE_CHANGED, NULL); - - lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", GPS.satellites.value()); - - switch (atoi(fix.value())) - { - case 0: - lv_led_off(gps_fix); - lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", 0); - break; - case 1: - lv_led_toggle(gps_fix); - break; - case 2: - lv_led_toggle(gps_fix); - break; - default: - lv_led_off(gps_fix); - lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", 0); - break; - } - - if (atoi(fix_mode.value()) != fix_mode_old) - { - lv_event_send(gps_fix_mode, LV_EVENT_VALUE_CHANGED, NULL); - fix_mode_old = atoi(fix_mode.value()); - } + lv_event_send(gps_count, LV_EVENT_VALUE_CHANGED, NULL); + lv_event_send(gps_fix_mode, LV_EVENT_VALUE_CHANGED, NULL); batt_level = battery_read(); if (batt_level != batt_level_old) diff --git a/src/gui/screens/Notify_Bar/notify_bar.h b/src/gui/screens/Notify_Bar/notify_bar.h index d93b840e..7318a4a6 100644 --- a/src/gui/screens/Notify_Bar/notify_bar.h +++ b/src/gui/screens/Notify_Bar/notify_bar.h @@ -65,13 +65,9 @@ void create_notify_bar() gps_count = lv_label_create(notifyBar); lv_label_set_text_fmt(gps_count, LV_SYMBOL_GPS "%2d", 0); + lv_obj_set_width(gps_count,40); lv_obj_add_event_cb(gps_count, update_gps_count, LV_EVENT_VALUE_CHANGED, NULL); - gps_fix = lv_led_create(notifyBar); - lv_led_set_color(gps_fix, lv_palette_main(LV_PALETTE_RED)); - lv_obj_set_size(gps_fix, 7, 7); - lv_led_off(gps_fix); - gps_fix_mode = lv_label_create(notifyBar); lv_obj_set_style_text_font(gps_fix_mode, &lv_font_montserrat_10, 0); lv_label_set_text(gps_fix_mode, "--"); diff --git a/src/gui/screens/Settings/events/settings_scr.h b/src/gui/screens/Settings/events/settings_scr.h index dc6e9d4c..064564e8 100644 --- a/src/gui/screens/Settings/events/settings_scr.h +++ b/src/gui/screens/Settings/events/settings_scr.h @@ -15,7 +15,7 @@ void load_main_screen(); */ static void back(lv_event_t *event) { - load_main_screen(); + load_main_screen(); } /** @@ -31,4 +31,17 @@ static void touch_calib(lv_event_t *event) REPEAT_CAL = false; is_main_screen = false; lv_scr_load(settingsScreen); +} + +/** + * @brief Compass Calibration + * + * @param event + */ +static void compass_calib(lv_event_t *event) +{ + tft.fillScreen(TFT_BLACK); + compass_calibrate(); + is_main_screen = false; + lv_scr_load(settingsScreen); } \ No newline at end of file diff --git a/src/gui/screens/Settings/settings_scr.h b/src/gui/screens/Settings/settings_scr.h index 7ae75aa4..b630c65f 100644 --- a/src/gui/screens/Settings/settings_scr.h +++ b/src/gui/screens/Settings/settings_scr.h @@ -29,6 +29,15 @@ void create_settings_scr() lv_obj_t *but_label; + // Compass Calibration + lv_obj_t *compass_calib_but = lv_btn_create(settingsScreen); + lv_obj_set_size(compass_calib_but, TFT_WIDTH - 30, 40); + but_label = lv_label_create(compass_calib_but); + lv_obj_set_style_text_font(but_label, &lv_font_montserrat_20, 0); + lv_label_set_text(but_label, "Compass Calibration"); + lv_obj_center(but_label); + lv_obj_add_event_cb(compass_calib_but, compass_calib, LV_EVENT_CLICKED, NULL); + // Touch Calibration lv_obj_t *touch_calib_but = lv_btn_create(settingsScreen); lv_obj_set_size(touch_calib_but, TFT_WIDTH - 30, 40); diff --git a/src/gui/screens/Splash/splash_scr.h b/src/gui/screens/Splash/splash_scr.h index a4df6047..13ec1dcf 100644 --- a/src/gui/screens/Splash/splash_scr.h +++ b/src/gui/screens/Splash/splash_scr.h @@ -12,6 +12,7 @@ */ void splash_scr() { + tft.fillScreen(TFT_BLACK); millis_actual = millis(); set_brightness(0); tft.drawPngFile(SPIFFS, PSTR("/BOOTLOGO.png"), (tft.width() / 2) - 150 , (tft.height() / 2) - 70); diff --git a/src/hardware/compass.h b/src/hardware/compass.h index 62dd5479..fbd6b878 100644 --- a/src/hardware/compass.h +++ b/src/hardware/compass.h @@ -19,6 +19,9 @@ Adafruit_HMC5883_Unified compass = Adafruit_HMC5883_Unified(12345); MPU9250 IMU(Wire, 0x68); #endif +#define COMPASS_CAL_TIME 16000 +static void save_compass_cal(float offset_x, float offset_y); + /** * @brief Magnetic declination * @@ -30,7 +33,7 @@ MPU9250 IMU(Wire, 0x68); float declinationAngle = 0.22; /** - * @brief Compass Heading Angle + * @brief Compass Heading Angle and Smooth factors * */ int heading = 0; @@ -40,16 +43,41 @@ float heading_previous = 0.0; #define SMOOTH_PREVIOUS_FACTOR 0.60 /** - * @brief Read compass data + * @brief Calibration variables * - * @return compass heading */ -int read_compass() +float minx, maxx, miny, maxy, offx = 0.0, offy = 0.0; + +/** + * @brief Init Compass + * + */ +void init_compass() { - float y = 0.0; - float x = 0.0; - float z = 0.0; +#ifdef CUSTOMBOARD + compass.begin(); +#endif +#ifdef MAKERF_ESP32S3 + int status = IMU.begin(); + if (status < 0) + { + log_e("IMU initialization unsuccessful"); + log_e("Check IMU wiring or try cycling power"); + log_e("Status: %i", status); + } +#endif +} + +/** + * @brief Read compass values + * + * @param x + * @param y + * @param z + */ +static void read_compass(float &x, float &y, float &z) +{ #ifdef CUSTOMBOARD sensors_event_t event; compass.getEvent(&event); @@ -64,11 +92,26 @@ int read_compass() y = IMU.getMagY_uT(); z = IMU.getMagZ_uT(); #endif - float heading_no_filter = atan2(y, x); +} + +/** + * @brief Get compass heading + * + * @return compass heading + */ +int get_heading() +{ + float y = 0.0; + float x = 0.0; + float z = 0.0; + + read_compass(x, y, z); + + float heading_no_filter = atan2(y - offy, x - offx); heading_no_filter += declinationAngle; heading_smooth = heading_no_filter; - //heading_smooth = (heading_no_filter * SMOOTH_FACTOR) + (heading_previous * SMOOTH_PREVIOUS_FACTOR); - //heading_previous = heading_smooth; + // heading_smooth = (heading_no_filter * SMOOTH_FACTOR) + (heading_previous * SMOOTH_PREVIOUS_FACTOR); + // heading_previous = heading_smooth; if (heading_smooth < 0) heading_smooth += 2 * M_PI; @@ -77,19 +120,71 @@ int read_compass() return (int)(heading_smooth * 180 / M_PI); } -void init_compass() +/** + * @brief Compass calibration + * + */ +static void compass_calibrate() { + bool cal = 1; + float y = 0.0; + float x = 0.0; + float z = 0.0; + uint16_t touchX, touchY; -#ifdef CUSTOMBOARD - compass.begin(); -#endif -#ifdef MAKERF_ESP32S3 - int status = IMU.begin(); - if (status < 0) + tft.drawCenterString("ROTATE THE DEVICE", 160, 10, &fonts::DejaVu18); + tft.drawPngFile(SPIFFS, PSTR("/turn.png"), (tft.width() / 2) - 50, 60); + tft.drawCenterString("TOUCH TO START", 160, 200, &fonts::DejaVu18); + tft.drawCenterString("COMPASS CALIBRATION", 160, 230, &fonts::DejaVu18); + + while (!tft.getTouch(&touchX, &touchY)) { - log_e("IMU initialization unsuccessful"); - log_e("Check IMU wiring or try cycling power"); - log_e("Status: %i", status); + }; + delay(1000); + + unsigned long calTimeWas = millis(); + + read_compass(x, y, z); + + maxx = minx = x; // Set initial values to current magnetometer readings. + maxy = miny = y; + + while (cal) + { + + read_compass(x, y, z); + + if (x > maxx) + maxx = x; + if (x < minx) + minx = x; + if (y > maxy) + maxy = y; + if (y < miny) + miny = y; + + int secmillis = millis() - calTimeWas; + int secs = (int)((COMPASS_CAL_TIME - secmillis + 1000) / 1000); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.setTextSize(3); + tft.setTextPadding(tft.textWidth("88")); + tft.drawNumber((COMPASS_CAL_TIME - secmillis) / 1000, (tft.width() >> 1), 280); + + if (secs == 0) + { + offx = (maxx + minx) / 2; + offy = (maxy + miny) / 2; + cal = 0; + } } -#endif -} + + tft.setTextSize(1); + tft.drawCenterString("DONE!", 160, 340, &fonts::DejaVu40); + tft.drawCenterString("TOUCH TO CONTINUE.", 160, 380, &fonts::DejaVu18); + + while (!tft.getTouch(&touchX, &touchY)) + { + }; + + save_compass_cal(offx,offy); +} \ No newline at end of file diff --git a/src/hardware/gps.h b/src/hardware/gps.h index a072b460..cbf90fab 100644 --- a/src/hardware/gps.h +++ b/src/hardware/gps.h @@ -14,7 +14,6 @@ HardwareSerial *gps = &Serial2; TinyGPSPlus GPS; bool is_gps_fixed = false; -uint8_t fix_mode_old = 0; uint8_t fix_old = 0; /** @@ -42,7 +41,6 @@ struct GSV TinyGPSCustom pdop(GPS, PSTR("GNGSA"), 15); // $GNGSA sentence, 15th element TinyGPSCustom hdop(GPS, PSTR("GNGSA"), 16); // $GNGSA sentence, 16th element TinyGPSCustom vdop(GPS, PSTR("GNGSA"), 17); // $GNGSA sentence, 17th element -TinyGPSCustom fix(GPS, PSTR("GNGGA"), 6); TinyGPSCustom fix_mode(GPS, PSTR("GNGSA"), 2); // GPS Satellites in view @@ -60,7 +58,6 @@ GSV BD_GSV; TinyGPSCustom pdop(GPS, PSTR("GPGSA"), 15); // $GPGSA sentence, 15th element TinyGPSCustom hdop(GPS, PSTR("GPGSA"), 16); // $GPGSA sentence, 16th element TinyGPSCustom vdop(GPS, PSTR("GPGSA"), 17); // $GPGSA sentence, 17th element -TinyGPSCustom fix(GPS, PSTR("GPGGA"), 6); TinyGPSCustom fix_mode(GPS, PSTR("GPGSA"), 2); // GPS Satellites in view diff --git a/src/hardware/tft.h b/src/hardware/tft.h index 43aee5ee..6ab91367 100644 --- a/src/hardware/tft.h +++ b/src/hardware/tft.h @@ -21,7 +21,6 @@ uint8_t brightness_level = 255; static TFT_eSPI tft; #define LVGL_BKG 0x10A3 - /** * @brief Set the TFT brightness * @@ -97,10 +96,11 @@ void touch_calibrate() tft.setTouchCalibrate(calData); else { - tft.drawString("TOUCH THE ARROW MARKER.", 10, tft.height()>>1, &fonts::DejaVu18); + tft.drawCenterString("TOUCH THE ARROW MARKER.", 160, tft.height() >> 1, &fonts::DejaVu18); tft.calibrateTouch(calData, TFT_WHITE, TFT_BLACK, std::max(tft.width(), tft.height()) >> 3); - tft.drawString("DONE!",90, (tft.height()>>1)+30,&fonts::DejaVu40); + tft.drawCenterString("DONE!", 160, (tft.height() >> 1) + 30, &fonts::DejaVu40); delay(500); + tft.drawCenterString("TOUCH TO CONTINUE.", 160, (tft.height() >> 1) + 100, &fonts::DejaVu18); File f = SPIFFS.open(CALIBRATION_FILE, "w"); if (f) @@ -108,6 +108,11 @@ void touch_calibrate() f.write((const unsigned char *)calData, 16); f.close(); } + + uint16_t touchX, touchY; + while (!tft.getTouch(&touchX, &touchY)) + { + }; } } diff --git a/src/main.cpp b/src/main.cpp index 428ee27b..e611b00e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ unsigned long millis_actual = 0; #include "utils/lv_spiffs_fs.h" #include "utils/lv_sd_fs.h" #include "utils/time_zone.h" +#include "utils/preferences.h" #include "gui/lvgl.h" #include "tasks.h" @@ -67,6 +68,7 @@ void setup() init_serial(); #endif powerOn(); + load_preferences(); init_sd(); init_SPIFFS(); init_LVGL(); @@ -78,7 +80,7 @@ void setup() map_spr.createSprite(768, 768); splash_scr(); - init_tasks(); + // init_tasks(); #ifdef DEFAULT_LAT load_main_screen(); @@ -98,15 +100,14 @@ void loop() lv_tick_inc(5); #endif lv_timer_handler(); -// while (gps->available() > 0) -// { -// #ifdef OUTPUT_NMEA -// { -// debug->write(gps->read()); -// } -// #else -// GPS.encode(gps->read()); -// vTaskDelay(10); -// #endif -// } + while (gps->available()>0) + { +#ifdef OUTPUT_NMEA + { + debug->write(gps->read()); + } +#else + GPS.encode(gps->read()); +#endif + } } diff --git a/src/tasks.h b/src/tasks.h index ca6ad302..b25e6c97 100644 --- a/src/tasks.h +++ b/src/tasks.h @@ -25,7 +25,7 @@ void Read_GPS(void *pvParameters) } #else GPS.encode(gps->read()); - vTaskDelay(5); + vTaskDelay(10); #endif } @@ -42,7 +42,7 @@ void LVGL_Task(void *pvParameters) log_v("Task2 - LVGL Task - running on core %d", xPortGetCoreID()); for (;;) { - vTaskDelay(5); + vTaskDelay(10); // lv_tick_inc(5); } } @@ -53,7 +53,7 @@ void LVGL_Task(void *pvParameters) */ void init_tasks() { - xTaskCreatePinnedToCore(Read_GPS, PSTR("Read GPS"), 19000, NULL, 2, NULL, 1); + xTaskCreatePinnedToCore(Read_GPS, PSTR("Read GPS"), 20000, NULL, 3, NULL, 1); delay(500); //xTaskCreatePinnedToCore(LVGL_Task, PSTR("LVGL Task"), 20000, NULL, 1, NULL, 1); //delay(500); diff --git a/src/utils/preferences.h b/src/utils/preferences.h new file mode 100644 index 00000000..2832ba14 --- /dev/null +++ b/src/utils/preferences.h @@ -0,0 +1,39 @@ +/** + * @file preferences.h + * @author Jordi Gauchía (jgauchia@jgauchia.com) + * @brief Preferences functions + * @version 0.1.6 + * @date 2023-06-14 + */ + +#include + +Preferences preferences; + +/** + * @brief Load stored preferences + * + */ +static void load_preferences() +{ + preferences.begin("ICENAV",false); + offx = preferences.getFloat("C_offset_x",0.0); + offy = preferences.getFloat("C_offset_y",0.0); + log_v("OFFSET X %f",offx); + log_v("OFFSET Y %f",offy); + preferences.end(); +} + +/** + * @brief Save current compass calibration in preferences + * + * @param offset_x + * @param offset_y + */ +static void save_compass_cal(float offset_x, float offset_y) +{ + preferences.begin("ICENAV",false); + preferences.putFloat("C_offset_x",offset_x); + preferences.putFloat("C_offset_y",offset_y); + preferences.end(); +} \ No newline at end of file