Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config on SD card - read/save, change meter resolution, add stats in lux_only mode #39

Merged
merged 26 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c5296d3
add Measurement Resolution setting
danielskowronski Feb 9, 2023
a638568
load settings on main_view enter, add peak lux stat
danielskowronski Feb 9, 2023
23e3303
very simple histogram
danielskowronski Feb 10, 2023
2957b1a
add todo for later
danielskowronski Feb 10, 2023
a8db978
save/read settings to SD card
danielskowronski Feb 16, 2023
af015f6
Merge branch 'main' into advanced-mode
danielskowronski Feb 16, 2023
1c23bfa
fix config path and button rendering
danielskowronski Feb 19, 2023
329eb0b
increase stack size
danielskowronski Feb 19, 2023
bd03dc2
proper `bh1750_set_mode` on app init
danielskowronski Feb 19, 2023
fda432c
add I2C addr selection, fix sensor init
danielskowronski Feb 20, 2023
5103462
Merge branch 'main' into advanced-mode
oleksiikutuzov Feb 22, 2023
7e96ce5
bump lib to origin
danielskowronski Feb 24, 2023
af99a09
inscreasing stack size to be safe
danielskowronski Feb 24, 2023
7998c32
Merge branch 'advanced-mode' of github.com:danielskowronski/flipperze…
danielskowronski Feb 24, 2023
0c0d0b9
Merge branch 'main' into advanced-mode
oleksiikutuzov Jul 19, 2023
7c47a51
Revert "Merge branch 'main' into advanced-mode"
oleksiikutuzov Jul 19, 2023
3b9598b
Fix conflicts
oleksiikutuzov Jul 20, 2023
5d284af
More files to the state of the main branch
oleksiikutuzov Jul 20, 2023
c14fffb
Fix formatting
oleksiikutuzov Jul 20, 2023
d2f7a24
Update changelog
oleksiikutuzov Jul 20, 2023
a32e3a4
Write sensor type to config, set address for MAX sensor
oleksiikutuzov Jul 20, 2023
dc664b7
Switching address for both sensors
oleksiikutuzov Jul 21, 2023
89746a6
Use shortcut for appdata folder, update changelog
oleksiikutuzov Jul 21, 2023
0d53820
Update license to current state
oleksiikutuzov Jul 21, 2023
692f746
Update docs
oleksiikutuzov Jul 21, 2023
7b89a59
Update screenshots
oleksiikutuzov Jul 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ SDA -> C1


## TODO
- [ ] Save settings to sd card
- [x] Save settings to sd card
- [ ] support different I2C addresses

## References
App inspired by [lightmeter](https://github.com/vpominchuk/lightmeter) project for Arduino by [vpominchuk](https://github.com/vpominchuk).
24 changes: 24 additions & 0 deletions application/gui/scenes/lightmeter_scene_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,19 @@ static const char* lux_only[] = {
[LUX_ONLY_ON] = "On",
};

static const char* measurement_resolution[] = {
[LOW_RES] = "Low",
[HIGH_RES] = "High",
[HIGH_RES2] = "High2",
};

enum LightMeterSubmenuIndex {
LightMeterSubmenuIndexISO,
LightMeterSubmenuIndexND,
LightMeterSubmenuIndexDome,
LightMeterSubmenuIndexBacklight,
LightMeterSubmenuIndexLuxMeter,
LightMeterSubmenuIndexMeasurementResolution,
LightMeterSubmenuIndexHelp,
LightMeterSubmenuIndexAbout,
};
Expand Down Expand Up @@ -127,6 +134,17 @@ static void lux_only_cb(VariableItem* item) {
lightmeter_app_set_config(app, config);
}

static void measurement_resolution_cb(VariableItem* item) {
LightMeterApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);

variable_item_set_current_value_text(item, measurement_resolution[index]);

LightMeterConfig* config = app->config;
config->measurement_resolution = index;
lightmeter_app_set_config(app, config);
}

static void ok_cb(void* context, uint32_t index) {
LightMeterApp* app = context;
UNUSED(app);
Expand Down Expand Up @@ -173,6 +191,11 @@ void lightmeter_scene_config_on_enter(void* context) {
variable_item_set_current_value_index(item, config->lux_only);
variable_item_set_current_value_text(item, lux_only[config->lux_only]);

item = variable_item_list_add(
var_item_list, "Resolution", COUNT_OF(measurement_resolution), measurement_resolution_cb, app);
variable_item_set_current_value_index(item, config->measurement_resolution);
variable_item_set_current_value_text(item, measurement_resolution[config->measurement_resolution]);

item = variable_item_list_add(var_item_list, "Help and Pinout", 0, NULL, NULL);
item = variable_item_list_add(var_item_list, "About", 0, NULL, NULL);

Expand Down Expand Up @@ -213,4 +236,5 @@ void lightmeter_scene_config_on_exit(void* context) {
main_view_set_nd(app->main_view, app->config->nd);
main_view_set_dome(app->main_view, app->config->dome);
main_view_set_lux_only(app->main_view, app->config->lux_only);
main_view_set_measurement_resolution(app->main_view, app->config->measurement_resolution);
}
7 changes: 7 additions & 0 deletions application/gui/scenes/lightmeter_scene_help.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ void lightmeter_scene_help_on_enter(void* context) {
" GND: GND\r\n"
" SDA: 15 [C1]\r\n"
" SCL: 16 [C0]\r\n");
furi_string_cat(temp_str, "\r\n\e#Resolutions:\r\n");
furi_string_cat(
temp_str,
"Low: 4.0lx (16ms, 0-54k)\r\n"
"High: 1.0lx (120ms, 0-54k)\r\n"
"High2: 0.5lx (120ms, 0-27k)\r\n"
);

widget_add_text_scroll_element(app->widget, 0, 0, 128, 64, furi_string_get_cstr(temp_str));
furi_string_free(temp_str);
Expand Down
19 changes: 18 additions & 1 deletion application/gui/scenes/lightmeter_scene_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,24 @@ static void lightmeter_scene_main_on_left(void* context) {
view_dispatcher_send_custom_event(app->view_dispatcher, LightMeterAppCustomEventConfig);
}

static void lightmeter_scene_main_on_right(void* context) {
LightMeterApp* app = context;

view_dispatcher_send_custom_event(app->view_dispatcher, LightMeterAppCustomEventReset);
}

void lightmeter_scene_main_on_enter(void* context) {
LightMeterApp* app = context;

variable_item_list_reset(app->var_item_list);
main_view_set_iso(app->main_view, app->config->iso);
main_view_set_nd(app->main_view, app->config->nd);
main_view_set_dome(app->main_view, app->config->dome);
main_view_set_lux_only(app->main_view, app->config->lux_only);
main_view_set_measurement_resolution(app->main_view, app->config->measurement_resolution);

lightmeter_main_view_set_left_callback(app->main_view, lightmeter_scene_main_on_left, app);
lightmeter_main_view_set_right_callback(app->main_view, lightmeter_scene_main_on_right, app);
view_dispatcher_switch_to_view(app->view_dispatcher, LightMeterAppViewMainView);
}

Expand All @@ -23,7 +37,10 @@ bool lightmeter_scene_main_on_event(void* context, SceneManagerEvent event) {
if(event.event == LightMeterAppCustomEventConfig) {
scene_manager_next_scene(app->scene_manager, LightMeterAppSceneConfig);
response = true;
}
} else if(event.event == LightMeterAppCustomEventReset) {
lightmeter_app_reset_callback(app);
response = true;
}
break;

case SceneManagerEventTypeTick:
Expand Down
79 changes: 76 additions & 3 deletions application/gui/views/main_view.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "main_view.h"
#include <math.h>
#include <furi.h>
#include <furi_hal.h>
#include <gui/elements.h>
Expand Down Expand Up @@ -72,6 +73,7 @@ const float speed_numbers[] = {
struct MainView {
View* view;
LightMeterMainViewButtonCallback cb_left;
LightMeterMainViewButtonCallback cb_right;
void* cb_context;
};

Expand All @@ -90,6 +92,21 @@ void lightmeter_main_view_set_left_callback(
true);
}

void lightmeter_main_view_set_right_callback(
MainView* lightmeter_main_view,
LightMeterMainViewButtonCallback callback,
void* context) {
with_view_model(
lightmeter_main_view->view,
MainViewModel * model,
{
UNUSED(model);
lightmeter_main_view->cb_right = callback;
lightmeter_main_view->cb_context = context;
},
true);
}

static void main_view_draw_callback(Canvas* canvas, void* context) {
furi_assert(context);
MainViewModel* model = context;
Expand All @@ -99,6 +116,7 @@ static void main_view_draw_callback(Canvas* canvas, void* context) {
// draw button
canvas_set_font(canvas, FontSecondary);
elements_button_left(canvas, "Config");
elements_button_right(canvas, "Reset");
danielskowronski marked this conversation as resolved.
Show resolved Hide resolved

if(!model->lux_only) {
// top row
Expand Down Expand Up @@ -190,6 +208,11 @@ static bool main_view_input_callback(InputEvent* event, void* context) {
main_view->cb_left(main_view->cb_context);
}
consumed = true;
} else if(event->type == InputTypeShort && event->key == InputKeyRight) {
if(main_view->cb_right) {
main_view->cb_right(main_view->cb_context);
}
consumed = true;
} else if(event->type == InputTypeShort && event->key == InputKeyBack) {
} else {
main_view_process(main_view, event);
Expand Down Expand Up @@ -224,9 +247,24 @@ View* main_view_get_view(MainView* main_view) {
void main_view_set_lux(MainView* main_view, float val) {
furi_assert(main_view);
with_view_model(
main_view->view, MainViewModel * model, { model->lux = val; }, true);
main_view->view, MainViewModel * model, {
model->lux = val;
model->peakLux = fmax(model->peakLux, val);

model->luxHistogram[ model->luxHistogramIndex++ ] = val;
model->luxHistogramIndex %= LUX_HISTORGRAM_LENGTH;
}, true);
}

void main_view_reset_lux(MainView* main_view) {
furi_assert(main_view);
with_view_model(
main_view->view, MainViewModel * model, {
model->peakLux = 0;
}, true);
}


void main_view_set_EV(MainView* main_view, float val) {
furi_assert(main_view);
with_view_model(
Expand Down Expand Up @@ -275,6 +313,24 @@ void main_view_set_lux_only(MainView* main_view, bool lux_only) {
main_view->view, MainViewModel * model, { model->lux_only = lux_only; }, true);
}

void main_view_set_measurement_resolution(MainView* main_view, int measurement_resolution) {
furi_assert(main_view);
with_view_model(
main_view->view, MainViewModel * model, { model->measurement_resolution = measurement_resolution; }, true);

switch (measurement_resolution) {
case LOW_RES:
bh1750_set_mode(ONETIME_LOW_RES_MODE);
break;
case HIGH_RES:
bh1750_set_mode(ONETIME_HIGH_RES_MODE);
break;
case HIGH_RES2:
bh1750_set_mode(ONETIME_HIGH_RES_MODE_2);
break;
}
}

bool main_view_get_dome(MainView* main_view) {
furi_assert(main_view);
bool val = false;
Expand Down Expand Up @@ -462,9 +518,26 @@ void draw_lux_only_mode(Canvas* canvas, MainViewModel* context) {

canvas_set_font(canvas, FontBigNumbers);
snprintf(str, sizeof(str), "%.0f", (double)model->lux);
canvas_draw_str_aligned(canvas, 80, 32, AlignRight, AlignCenter, str);
canvas_draw_str_aligned(canvas, 80, 22, AlignRight, AlignCenter, str);

canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 85, 39, AlignLeft, AlignBottom, "Lux");
canvas_draw_str_aligned(canvas, 85, 29, AlignLeft, AlignBottom, "Lux now");

canvas_set_font(canvas, FontPrimary);
snprintf(str, sizeof(str), "%.0f", (double)model->peakLux);
canvas_draw_str_aligned(canvas, 80, 39, AlignRight, AlignCenter, str);

canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 85, 43, AlignLeft, AlignBottom, "Lux peak");

for (int i=0; i<LUX_HISTORGRAM_LENGTH; i++){
float lux = model->luxHistogram[
(i + model->luxHistogramIndex) % LUX_HISTORGRAM_LENGTH ];
int barHeight = log10(lux) / log10(LUX_HISTORGRAM_LOGBASE);
canvas_draw_line(canvas,
LUX_HISTORGRAM_LEFT + i, LUX_HISTORGRAM_BOTTOM,
LUX_HISTORGRAM_LEFT + i, LUX_HISTORGRAM_BOTTOM - barHeight);
}

}
}
27 changes: 27 additions & 0 deletions application/gui/views/main_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
#include "lightmeter_icons.h"
#include "../../lightmeter_config.h"

/* log base 1.4 and 12 pixels cut off
makes it show values approx 65-65k
with reasonable resolution in 1-10k range
on 20px of screen height */
#define LUX_HISTORGRAM_LOGBASE 1.4
#define LUX_HISTORGRAM_BOTTOM 64+12

/* 40 pixels between 45th and 85th
between left and right button labels */
#define LUX_HISTORGRAM_LEFT 45
#define LUX_HISTORGRAM_LENGTH 40


typedef struct MainView MainView;

typedef enum {
Expand All @@ -17,6 +30,7 @@ typedef struct {
uint8_t recv[2];
MainViewMode current_mode;
float lux;
float peakLux;
float EV;
float aperture_val;
float speed_val;
Expand All @@ -28,6 +42,10 @@ typedef struct {
int speed;
bool dome;
bool lux_only;
int measurement_resolution;

float luxHistogram[LUX_HISTORGRAM_LENGTH];
int luxHistogramIndex;
} MainViewModel;

typedef void (*LightMeterMainViewButtonCallback)(void* context);
Expand All @@ -37,6 +55,11 @@ void lightmeter_main_view_set_left_callback(
LightMeterMainViewButtonCallback callback,
void* context);

void lightmeter_main_view_set_right_callback(
MainView* lightmeter_main_view,
LightMeterMainViewButtonCallback callback,
void* context);

MainView* main_view_alloc();

void main_view_free(MainView* main_view);
Expand All @@ -45,6 +68,8 @@ View* main_view_get_view(MainView* main_view);

void main_view_set_lux(MainView* main_view, float val);

void main_view_reset_lux(MainView* main_view);

void main_view_set_EV(MainView* main_view_, float val);

void main_view_set_response(MainView* main_view_, bool val);
Expand All @@ -61,6 +86,8 @@ void main_view_set_dome(MainView* main_view, bool val);

void main_view_set_lux_only(MainView* main_view, bool val);

void main_view_set_measurement_resolution(MainView* main_view, int val);

bool main_view_get_dome(MainView* main_view);

void draw_top_row(Canvas* canvas, MainViewModel* context);
Expand Down
42 changes: 42 additions & 0 deletions application/lightmeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,31 @@ LightMeterApp* lightmeter_app_alloc(uint32_t first_scene) {
app->config->aperture = DEFAULT_APERTURE;
app->config->dome = DEFAULT_DOME;
app->config->backlight = DEFAULT_BACKLIGHT;
app->config->measurement_resolution = HIGH_RES;
app->config->lux_only = LUX_ONLY_OFF;


// Records
app->gui = furi_record_open(RECORD_GUI);
app->storage = furi_record_open(RECORD_STORAGE);
app->notifications = furi_record_open(RECORD_NOTIFICATION);

app->cfg_path = furi_string_alloc();
furi_string_printf(app->cfg_path, "%s/%s", APP_PATH_DIR, APP_PATH_CFG);

FlipperFormat* cfg_fmt = flipper_format_file_alloc(app->storage);
if (flipper_format_file_open_existing(cfg_fmt, furi_string_get_cstr(app->cfg_path))) {
flipper_format_read_hex(cfg_fmt, "iso", &app->config->iso, 1);
flipper_format_read_hex(cfg_fmt, "nd", &app->config->nd, 1);
flipper_format_read_hex(cfg_fmt, "aperture", &app->config->aperture, 1);
flipper_format_read_hex(cfg_fmt, "dome", &app->config->dome, 1);
flipper_format_read_hex(cfg_fmt, "backlight", &app->config->backlight, 1);
flipper_format_read_hex(cfg_fmt, "measurement_resolution", &app->config->measurement_resolution, 1);
flipper_format_read_hex(cfg_fmt, "lux_only", &app->config->lux_only, 1);
}
flipper_format_free(cfg_fmt);


// View dispatcher
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&lightmeter_scene_handlers, app);
Expand Down Expand Up @@ -115,6 +135,7 @@ void lightmeter_app_free(LightMeterApp* app) {
app->notifications,
&sequence_display_backlight_enforce_auto); // set backlight back to auto
}
furi_record_close(RECORD_STORAGE);
furi_record_close(RECORD_NOTIFICATION);

bh1750_set_power_state(0);
Expand All @@ -136,6 +157,21 @@ void lightmeter_app_set_config(LightMeterApp* context, LightMeterConfig* config)
LightMeterApp* app = context;

app->config = config;
storage_common_mkdir(app->storage, APP_PATH_DIR);

FlipperFormat* cfg_fmt = flipper_format_file_alloc(app->storage);
if (flipper_format_file_open_always(cfg_fmt, furi_string_get_cstr(app->cfg_path))) {
flipper_format_write_header_cstr(cfg_fmt, "lightmeter", 1);

flipper_format_write_hex(cfg_fmt, "iso", &(app->config->iso), 1);
flipper_format_write_hex(cfg_fmt, "nd", &(app->config->nd), 1);
flipper_format_write_hex(cfg_fmt, "aperture", &(app->config->aperture), 1);
flipper_format_write_hex(cfg_fmt, "dome", &(app->config->dome), 1);
flipper_format_write_hex(cfg_fmt, "backlight", &(app->config->backlight), 1);
flipper_format_write_hex(cfg_fmt, "measurement_resolution", &(app->config->measurement_resolution), 1);
flipper_format_write_hex(cfg_fmt, "lux_only", &(app->config->lux_only), 1);
}
flipper_format_free(cfg_fmt);
}

void lightmeter_app_i2c_callback(LightMeterApp* context) {
Expand All @@ -159,3 +195,9 @@ void lightmeter_app_i2c_callback(LightMeterApp* context) {
main_view_set_EV(app->main_view, EV);
main_view_set_response(app->main_view, response);
}

void lightmeter_app_reset_callback(LightMeterApp* context){
LightMeterApp* app = context;

main_view_reset_lux(app->main_view);
}
Loading