BH1750.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * BH1750.c
  3. *
  4. * The MIT License.
  5. * Created on: 06.11.2022
  6. * Author: Oleksii Kutuzov
  7. *
  8. * Ported from:
  9. * https://github.com/lamik/Light_Sensors_STM32
  10. */
  11. #include "BH1750.h"
  12. BH1750_mode bh1750_mode = BH1750_DEFAULT_MODE; // Current sensor mode
  13. uint8_t bh1750_mt_reg = BH1750_DEFAULT_MTREG; // Current MT register value
  14. //
  15. // Initialization.
  16. //
  17. BH1750_STATUS bh1750_init() {
  18. if(BH1750_OK == bh1750_reset()) {
  19. if(BH1750_OK == bh1750_set_mt_reg(BH1750_DEFAULT_MTREG)) // Set default value;
  20. return BH1750_OK;
  21. }
  22. return BH1750_ERROR;
  23. }
  24. //
  25. // Reset all registers to default value.
  26. //
  27. BH1750_STATUS bh1750_reset() {
  28. uint8_t command = 0x07;
  29. bool status;
  30. furi_hal_i2c_acquire(I2C_BUS);
  31. status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &command, 1, I2C_TIMEOUT);
  32. furi_hal_i2c_release(I2C_BUS);
  33. if(status) {
  34. return BH1750_OK;
  35. }
  36. return BH1750_ERROR;
  37. }
  38. //
  39. // Set the power state.
  40. // 0 - sleep, low power.
  41. // 1 - running.
  42. //
  43. BH1750_STATUS bh1750_set_power_state(uint8_t PowerOn) {
  44. PowerOn = (PowerOn ? 1 : 0);
  45. bool status;
  46. furi_hal_i2c_acquire(I2C_BUS);
  47. status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &PowerOn, 1, I2C_TIMEOUT);
  48. furi_hal_i2c_release(I2C_BUS);
  49. if(status) {
  50. return BH1750_OK;
  51. }
  52. return BH1750_ERROR;
  53. }
  54. //
  55. // Set the mode of converting. Look into bh1750_mode enum.
  56. //
  57. BH1750_STATUS bh1750_set_mode(BH1750_mode mode) {
  58. if(!((mode >> 4) || (mode >> 5))) {
  59. return BH1750_ERROR;
  60. }
  61. if((mode & 0x0F) > 3) {
  62. return BH1750_ERROR;
  63. }
  64. bool status;
  65. bh1750_mode = mode;
  66. furi_hal_i2c_acquire(I2C_BUS);
  67. status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &mode, 1, I2C_TIMEOUT);
  68. furi_hal_i2c_release(I2C_BUS);
  69. if(status) {
  70. return BH1750_OK;
  71. }
  72. return BH1750_ERROR;
  73. }
  74. //
  75. // Set the Measurement Time register. It allows to increase or decrease the sensitivity.
  76. //
  77. BH1750_STATUS bh1750_set_mt_reg(uint8_t mt_reg) {
  78. if(mt_reg < 31 || mt_reg > 254) {
  79. return BH1750_ERROR;
  80. }
  81. bh1750_mt_reg = mt_reg;
  82. uint8_t tmp[2];
  83. bool status;
  84. tmp[0] = (0x40 | (mt_reg >> 5));
  85. tmp[1] = (0x60 | (mt_reg & 0x1F));
  86. furi_hal_i2c_acquire(I2C_BUS);
  87. status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &tmp[0], 1, I2C_TIMEOUT);
  88. furi_hal_i2c_release(I2C_BUS);
  89. if(!status) {
  90. return BH1750_ERROR;
  91. }
  92. furi_hal_i2c_acquire(I2C_BUS);
  93. status = furi_hal_i2c_tx(I2C_BUS, BH1750_ADDRESS, &tmp[1], 1, I2C_TIMEOUT);
  94. furi_hal_i2c_release(I2C_BUS);
  95. if(status) {
  96. return BH1750_OK;
  97. }
  98. return BH1750_ERROR;
  99. }
  100. //
  101. // Trigger the conversion in manual modes.
  102. // For low resolution conversion time is typical 16 ms,
  103. // for high resolution 120 ms. You need to wait until read the measurement value.
  104. // There is no need to exit low power mode for manual conversion. It makes automatically.
  105. //
  106. BH1750_STATUS bh1750_trigger_manual_conversion() {
  107. if(BH1750_OK == bh1750_set_mode(bh1750_mode)) {
  108. return BH1750_OK;
  109. }
  110. return BH1750_ERROR;
  111. }
  112. //
  113. // Read the converted value and calculate the result.
  114. //
  115. BH1750_STATUS bh1750_read_light(float* result) {
  116. float result_tmp;
  117. uint8_t rcv[2];
  118. bool status;
  119. furi_hal_i2c_acquire(I2C_BUS);
  120. status = furi_hal_i2c_rx(I2C_BUS, BH1750_ADDRESS, rcv, 2, I2C_TIMEOUT);
  121. furi_hal_i2c_release(I2C_BUS);
  122. if(status) {
  123. result_tmp = (rcv[0] << 8) | (rcv[1]);
  124. if(bh1750_mt_reg != BH1750_DEFAULT_MTREG) {
  125. result_tmp *= (float)((uint8_t)BH1750_DEFAULT_MTREG / (float)bh1750_mt_reg);
  126. }
  127. if(bh1750_mode == ONETIME_HIGH_RES_MODE_2 || bh1750_mode == CONTINUOUS_HIGH_RES_MODE_2) {
  128. result_tmp /= 2.0;
  129. }
  130. *result = result_tmp / BH1750_CONVERSION_FACTOR;
  131. return BH1750_OK;
  132. }
  133. return BH1750_ERROR;
  134. }