Skip to content

Commit

Permalink
Merge pull request #155 from jakkra/jakkra_magnetometer_calib
Browse files Browse the repository at this point in the history
Store magnetometer calibration in flash
  • Loading branch information
Kampi authored Nov 26, 2023
2 parents 8b2d33b + 40b6b8e commit 06f412b
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 16 deletions.
16 changes: 11 additions & 5 deletions app/src/applications/compass/compass_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ static void compass_app_stop(void);

// Functions related to app functionality
static void timer_callback(lv_timer_t *timer);
static void on_start_calibration(void);

LV_IMG_DECLARE(move);

Expand All @@ -31,13 +32,9 @@ static uint32_t cal_start_ms;

static void compass_app_start(lv_obj_t *root, lv_group_t *group)
{
compass_ui_show(root);
compass_ui_show(root, on_start_calibration);
refresh_timer = lv_timer_create(timer_callback, CONFIG_DEFAULT_CONFIGURATION_COMPASS_REFRESH_INTERVAL_MS, NULL);
zsw_magnetometer_set_enable(true);
zsw_magnetometer_start_calibration();
is_calibrating = true;
cal_start_ms = lv_tick_get();
zsw_popup_show("Calibration", "Spin around 360 degrees for 10.", NULL, 100, false);
}

static void compass_app_stop(void)
Expand All @@ -51,6 +48,15 @@ static void compass_app_stop(void)
}
}

static void on_start_calibration(void)
{
zsw_magnetometer_start_calibration();
is_calibrating = true;
cal_start_ms = lv_tick_get();
zsw_popup_show("Calibration",
"Spin the watch around 360 degrees\nand do some random rotations in 3D space for 10 seconds.", NULL, 10, false);
}

static void timer_callback(lv_timer_t *timer)
{
if (is_calibrating &&
Expand Down
26 changes: 25 additions & 1 deletion app/src/applications/compass/compass_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,20 @@ static lv_obj_t *compass_panel;
static lv_obj_t *compass_img;
static lv_obj_t *compass_label;

static on_start_calibraion_cb_t start_cal;

static void calibrate_button_event_cb(lv_event_t *e)
{
if (start_cal) {
start_cal();
}
}

static void create_ui(lv_obj_t *parent)
{
lv_obj_t *cal_btn;
lv_obj_t *cal_btn_label;

LV_IMG_DECLARE(cardinal_point)
compass_panel = lv_obj_create(parent);
lv_obj_set_width(compass_panel, 240);
Expand All @@ -19,6 +31,16 @@ static void create_ui(lv_obj_t *parent)
lv_obj_set_style_bg_opa(compass_panel, LV_OPA_TRANSP, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_width(compass_panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT);

cal_btn = lv_btn_create(compass_panel);
lv_obj_set_style_pad_all(cal_btn, 3, LV_PART_MAIN);
lv_obj_set_align(cal_btn, LV_ALIGN_CENTER);
lv_obj_set_pos(cal_btn, 0, 80);
lv_obj_set_size(cal_btn, 70, 25);
lv_obj_set_style_bg_color(cal_btn, lv_palette_main(LV_PALETTE_ORANGE), LV_PART_MAIN | LV_STATE_DEFAULT);
cal_btn_label = lv_label_create(cal_btn);
lv_label_set_text(cal_btn_label, "Calibrate");
lv_obj_add_event_cb(cal_btn, calibrate_button_event_cb, LV_EVENT_CLICKED, NULL);

compass_img = lv_img_create(compass_panel);
lv_img_set_src(compass_img, &cardinal_point);
lv_obj_set_width(compass_img, LV_SIZE_CONTENT);
Expand All @@ -36,7 +58,7 @@ static void create_ui(lv_obj_t *parent)
lv_obj_set_style_text_opa(compass_label, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
}

void compass_ui_show(lv_obj_t *root)
void compass_ui_show(lv_obj_t *root, on_start_calibraion_cb_t start_cal_cb)
{
assert(root_page == NULL);

Expand All @@ -48,6 +70,8 @@ void compass_ui_show(lv_obj_t *root)
lv_obj_set_size(root_page, LV_PCT(100), LV_PCT(100));
lv_obj_clear_flag(root_page, LV_OBJ_FLAG_SCROLLABLE);

start_cal = start_cal_cb;

create_ui(root_page);
}

Expand Down
4 changes: 3 additions & 1 deletion app/src/applications/compass/compass_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include <inttypes.h>
#include <lvgl.h>

void compass_ui_show(lv_obj_t *root);
typedef void(*on_start_calibraion_cb_t)(void);

void compass_ui_show(lv_obj_t *root, on_start_calibraion_cb_t start_cal_cb);

void compass_ui_remove(void);

Expand Down
57 changes: 48 additions & 9 deletions app/src/sensors/zsw_magnetometer.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/settings/settings.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
Expand All @@ -19,6 +20,16 @@ LOG_MODULE_REGISTER(zsw_magnetometer, CONFIG_ZSW_SENSORS_LOG_LEVEL);
#define M_PI 3.14159265358979323846
#endif

#define SETTINGS_NAME_MAGN "magn"
#define SETTINGS_KEY_CALIB "calibr"
#define SETTINGS_MAGN_CALIB SETTINGS_NAME_MAGN "/" SETTINGS_KEY_CALIB

typedef struct {
float offset_x;
float offset_y;
float offset_z;
} magn_calib_data_t;

static double last_heading;
static double last_x;
static double last_y;
Expand All @@ -30,9 +41,7 @@ static double min_x;
static double min_y;
static double min_z;
static bool is_calibrating;
static float offset_x;
static float offset_y;
static float offset_z;
static magn_calib_data_t calibration_data;

static void zbus_periodic_slow_callback(const struct zbus_channel *chan);

Expand Down Expand Up @@ -116,22 +125,50 @@ static void lis2mdl_trigger_handler(const struct device *dev,
}
}

last_x = last_x - offset_x;
last_y = last_y - offset_y;
last_z = last_z - offset_z;
last_x = last_x - calibration_data.offset_x;
last_y = last_y - calibration_data.offset_y;
last_z = last_z - calibration_data.offset_z;

last_heading = xyz_to_rotation(last_x, last_y, last_z);

LOG_DBG("Rotation: %f", last_heading);
}

static int magn_cal_load(const char *p_key, size_t len,
settings_read_cb read_cb, void *p_cb_arg, void *p_param)
{
ARG_UNUSED(p_key);

if (len != sizeof(magn_calib_data_t)) {
LOG_ERR("Invalid length of magn calibration data");
return -EINVAL;
}

if (read_cb(p_cb_arg, &calibration_data, len) != sizeof(magn_calib_data_t)) {
LOG_ERR("Error reading magn calibration data");
return -EIO;
}

return 0;
}

int zsw_magnetometer_init(void)
{
if (!device_is_ready(magnetometer)) {
LOG_ERR("Device magnetometer is not ready");
return -ENODEV;
}

if (settings_subsys_init()) {
LOG_ERR("Error during settings_subsys_init!");
return -EFAULT;
}

if (settings_load_subtree_direct(SETTINGS_MAGN_CALIB, magn_cal_load, NULL)) {
LOG_ERR("Error during settings_load_subtree!");
return -EFAULT;
}

struct sensor_trigger trig;
struct sensor_value odr_attr;

Expand Down Expand Up @@ -205,9 +242,11 @@ int zsw_magnetometer_stop_calibration(void)
}

is_calibrating = false;
offset_x = (max_x + min_x) / 2;
offset_y = (max_y + min_y) / 2;
offset_z = (max_z + min_z) / 2;
calibration_data.offset_x = (max_x + min_x) / 2;
calibration_data.offset_y = (max_y + min_y) / 2;
calibration_data.offset_z = (max_z + min_z) / 2;

settings_save_one(SETTINGS_MAGN_CALIB, &calibration_data, sizeof(magn_calib_data_t));

return 0;
}
Expand Down

0 comments on commit 06f412b

Please sign in to comment.