lightmeter upd

This commit is contained in:
RogueMaster
2022-12-12 15:40:42 -05:00
parent 62cc8d0865
commit 5a4616f185
29 changed files with 365 additions and 339 deletions
+1
View File
@@ -25,6 +25,7 @@ Thank you to all the supporters!
- Updated: [Intravelometer (By theageoflove)](https://github.com/theageoflove/flipperzero-zeitraffer)
- Added: [IR Remote (By Hong5489)](https://github.com/Hong5489/ir_remote)
- Removed: [POCSAG (By Shmuma)](https://github.com/Shmuma/flipper-zero-pocsag)
- Updated: [Lightmeter (By oleksiikutuzov)](https://github.com/oleksiikutuzov/flipperzero-lightmeter) `Req: BH1750`
## Install from Release
FLASH STOCK FIRST BEFORE UPDATING TO CUSTOM FIRMWARE!
@@ -0,0 +1,191 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: AlwaysBreak
AlignArrayOfStructures: None
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- __capability
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 99
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: BinPack
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 4
IndentWrappedFunctionNames: true
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 10
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Left
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: false
RemoveBracesLLVM: false
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: Never
SortJavaStaticImport: Before
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeParensOptions:
AfterControlStatements: false
AfterForeachMacros: false
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: false
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: c++03
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...
+17 -3
View File
@@ -1,9 +1,10 @@
# flipperzero-lightmeter
# flipperzero-lightmeter
[Original link](https://github.com/oleksiikutuzov/flipperzero-lightmeter)
[![Build FAP](https://github.com/oleksiikutuzov/flipperzero-lightmeter/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/oleksiikutuzov/flipperzero-lightmeter/actions/workflows/build.yml)
<img src="images/framed_gui_main.png" width="500px">
<img src="images/framed_gui_main.png" width="500px">
<img src="images/framed_gui_lux_meter.png" width="500px">
## Wiring
@@ -14,6 +15,19 @@ SCL -> C0
SDA -> C1
```
## Sensor module
<img src="module/back.jpg" width="500px">
### If you want to build this module, you'll need (it's quite over-engineered, sorry :D)
1. [Module PCB](https://github.com/oleksiikutuzov/flipperzero-lightmeter/blob/main/module/module_v2_gerber.zip)
2. [Enclosure](https://github.com/oleksiikutuzov/flipperzero-lightmeter/blob/main/module/module_v2_enclosure.stl)
3. 4-pin female header
4. 10-pin male header
5. 2x M3 threaded inserts (max diameter 5.3 mm, max height 4 mm)
6. 2x M3x5 screws
## TODO
- [ ] Save settings to sd card
@@ -21,4 +21,7 @@ App(
),
],
fap_icon_assets="icons",
fap_description="Lightmeter app for photography based on BH1750 sensor",
fap_author="Oleksii Kutuzov",
fap_weburl="https://github.com/oleksiikutuzov/flipperzero-lightmeter",
)
@@ -1,5 +1,7 @@
#include "../../lightmeter.h"
#define TAG "Scene Config"
static const char* iso_numbers[] = {
[ISO_6] = "6",
[ISO_12] = "12",
@@ -39,10 +41,24 @@ static const char* diffusion_dome[] = {
[WITH_DOME] = "Yes",
};
static const char* backlight[] = {
[BACKLIGHT_AUTO] = "Auto",
[BACKLIGHT_ON] = "On",
};
static const char* lux_only[] = {
[LUX_ONLY_OFF] = "Off",
[LUX_ONLY_ON] = "On",
};
enum LightMeterSubmenuIndex {
LightMeterSubmenuIndexISO,
LightMeterSubmenuIndexND,
LightMeterSubmenuIndexDome,
LightMeterSubmenuIndexBacklight,
LightMeterSubmenuIndexLuxMeter,
LightMeterSubmenuIndexHelp,
LightMeterSubmenuIndexAbout,
};
static void iso_numbers_cb(VariableItem* item) {
@@ -78,14 +94,47 @@ static void dome_presence_cb(VariableItem* item) {
lightmeter_app_set_config(app, config);
}
static void backlight_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, backlight[index]);
LightMeterConfig* config = app->config;
if(index != config->backlight) {
if(index == BACKLIGHT_ON) {
notification_message(
app->notifications,
&sequence_display_backlight_enforce_on); // force on backlight
} else {
notification_message(
app->notifications,
&sequence_display_backlight_enforce_auto); // force auto backlight
}
}
config->backlight = index;
lightmeter_app_set_config(app, config);
}
static void lux_only_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, lux_only[index]);
LightMeterConfig* config = app->config;
config->lux_only = index;
lightmeter_app_set_config(app, config);
}
static void ok_cb(void* context, uint32_t index) {
LightMeterApp* app = context;
UNUSED(app);
switch(index) {
case 3:
case LightMeterSubmenuIndexHelp:
view_dispatcher_send_custom_event(app->view_dispatcher, LightMeterAppCustomEventHelp);
break;
case 4:
case LightMeterSubmenuIndexAbout:
view_dispatcher_send_custom_event(app->view_dispatcher, LightMeterAppCustomEventAbout);
break;
default:
@@ -114,6 +163,16 @@ void lightmeter_scene_config_on_enter(void* context) {
variable_item_set_current_value_index(item, config->dome);
variable_item_set_current_value_text(item, diffusion_dome[config->dome]);
item =
variable_item_list_add(var_item_list, "Backlight", COUNT_OF(backlight), backlight_cb, app);
variable_item_set_current_value_index(item, config->backlight);
variable_item_set_current_value_text(item, backlight[config->backlight]);
item = variable_item_list_add(
var_item_list, "Lux meter only", COUNT_OF(lux_only), lux_only_cb, app);
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, "Help and Pinout", 0, NULL, NULL);
item = variable_item_list_add(var_item_list, "About", 0, NULL, NULL);
@@ -153,4 +212,5 @@ void lightmeter_scene_config_on_exit(void* context) {
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);
}
@@ -10,6 +10,8 @@ void lightmeter_scene_help_on_enter(void* context) {
furi_string_cat(temp_str, "\e#Pinout:\r\n");
furi_string_cat(
temp_str,
" VCC: 3.3V\r\n"
" GND: GND\r\n"
" SDA: 15 [C1]\r\n"
" SCL: 16 [C0]\r\n");
@@ -41,7 +41,7 @@ static const int nd_numbers[] = {
[ND_4096] = 4096,
};
static const float aperture_numbers[] = {
const float aperture_numbers[] = {
[AP_1] = 1.0,
[AP_1_4] = 1.4,
[AP_2] = 2.0,
@@ -59,7 +59,7 @@ static const float aperture_numbers[] = {
[AP_128] = 128,
};
static const float speed_numbers[] = {
const float speed_numbers[] = {
[SPEED_8000] = 1.0 / 8000, [SPEED_4000] = 1.0 / 4000, [SPEED_2000] = 1.0 / 2000,
[SPEED_1000] = 1.0 / 1000, [SPEED_500] = 1.0 / 500, [SPEED_250] = 1.0 / 250,
[SPEED_125] = 1.0 / 125, [SPEED_60] = 1.0 / 60, [SPEED_30] = 1.0 / 30,
@@ -94,37 +94,39 @@ static void main_view_draw_callback(Canvas* canvas, void* context) {
furi_assert(context);
MainViewModel* model = context;
// FURI_LOG_D("MAIN VIEW", "Drawing");
canvas_clear(canvas);
// top row
draw_top_row(canvas, model);
// add f, T values
canvas_set_font(canvas, FontBigNumbers);
// draw f icon and number
canvas_draw_icon(canvas, 15, 17, &I_f_10x14);
draw_aperture(canvas, model);
// draw T icon and number
canvas_draw_icon(canvas, 15, 34, &I_T_10x14);
draw_speed(canvas, model);
// draw button
canvas_set_font(canvas, FontSecondary);
elements_button_left(canvas, "Config");
// draw ND number
draw_nd_number(canvas, model);
if(!model->lux_only) {
// top row
draw_top_row(canvas, model);
// draw EV number
canvas_set_font(canvas, FontSecondary);
draw_EV_number(canvas, model);
// add f, T values
canvas_set_font(canvas, FontBigNumbers);
// draw mode indicator
draw_mode_indicator(canvas, model);
// draw f icon and number
canvas_draw_icon(canvas, 15, 17, &I_f_10x14);
draw_aperture(canvas, model);
// draw T icon and number
canvas_draw_icon(canvas, 15, 34, &I_T_10x14);
draw_speed(canvas, model);
// draw ND number
draw_nd_number(canvas, model);
// draw EV number
canvas_set_font(canvas, FontSecondary);
draw_EV_number(canvas, model);
// draw mode indicator
draw_mode_indicator(canvas, model);
} else {
draw_lux_only_mode(canvas, model);
}
}
static void main_view_process(MainView* main_view, InputEvent* event) {
@@ -267,6 +269,12 @@ void main_view_set_dome(MainView* main_view, bool dome) {
main_view->view, MainViewModel * model, { model->dome = dome; }, true);
}
void main_view_set_lux_only(MainView* main_view, bool lux_only) {
furi_assert(main_view);
with_view_model(
main_view->view, MainViewModel * model, { model->lux_only = lux_only; }, true);
}
bool main_view_get_dome(MainView* main_view) {
furi_assert(main_view);
bool val = false;
@@ -307,7 +315,7 @@ void draw_top_row(Canvas* canvas, MainViewModel* context) {
canvas_set_font(canvas, FontPrimary);
// metering mode A ambient, F flash
canvas_draw_str_aligned(canvas, 1, 1, AlignLeft, AlignTop, "A");
// canvas_draw_str_aligned(canvas, 1, 1, AlignLeft, AlignTop, "A");
snprintf(str, sizeof(str), "ISO: %d", iso_numbers[model->iso]);
canvas_draw_str_aligned(canvas, 19, 1, AlignLeft, AlignTop, str);
@@ -412,6 +420,8 @@ void draw_nd_number(Canvas* canvas, MainViewModel* context) {
char str[9];
canvas_set_font(canvas, FontSecondary);
if(model->response) {
snprintf(str, sizeof(str), "ND: %d", nd_numbers[model->nd]);
} else {
@@ -432,3 +442,29 @@ void draw_EV_number(Canvas* canvas, MainViewModel* context) {
canvas_draw_str_aligned(canvas, 87, 29, AlignLeft, AlignBottom, "EV: --");
}
}
void draw_lux_only_mode(Canvas* canvas, MainViewModel* context) {
MainViewModel* model = context;
if(!model->response) {
canvas_draw_box(canvas, 0, 0, 128, 12);
canvas_set_color(canvas, ColorWhite);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 24, 10, "No sensor found");
canvas_set_color(canvas, ColorBlack);
} else {
char str[12];
canvas_set_font(canvas, FontPrimary);
canvas_draw_line(canvas, 0, 10, 128, 10);
canvas_draw_str_aligned(canvas, 64, 1, AlignCenter, AlignTop, "Lux meter mode");
canvas_set_font(canvas, FontBigNumbers);
snprintf(str, sizeof(str), "%.0f", (double)model->lux);
canvas_draw_str_aligned(canvas, 80, 32, AlignRight, AlignCenter, str);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 85, 39, AlignLeft, AlignBottom, "Lux");
}
}
@@ -27,6 +27,7 @@ typedef struct {
int aperture;
int speed;
bool dome;
bool lux_only;
} MainViewModel;
typedef void (*LightMeterMainViewButtonCallback)(void* context);
@@ -58,6 +59,8 @@ void main_view_set_speed(MainView* main_view, int val);
void main_view_set_dome(MainView* main_view, bool val);
void main_view_set_lux_only(MainView* main_view, bool val);
bool main_view_get_dome(MainView* main_view);
void draw_top_row(Canvas* canvas, MainViewModel* context);
@@ -71,3 +74,5 @@ void draw_mode_indicator(Canvas* canvas, MainViewModel* context);
void draw_nd_number(Canvas* canvas, MainViewModel* context);
void draw_EV_number(Canvas* canvas, MainViewModel* context);
void draw_lux_only_mode(Canvas* canvas, MainViewModel* context);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

@@ -1,144 +0,0 @@
/**
* @file BH1750.h
* @author Oleksii Kutuzov (oleksii.kutuzov@icloud.com)
* @brief
* @version 0.1
* @date 2022-11-06
*
* @copyright Copyright (c) 2022
*
* Ported from:
* https://github.com/lamik/Light_Sensors_STM32
*/
#include "BH1750.h"
BH1750_mode bh1750_mode = BH1750_DEFAULT_MODE; // Current sensor mode
uint8_t bh1750_mt_reg = BH1750_DEFAULT_MTREG; // Current MT register value
BH1750_STATUS bh1750_init() {
if(BH1750_OK == bh1750_reset()) {
if(BH1750_OK == bh1750_set_mt_reg(BH1750_DEFAULT_MTREG)) {
return BH1750_OK;
}
}
return BH1750_ERROR;
}
BH1750_STATUS bh1750_reset() {
uint8_t command = 0x07;
bool status;
furi_hal_i2c_acquire(I2C_BUS);
status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &command, 1, I2C_TIMEOUT);
furi_hal_i2c_release(I2C_BUS);
if(status) {
return BH1750_OK;
}
return BH1750_ERROR;
}
BH1750_STATUS bh1750_set_power_state(uint8_t PowerOn) {
PowerOn = (PowerOn ? 1 : 0);
bool status;
furi_hal_i2c_acquire(I2C_BUS);
status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &PowerOn, 1, I2C_TIMEOUT);
furi_hal_i2c_release(I2C_BUS);
if(status) {
return BH1750_OK;
}
return BH1750_ERROR;
}
BH1750_STATUS bh1750_set_mode(BH1750_mode mode) {
if(!((mode >> 4) || (mode >> 5))) {
return BH1750_ERROR;
}
if((mode & 0x0F) > 3) {
return BH1750_ERROR;
}
bool status;
bh1750_mode = mode;
furi_hal_i2c_acquire(I2C_BUS);
status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &mode, 1, I2C_TIMEOUT);
furi_hal_i2c_release(I2C_BUS);
if(status) {
return BH1750_OK;
}
return BH1750_ERROR;
}
BH1750_STATUS bh1750_set_mt_reg(uint8_t mt_reg) {
if(mt_reg < 31 || mt_reg > 254) {
return BH1750_ERROR;
}
bh1750_mt_reg = mt_reg;
uint8_t tmp[2];
bool status;
tmp[0] = (0x40 | (mt_reg >> 5));
tmp[1] = (0x60 | (mt_reg & 0x1F));
furi_hal_i2c_acquire(I2C_BUS);
status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &tmp[0], 1, I2C_TIMEOUT);
furi_hal_i2c_release(I2C_BUS);
if(!status) {
return BH1750_ERROR;
}
furi_hal_i2c_acquire(I2C_BUS);
status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &tmp[1], 1, I2C_TIMEOUT);
furi_hal_i2c_release(I2C_BUS);
if(status) {
return BH1750_OK;
}
return BH1750_ERROR;
}
BH1750_STATUS bh1750_trigger_manual_conversion() {
if(BH1750_OK == bh1750_set_mode(bh1750_mode)) {
return BH1750_OK;
}
return BH1750_ERROR;
}
BH1750_STATUS bh1750_read_light(float* result) {
float result_tmp;
uint8_t rcv[2];
bool status;
furi_hal_i2c_acquire(I2C_BUS);
status = furi_hal_i2c_rx(I2C_BUS, BH1750_ADDRESS, rcv, 2, I2C_TIMEOUT);
furi_hal_i2c_release(I2C_BUS);
if(status) {
result_tmp = (rcv[0] << 8) | (rcv[1]);
if(bh1750_mt_reg != BH1750_DEFAULT_MTREG) {
result_tmp *= (float)((uint8_t)BH1750_DEFAULT_MTREG / (float)bh1750_mt_reg);
}
if(bh1750_mode == ONETIME_HIGH_RES_MODE_2 || bh1750_mode == CONTINUOUS_HIGH_RES_MODE_2) {
result_tmp /= 2.0;
}
*result = result_tmp / BH1750_CONVERSION_FACTOR;
return BH1750_OK;
}
return BH1750_ERROR;
}
@@ -1,103 +0,0 @@
/**
* @file BH1750.h
* @author Oleksii Kutuzov (oleksii.kutuzov@icloud.com)
* @brief
* @version 0.1
* @date 2022-11-06
*
* @copyright Copyright (c) 2022
*
* Ported from:
* https://github.com/lamik/Light_Sensors_STM32
*/
#include <furi.h>
#include <furi_hal.h>
#ifndef BH1750_H_
#define BH1750_H_
// I2C BUS
#define I2C_BUS &furi_hal_i2c_handle_external
#define I2C_TIMEOUT 10
#define BH1750_ADDRESS (0x23 << 1)
#define BH1750_POWER_DOWN 0x00
#define BH1750_POWER_ON 0x01
#define BH1750_RESET 0x07
#define BH1750_DEFAULT_MTREG 69
#define BH1750_DEFAULT_MODE ONETIME_HIGH_RES_MODE
#define BH1750_CONVERSION_FACTOR 1.2
typedef enum { BH1750_OK = 0, BH1750_ERROR = 1 } BH1750_STATUS;
typedef enum {
CONTINUOUS_HIGH_RES_MODE = 0x10,
CONTINUOUS_HIGH_RES_MODE_2 = 0x11,
CONTINUOUS_LOW_RES_MODE = 0x13,
ONETIME_HIGH_RES_MODE = 0x20,
ONETIME_HIGH_RES_MODE_2 = 0x21,
ONETIME_LOW_RES_MODE = 0x23
} BH1750_mode;
/**
* @brief Initialize the sensor. Sends the reset command and sets the measurement register to the default value.
*
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_init();
/**
* @brief Reset all registers to the default value.
*
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_reset();
/**
* @brief Sets the power state. 1 - running; 0 - sleep, low power.
*
* @param PowerOn sensor state.
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_set_power_state(uint8_t PowerOn);
/**
* @brief Set the Measurement Time register. It allows to increase or decrease the sensitivity.
*
* @param MTreg value from 31 to 254, defaults to 69.
*
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_set_mt_reg(uint8_t MTreg);
/**
* @brief Set the mode of converting. Look into the bh1750_mode enum.
*
* @param Mode mode enumerator
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_set_mode(BH1750_mode Mode);
/**
* @brief Trigger the conversion in manual modes.
*
* @details a low-resolution mode, the conversion time is typically 16 ms, and for a high-resolution
* mode is 120 ms. You need to wait until reading the measurement value. There is no need
* to exit low-power mode for manual conversion. It makes automatically.
*
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_trigger_manual_conversion();
/**
* @brief Read the converted value and calculate the result.
*
* @param Result stores received value to this variable.
* @return BH1750_STATUS
*/
BH1750_STATUS bh1750_read_light(float* Result);
#endif /* BH1750_H_ */
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 Oleksii Kutuzov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,2 +0,0 @@
# flipperzero-BH1750
BH1750 light sensor library for Flipper Zero
+7 -7
View File
@@ -1,7 +1,7 @@
#include "lightmeter.h"
#include "lightmeter_helper.h"
#define WORKER_TAG "MAIN APP"
#define TAG "MAIN APP"
static bool lightmeter_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
@@ -31,7 +31,6 @@ LightMeterApp* lightmeter_app_alloc(uint32_t first_scene) {
bh1750_set_power_state(1);
bh1750_init();
bh1750_set_mode(ONETIME_HIGH_RES_MODE);
bh1750_set_mt_reg(100);
// Set default values to config
app->config = malloc(sizeof(LightMeterConfig));
@@ -39,12 +38,11 @@ LightMeterApp* lightmeter_app_alloc(uint32_t first_scene) {
app->config->nd = DEFAULT_ND;
app->config->aperture = DEFAULT_APERTURE;
app->config->dome = DEFAULT_DOME;
app->config->backlight = DEFAULT_BACKLIGHT;
// Records
app->gui = furi_record_open(RECORD_GUI);
app->notifications = furi_record_open(RECORD_NOTIFICATION);
notification_message(
app->notifications, &sequence_display_backlight_enforce_on); // force on backlight
// View dispatcher
app->view_dispatcher = view_dispatcher_alloc();
@@ -112,9 +110,11 @@ void lightmeter_app_free(LightMeterApp* app) {
// Records
furi_record_close(RECORD_GUI);
notification_message(
app->notifications,
&sequence_display_backlight_enforce_auto); // set backlight back to auto
if(app->config->backlight != BACKLIGHT_AUTO) {
notification_message(
app->notifications,
&sequence_display_backlight_enforce_auto); // set backlight back to auto
}
furi_record_close(RECORD_NOTIFICATION);
bh1750_set_power_state(0);
@@ -24,6 +24,8 @@ typedef struct {
int nd;
int aperture;
int dome;
int backlight;
int lux_only;
} LightMeterConfig;
typedef struct {
@@ -1,6 +1,6 @@
#pragma once
#define LM_VERSION_APP "0.5"
#define LM_VERSION_APP "0.7"
#define LM_DEVELOPED "Oleksii Kutuzov"
#define LM_GITHUB "https://github.com/oleksiikutuzov/flipperzero-lightmeter"
@@ -10,6 +10,7 @@
#define DEFAULT_APERTURE AP_2_8
#define DEFAULT_SPEED SPEED_125
#define DEFAULT_DOME WITHOUT_DOME
#define DEFAULT_BACKLIGHT BACKLIGHT_AUTO
typedef enum {
ISO_6,
@@ -97,3 +98,10 @@ typedef enum {
WITHOUT_DOME,
WITH_DOME,
} LightMeterDomePresence;
typedef enum {
LUX_ONLY_OFF,
LUX_ONLY_ON,
} LightMeterLuxOnlyMode;
typedef enum { BACKLIGHT_AUTO, BACKLIGHT_ON } LightMeterBacklight;
@@ -1,33 +1,8 @@
#include "lightmeter_helper.h"
#include "lightmeter_config.h"
static const float aperture_numbers[] = {
[AP_1] = 1.0,
[AP_1_4] = 1.4,
[AP_2] = 2.0,
[AP_2_8] = 2.8,
[AP_4] = 4.0,
[AP_5_6] = 5.6,
[AP_8] = 8,
[AP_11] = 11,
[AP_16] = 16,
[AP_22] = 22,
[AP_32] = 32,
[AP_45] = 45,
[AP_64] = 64,
[AP_90] = 90,
[AP_128] = 128,
};
static const float time_numbers[] = {
[SPEED_8000] = 1.0 / 8000, [SPEED_4000] = 1.0 / 4000, [SPEED_2000] = 1.0 / 2000,
[SPEED_1000] = 1.0 / 1000, [SPEED_500] = 1.0 / 500, [SPEED_250] = 1.0 / 250,
[SPEED_125] = 1.0 / 125, [SPEED_60] = 1.0 / 60, [SPEED_30] = 1.0 / 30,
[SPEED_15] = 1.0 / 15, [SPEED_8] = 1.0 / 8, [SPEED_4] = 1.0 / 4,
[SPEED_2] = 1.0 / 2, [SPEED_1S] = 1.0, [SPEED_2S] = 2.0,
[SPEED_4S] = 4.0, [SPEED_8S] = 8.0, [SPEED_15S] = 15.0,
[SPEED_30S] = 30.0,
};
extern const float aperture_numbers[];
extern const float speed_numbers[];
float lux2ev(float lux) {
return log2(lux / 2.5);
@@ -41,7 +16,6 @@ float getMinDistance(float x, float v1, float v2) {
return v1;
}
// Convert calculated aperture value to photography style aperture value.
float normalizeAperture(float a) {
for(int i = 0; i < AP_NUM; i++) {
float a1 = aperture_numbers[i];
@@ -57,8 +31,8 @@ float normalizeAperture(float a) {
float normalizeTime(float a) {
for(int i = 0; i < SPEED_NUM; i++) {
float a1 = time_numbers[i];
float a2 = time_numbers[i + 1];
float a1 = speed_numbers[i];
float a2 = speed_numbers[i + 1];
if(a1 < a && a2 >= a) {
return getMinDistance(a, a1, a2);
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB