diff --git a/applications/plugins/lightmeter/lib/BH1750/BH1750.c b/applications/plugins/lightmeter/lib/BH1750/BH1750.c new file mode 100644 index 000000000..28616e040 --- /dev/null +++ b/applications/plugins/lightmeter/lib/BH1750/BH1750.c @@ -0,0 +1,144 @@ +/** + * @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; +} diff --git a/applications/plugins/lightmeter/lib/BH1750/BH1750.h b/applications/plugins/lightmeter/lib/BH1750/BH1750.h new file mode 100644 index 000000000..991350f7f --- /dev/null +++ b/applications/plugins/lightmeter/lib/BH1750/BH1750.h @@ -0,0 +1,103 @@ +/** + * @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 +#include + +#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_ */ diff --git a/applications/plugins/lightmeter/lib/BH1750/LICENSE b/applications/plugins/lightmeter/lib/BH1750/LICENSE new file mode 100644 index 000000000..cb2f65db5 --- /dev/null +++ b/applications/plugins/lightmeter/lib/BH1750/LICENSE @@ -0,0 +1,21 @@ +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. diff --git a/applications/plugins/lightmeter/lib/BH1750/README.md b/applications/plugins/lightmeter/lib/BH1750/README.md new file mode 100644 index 000000000..b1338d4ab --- /dev/null +++ b/applications/plugins/lightmeter/lib/BH1750/README.md @@ -0,0 +1,2 @@ +# flipperzero-BH1750 +BH1750 light sensor library for Flipper Zero diff --git a/applications/plugins/lightmeter/lib/BH1750/docs/BH1750.pdf b/applications/plugins/lightmeter/lib/BH1750/docs/BH1750.pdf new file mode 100644 index 000000000..267efddc6 Binary files /dev/null and b/applications/plugins/lightmeter/lib/BH1750/docs/BH1750.pdf differ