Skip to content

Commit

Permalink
Add support for v1.1 GPS unit. (#156)
Browse files Browse the repository at this point in the history
* Add support for v1.1 GPS unit.

Add a setting for the GPS unit baud rate, defaults to 9600 (the old EOL)
unit.
The new (v1.1) unit runs at 115200.

Also, add the GPS time age to the 'GPS Data' output.
Update the GPS service interval to 50ms, to support the faster unit (may
need to convert this to a FreeRTOS task/queue).

Whilst here, refactor a bit of GPS handling.

* Update README for GPS baud setting.
  • Loading branch information
gkoh authored Jan 5, 2025
1 parent 817be37 commit 87c6e47
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 9 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,18 @@ Connection to mobile devices is a little iffy:

### GPS Location Tagging

> [!WARNING]
> This unit is EOL, support for the replacement is pending (see #141).
For Fujifilm cameras, location tagging is supported with the M5Stack GPS unit:
- [GPS/BDS Unit v1.1 (AT6668)](https://shop.m5stack.com/products/gps-bds-unit-v1-1-at6668)

The previous unit is now EOL:
- [Mini GPS/BDS Unit](https://shop.m5stack.com/products/mini-gps-bds-unit)

GPS support can be enabled in `furble` in `Settings->GPS`, the camera must also be configured to request location data.

The default baud rate for the GPS unit is 9600.
The new v1.1 unit runs at a higher baud rate and must be configured under
`Settings->GPS->GPS baud 115200` for correct operation.

### Intervalometer

The intervalometer can be configured via three settings in `Settings->Intervalometer`:
Expand Down
9 changes: 7 additions & 2 deletions include/FurbleGPS.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef FURBLE_GPS_H
#define FURBLE_GPS_H

#include <HardwareSerial.h>

#include <lvgl.h>

#include <TinyGPS++.h>
Expand Down Expand Up @@ -28,19 +30,22 @@ class GPS {
private:
GPS() {};

static constexpr const uint32_t BAUD = 9600;
static constexpr const size_t BUFFER_SIZE = 64;

#if FURBLE_GROVE_CORE
static constexpr const int8_t RX = 22;
static constexpr const int8_t TX = 21;
#else
static constexpr const int8_t RX = 33;
static constexpr const int8_t TX = 32;
#endif
static constexpr const uint16_t SERVICE_MS = 250;
static constexpr const uint16_t SERVICE_MS = 25;
static constexpr const uint32_t MAX_AGE_MS = 60 * 1000;

void serviceSerial(void);

HardwareSerial m_SerialPort = HardwareSerial(2);

lv_obj_t *m_Icon = NULL;
lv_timer_t *m_Timer = NULL;

Expand Down
4 changes: 4 additions & 0 deletions include/FurbleSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Settings {
THEME,
TX_POWER,
GPS,
GPS_BAUD,
INTERVAL,
MULTICONNECT,
RECONNECT,
Expand All @@ -32,6 +33,9 @@ class Settings {
const char *nvs_namespace;
} setting_t;

static const uint32_t BAUD_9600 = 9600;
static const uint32_t BAUD_115200 = 115200;

static void init(void);

static const setting_t &get(type_t);
Expand Down
1 change: 1 addition & 0 deletions include/FurbleUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class UI {
lv_obj_t *gpsIcon;
lv_obj_t *batteryIcon;
lv_obj_t *reconnectIcon;
lv_obj_t *gpsBaud;
lv_obj_t *gpsData;
bool screenLocked;
} status_t;
Expand Down
18 changes: 14 additions & 4 deletions src/FurbleGPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ GPS &GPS::getInstance() {
}

void GPS::init(void) {
Serial2.begin(BAUD, SERIAL_8N1, RX, TX);

getInstance().reloadSetting();
}

Expand All @@ -27,6 +25,10 @@ void GPS::setIcon(lv_obj_t *icon) {
/** Refresh the setting from NVS. */
void GPS::reloadSetting(void) {
m_Enabled = Settings::load<bool>(Settings::GPS);
if (m_Enabled) {
uint32_t baud = Settings::load<uint32_t>(Settings::GPS_BAUD);
m_SerialPort.begin(baud, SERIAL_8N1, RX, TX);
}
}

/** Is GPS enabled? */
Expand Down Expand Up @@ -69,12 +71,20 @@ void GPS::update(void) {

/** Read and decode the GPS data from serial port. */
void GPS::serviceSerial(void) {
static std::array<uint8_t, BUFFER_SIZE> buffer;

if (!m_Enabled) {
return;
}

while (Serial2.available() > 0) {
m_GPS.encode(Serial2.read());
size_t available = m_SerialPort.available();
if (available > 0) {
size_t bytes = m_SerialPort.readBytes(buffer.data(), std::min(buffer.size(), available));
ESP_LOGI("gps", "bytes = %u", bytes);

for (size_t i = 0; i < bytes; i++) {
m_GPS.encode(buffer[i]);
}
}

if ((m_GPS.location.age() < MAX_AGE_MS) && m_GPS.location.isValid()
Expand Down
24 changes: 24 additions & 0 deletions src/FurbleSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
namespace Furble {
Preferences Settings::m_Prefs;

const uint32_t Settings::BAUD_9600;

const std::unordered_map<Settings::type_t, Settings::setting_t> Settings::m_Setting = {
{BRIGHTNESS, {BRIGHTNESS, "Brightness", "brightness", "M5ez"} },
{INACTIVITY, {INACTIVITY, "Inactivity", "inactivity", "M5ez"} },
{THEME, {THEME, "Theme", "theme", "M5ez"} },
{TX_POWER, {TX_POWER, "TX Power", "tx_power", FURBLE_STR} },
{GPS, {GPS, "GPS", "gps", FURBLE_STR} },
{GPS_BAUD, {GPS_BAUD, "GPS Baud", "gps_baud", FURBLE_STR} },
{INTERVAL, {INTERVAL, "Interval", "interval", FURBLE_STR} },
{MULTICONNECT, {MULTICONNECT, "Multi-Connect", "multiconnect", FURBLE_STR}},
{RECONNECT, {RECONNECT, "Infinite-ReConnect", "reconnect", FURBLE_STR} },
Expand Down Expand Up @@ -43,6 +46,16 @@ uint8_t Settings::load<uint8_t>(type_t type) {
return value;
}

template <>
uint32_t Settings::load<uint32_t>(type_t type) {
const auto &setting = get(type);
m_Prefs.begin(setting.nvs_namespace, true);
uint32_t value = m_Prefs.getUInt(setting.key);
m_Prefs.end();

return value;
}

template <>
std::string Settings::load<std::string>(type_t type) {
const auto &setting = get(type);
Expand Down Expand Up @@ -106,6 +119,14 @@ void Settings::save<uint8_t>(const type_t type, const uint8_t &value) {
m_Prefs.end();
}

template <>
void Settings::save<uint32_t>(const type_t type, const uint32_t &value) {
const auto &setting = get(type);
m_Prefs.begin(setting.nvs_namespace, false);
m_Prefs.putUInt(setting.key, value);
m_Prefs.end();
}

template <>
void Settings::save<interval_t>(const type_t type, const interval_t &value) {
const auto &setting = get(type);
Expand Down Expand Up @@ -155,6 +176,9 @@ void Settings::init(void) {
case FAUXNY:
save<bool>(setting.type, false);
break;
case GPS_BAUD:
save<uint32_t>(setting.type, BAUD_9600);
break;
}
}
m_Prefs.end();
Expand Down
41 changes: 41 additions & 0 deletions src/FurbleUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,10 @@ void UI::addSettingItem(lv_obj_t *page, const char *symbol, Settings::type_t set
auto *status = static_cast<status_t *>(lv_event_get_user_data(e));
status->gps->reloadSetting();
if (status->gps->isEnabled()) {
lv_obj_clear_flag(status->gpsBaud, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(status->gpsData, LV_OBJ_FLAG_HIDDEN);
} else {
lv_obj_add_flag(status->gpsBaud, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(status->gpsData, LV_OBJ_FLAG_HIDDEN);
}
},
Expand Down Expand Up @@ -1294,9 +1296,38 @@ void UI::addGPSMenu(const menu_t &parent) {
addSettingItem(menu.page, NULL, Settings::GPS);
lv_menu_set_load_page_event(menu.main, menu.button, menu.page);

// add GPS baud control
m_Status.gpsBaud = lv_menu_cont_create(menu.page);
lv_obj_set_flex_flow(m_Status.gpsBaud, LV_FLEX_FLOW_ROW_WRAP);
lv_obj_t *label = lv_label_create(m_Status.gpsBaud);
lv_label_set_text(label, "GPS baud 115200");
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_flex_grow(label, 1);

lv_obj_t *baud_sw = lv_switch_create(m_Status.gpsBaud);
uint32_t baud = Settings::load<uint32_t>(Settings::GPS_BAUD);
lv_obj_add_state(baud_sw, baud == Settings::BAUD_115200 ? LV_STATE_CHECKED : 0);
lv_obj_add_event_cb(
baud_sw,
[](lv_event_t *e) {
auto *status = static_cast<status_t *>(lv_event_get_user_data(e));
lv_obj_t *baud_sw = static_cast<lv_obj_t *>(lv_event_get_target(e));
uint32_t baud;

if (lv_obj_has_state(baud_sw, LV_STATE_CHECKED)) {
baud = Settings::BAUD_115200;
} else {
baud = Settings::BAUD_9600;
}
Settings::save<uint32_t>(Settings::GPS_BAUD, baud);
status->gps->reloadSetting();
},
LV_EVENT_VALUE_CHANGED, &m_Status);

menu_t &gpsData = addMenu(m_GPSDataStr, NULL, true, menu);
m_Status.gpsData = gpsData.button;
if (!m_Status.gps->isEnabled()) {
lv_obj_add_flag(m_Status.gpsBaud, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(m_Status.gpsData, LV_OBJ_FLAG_HIDDEN);
}

Expand All @@ -1308,6 +1339,9 @@ void UI::addGPSMenu(const menu_t &parent) {
lv_label_set_text_fmt(valid, "%s (%u)", gps.location.isValid() ? "Valid" : "Invalid",
gps.satellites.value());

static lv_obj_t *age = lv_label_create(gpsData->page);
lv_label_set_text_fmt(age, "%us ago", gps.time.age() / 1000);

static lv_obj_t *lat = lv_label_create(gpsData->page);
lv_label_set_text_fmt(lat, "%.2f°", gps.location.lat());

Expand All @@ -1317,12 +1351,19 @@ void UI::addGPSMenu(const menu_t &parent) {
static lv_obj_t *alt = lv_label_create(gpsData->page);
lv_label_set_text_fmt(alt, "%.2f m", gps.altitude.meters());

#if defined(FURBLE_M5COREX)
static lv_obj_t *datetime = lv_label_create(gpsData->page);
lv_label_set_text_fmt(datetime, "%4u-%02u-%02u %02u:%02u:%02u", gps.date.year(),
gps.date.month(), gps.date.day(), gps.time.hour(), gps.time.minute(),
gps.time.second());
#else
static lv_obj_t *date = lv_label_create(gpsData->page);
lv_label_set_text_fmt(date, "%4u-%02u-%02u", gps.date.year(), gps.date.month(),
gps.date.day());
static lv_obj_t *time = lv_label_create(gpsData->page);
lv_label_set_text_fmt(time, "%02u:%02u:%02u", gps.time.hour(), gps.time.minute(),
gps.time.second());
#endif
},
1000, &gpsData);
lv_timer_pause(timer);
Expand Down

0 comments on commit 87c6e47

Please sign in to comment.