BH1750.c 4.1 KB

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