diff --git a/applications/external/lightmeter/README.md b/applications/external/lightmeter/README.md
index d9c071e67..e90630c03 100644
--- a/applications/external/lightmeter/README.md
+++ b/applications/external/lightmeter/README.md
@@ -1,21 +1,17 @@
-# flipperzero-lightmeter
+## Lightmeter app for photography
-[Original link](https://github.com/oleksiikutuzov/flipperzero-lightmeter)
+An application that suggests settings for your manual camera based on the reading of the ambient light sensor. Can also be used in a pure lux meter mode.
+## Supported sensors
-
+- BH1750
+- MAX44009
## Wiring
-```
-VCC -> 3.3V
-GND -> GND
-SCL -> C0
-SDA -> C1
-```
-
-## TODO
-- [ ] Save settings to sd card
-
-## References
-App inspired by [lightmeter](https://github.com/vpominchuk/lightmeter) project for Arduino by [vpominchuk](https://github.com/vpominchuk).
+| Sensor | Flipper Zero |
+| ------ | ------------ |
+| VCC | 3.3V |
+| GND | GND |
+| SCL | C0 |
+| SDA | C1 |
diff --git a/applications/external/lightmeter/application.fam b/applications/external/lightmeter/application.fam
index fc46550fe..dcdf0d9f9 100644
--- a/applications/external/lightmeter/application.fam
+++ b/applications/external/lightmeter/application.fam
@@ -1,6 +1,6 @@
App(
appid="lightmeter",
- name="[BH1750] Lightmeter",
+ name="Lightmeter",
apptype=FlipperAppType.EXTERNAL,
entry_point="lightmeter_app",
requires=[
@@ -8,6 +8,7 @@ App(
],
stack_size=1 * 1024,
order=90,
+ fap_version=(1, 1),
fap_icon="lightmeter.png",
fap_category="GPIO",
fap_private_libs=[
@@ -18,9 +19,16 @@ App(
"BH1750.c",
],
),
+ Lib(
+ name="MAX44009",
+ cincludes=["."],
+ sources=[
+ "MAX44009.c",
+ ],
+ ),
],
+ fap_description="Lightmeter app for photography",
+ fap_author="Oleksii Kutuzov",
+ fap_weburl="https://github.com/oleksiikutuzov/flipperzero-lightmeter",
fap_icon_assets="icons",
- fap_author="@oleksiikutuzov",
- fap_version="1.0",
- fap_description="Lightmeter app for photography based on BH1750 sensor",
)
diff --git a/applications/external/lightmeter/gui/scenes/lightmeter_scene_config.c b/applications/external/lightmeter/gui/scenes/lightmeter_scene_config.c
index 3d6bd5803..aafa1f843 100644
--- a/applications/external/lightmeter/gui/scenes/lightmeter_scene_config.c
+++ b/applications/external/lightmeter/gui/scenes/lightmeter_scene_config.c
@@ -51,12 +51,18 @@ static const char* lux_only[] = {
[LUX_ONLY_ON] = "On",
};
+static const char* sensor_type[] = {
+ [SENSOR_BH1750] = "BH1750",
+ [SENSOR_MAX44009] = "MAX44009",
+};
+
enum LightMeterSubmenuIndex {
LightMeterSubmenuIndexISO,
LightMeterSubmenuIndexND,
LightMeterSubmenuIndexDome,
LightMeterSubmenuIndexBacklight,
LightMeterSubmenuIndexLuxMeter,
+ LightMeterSubmenuIndexSensorType,
LightMeterSubmenuIndexHelp,
LightMeterSubmenuIndexAbout,
};
@@ -127,6 +133,17 @@ static void lux_only_cb(VariableItem* item) {
lightmeter_app_set_config(app, config);
}
+static void sensor_type_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, sensor_type[index]);
+
+ LightMeterConfig* config = app->config;
+ config->sensor_type = index;
+ lightmeter_app_set_config(app, config);
+}
+
static void ok_cb(void* context, uint32_t index) {
LightMeterApp* app = context;
UNUSED(app);
@@ -173,6 +190,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, "Sensor", COUNT_OF(sensor_type), sensor_type_cb, app);
+ variable_item_set_current_value_index(item, config->sensor_type);
+ variable_item_set_current_value_text(item, sensor_type[config->sensor_type]);
+
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);
diff --git a/applications/external/lightmeter/gui/scenes/lightmeter_scene_help.c b/applications/external/lightmeter/gui/scenes/lightmeter_scene_help.c
index 0441f0925..a5688ee2f 100644
--- a/applications/external/lightmeter/gui/scenes/lightmeter_scene_help.c
+++ b/applications/external/lightmeter/gui/scenes/lightmeter_scene_help.c
@@ -6,7 +6,8 @@ void lightmeter_scene_help_on_enter(void* context) {
FuriString* temp_str;
temp_str = furi_string_alloc();
furi_string_printf(
- temp_str, "App works with BH1750\nambient light sensor\nconnected via I2C interface\n\n");
+ temp_str,
+ "App works with BH1750 and MAX44409 ambient light sensor connected via I2C interface\n\n");
furi_string_cat(temp_str, "\e#Pinout:\r\n");
furi_string_cat(
temp_str,
diff --git a/applications/external/lightmeter/gui/scenes/lightmeter_scene_main.c b/applications/external/lightmeter/gui/scenes/lightmeter_scene_main.c
index 8ba474461..3b4789e99 100644
--- a/applications/external/lightmeter/gui/scenes/lightmeter_scene_main.c
+++ b/applications/external/lightmeter/gui/scenes/lightmeter_scene_main.c
@@ -9,6 +9,7 @@ static void lightmeter_scene_main_on_left(void* context) {
void lightmeter_scene_main_on_enter(void* context) {
LightMeterApp* app = context;
+ lightmeter_app_i2c_init_sensor(context);
lightmeter_main_view_set_left_callback(app->main_view, lightmeter_scene_main_on_left, app);
view_dispatcher_switch_to_view(app->view_dispatcher, LightMeterAppViewMainView);
}
@@ -39,5 +40,5 @@ bool lightmeter_scene_main_on_event(void* context, SceneManagerEvent event) {
}
void lightmeter_scene_main_on_exit(void* context) {
- UNUSED(context);
+ lightmeter_app_i2c_deinit_sensor(context);
}
diff --git a/applications/external/lightmeter/lib/MAX44009/MAX44009.c b/applications/external/lightmeter/lib/MAX44009/MAX44009.c
new file mode 100644
index 000000000..211f6a9ba
--- /dev/null
+++ b/applications/external/lightmeter/lib/MAX44009/MAX44009.c
@@ -0,0 +1,27 @@
+#include
+#include
+#include
+
+void max44009_init() {
+ furi_hal_i2c_acquire(I2C_BUS);
+ furi_hal_i2c_write_reg_8(I2C_BUS, MAX44009_ADDR,
+ MAX44009_REG_CONFIG, MAX44009_REG_CONFIG_CONT_MODE, I2C_TIMEOUT);
+ furi_hal_i2c_release(I2C_BUS);
+}
+
+int max44009_read_light(float* result) {
+ uint8_t data_one = 0;
+ uint8_t exp, mantissa;
+ int status;
+
+ furi_hal_i2c_acquire(I2C_BUS);
+ furi_hal_i2c_read_reg_8(I2C_BUS, MAX44009_ADDR, MAX44009_REG_LUX_HI, &data_one, I2C_TIMEOUT);
+ exp = (data_one & MAX44009_REG_LUX_HI_EXP_MASK) >> 4;
+ mantissa = (data_one & MAX44009_REG_LUX_HI_MANT_HI_MASK) << 4;
+ status = furi_hal_i2c_read_reg_8(I2C_BUS, MAX44009_ADDR, MAX44009_REG_LUX_LO, &data_one, I2C_TIMEOUT);
+ mantissa |= (data_one & MAX44009_REG_LUX_LO_MANT_LO_MASK);
+ furi_hal_i2c_release(I2C_BUS);
+ *result = (float)pow(2, exp) * mantissa * 0.045;
+ FURI_LOG_D("MAX44009", "exp %d, mant %d, lux %f", exp, mantissa, (double)*result);
+ return status;
+}
\ No newline at end of file
diff --git a/applications/external/lightmeter/lib/MAX44009/MAX44009.h b/applications/external/lightmeter/lib/MAX44009/MAX44009.h
new file mode 100644
index 000000000..fb350653d
--- /dev/null
+++ b/applications/external/lightmeter/lib/MAX44009/MAX44009.h
@@ -0,0 +1,26 @@
+#include
+#include
+
+#pragma once
+
+// I2C BUS
+#define I2C_BUS &furi_hal_i2c_handle_external
+#define I2C_TIMEOUT 10
+
+#define MAX44009_ADDR (0x4A << 1)
+
+#define MAX44009_REG_INT_STATUS 0x00
+#define MAX44009_REG_INT_EN 0x01
+#define MAX44009_REG_CONFIG 0x02
+#define MAX44009_REG_CONFIG_CONT_MODE (1 << 7)
+#define MAX44009_REG_LUX_HI 0x03
+#define MAX44009_REG_LUX_HI_EXP_MASK 0xF0
+#define MAX44009_REG_LUX_HI_MANT_HI_MASK 0x0F
+#define MAX44009_REG_LUX_LO 0x04
+#define MAX44009_REG_LUX_LO_MANT_LO_MASK 0x0F
+#define MAX44009_REG_THRESH_HI 0x05
+#define MAX44009_REG_THRESH_LO 0x06
+#define MAX44009_REG_INT_TIME 0x07
+
+void max44009_init();
+int max44009_read_light(float* result);
diff --git a/applications/external/lightmeter/lightmeter.c b/applications/external/lightmeter/lightmeter.c
index 07661d2d4..b128e334f 100644
--- a/applications/external/lightmeter/lightmeter.c
+++ b/applications/external/lightmeter/lightmeter.c
@@ -27,11 +27,6 @@ static void lightmeter_tick_event_callback(void* context) {
LightMeterApp* lightmeter_app_alloc(uint32_t first_scene) {
LightMeterApp* app = malloc(sizeof(LightMeterApp));
- // Sensor
- bh1750_set_power_state(1);
- bh1750_init();
- bh1750_set_mode(ONETIME_HIGH_RES_MODE);
-
// Set default values to config
app->config = malloc(sizeof(LightMeterConfig));
app->config->iso = DEFAULT_ISO;
@@ -117,8 +112,6 @@ void lightmeter_app_free(LightMeterApp* app) {
}
furi_record_close(RECORD_NOTIFICATION);
- bh1750_set_power_state(0);
-
free(app->config);
free(app);
}
@@ -138,6 +131,38 @@ void lightmeter_app_set_config(LightMeterApp* context, LightMeterConfig* config)
app->config = config;
}
+void lightmeter_app_i2c_init_sensor(LightMeterApp* context) {
+ LightMeterApp* app = context;
+ switch(app->config->sensor_type) {
+ case SENSOR_BH1750:
+ bh1750_set_power_state(1);
+ bh1750_init();
+ bh1750_set_mode(ONETIME_HIGH_RES_MODE);
+ break;
+ case SENSOR_MAX44009:
+ max44009_init();
+ break;
+ default:
+ FURI_LOG_E(TAG, "Invalid sensor type %d", app->config->sensor_type);
+ return;
+ }
+}
+
+void lightmeter_app_i2c_deinit_sensor(LightMeterApp* context) {
+ LightMeterApp* app = context;
+ switch(app->config->sensor_type) {
+ case SENSOR_BH1750:
+ bh1750_set_power_state(0);
+ break;
+ case SENSOR_MAX44009:
+ // nothing
+ break;
+ default:
+ FURI_LOG_E(TAG, "Invalid sensor type %d", app->config->sensor_type);
+ return;
+ }
+}
+
void lightmeter_app_i2c_callback(LightMeterApp* context) {
LightMeterApp* app = context;
@@ -145,16 +170,18 @@ void lightmeter_app_i2c_callback(LightMeterApp* context) {
float lux = 0;
bool response = 0;
- if(bh1750_trigger_manual_conversion() == BH1750_OK) response = 1;
-
- if(response) {
- bh1750_read_light(&lux);
-
- if(main_view_get_dome(app->main_view)) lux *= DOME_COEFFICIENT;
-
- EV = lux2ev(lux);
+ if(app->config->sensor_type == SENSOR_BH1750) {
+ if(bh1750_trigger_manual_conversion() == BH1750_OK) {
+ bh1750_read_light(&lux);
+ response = 1;
+ }
+ } else if(app->config->sensor_type == SENSOR_MAX44009) {
+ if(max44009_read_light(&lux)) response = 1;
}
+ if(main_view_get_dome(app->main_view)) lux *= DOME_COEFFICIENT;
+ EV = lux2ev(lux);
+
main_view_set_lux(app->main_view, lux);
main_view_set_EV(app->main_view, EV);
main_view_set_response(app->main_view, response);
diff --git a/applications/external/lightmeter/lightmeter.h b/applications/external/lightmeter/lightmeter.h
index 2558be3c5..75bc09b02 100644
--- a/applications/external/lightmeter/lightmeter.h
+++ b/applications/external/lightmeter/lightmeter.h
@@ -18,6 +18,7 @@
#include "lightmeter_config.h"
#include
+#include
typedef struct {
int iso;
@@ -26,6 +27,7 @@ typedef struct {
int dome;
int backlight;
int lux_only;
+ int sensor_type;
} LightMeterConfig;
typedef struct {
@@ -55,4 +57,6 @@ typedef enum {
void lightmeter_app_set_config(LightMeterApp* context, LightMeterConfig* config);
+void lightmeter_app_i2c_init_sensor(LightMeterApp* context);
+void lightmeter_app_i2c_deinit_sensor(LightMeterApp* context);
void lightmeter_app_i2c_callback(LightMeterApp* context);
diff --git a/applications/external/lightmeter/lightmeter_config.h b/applications/external/lightmeter/lightmeter_config.h
index 5edbdce0a..d46f0cd38 100644
--- a/applications/external/lightmeter/lightmeter_config.h
+++ b/applications/external/lightmeter/lightmeter_config.h
@@ -1,6 +1,6 @@
#pragma once
-#define LM_VERSION_APP "0.7"
+#define LM_VERSION_APP "1.1"
#define LM_DEVELOPED "Oleksii Kutuzov"
#define LM_GITHUB "https://github.com/oleksiikutuzov/flipperzero-lightmeter"
@@ -105,4 +105,9 @@ typedef enum {
LUX_ONLY_ON,
} LightMeterLuxOnlyMode;
+typedef enum {
+ SENSOR_BH1750,
+ SENSOR_MAX44009,
+} LightMeterSensorType;
+
typedef enum { BACKLIGHT_AUTO, BACKLIGHT_ON } LightMeterBacklight;