2
\$\begingroup\$

I'm trying to read value from sensor GY-30 BH1750 by I2C but when I check variables in STM Studio, they don't change.

Sensor address is 0x23 when addr connected to GND

POWER_ON 0x01

RESET 0x07

BH1750_CONTINUOUS_HIGH_RES_MODE 0x10

It's my code which I try to get data :

 buffer[0] = BH1750_POWER_ON;
 buffer[1] = RESET;
 HAL_I2C_Master_Transmit(&hi2c1, SENSOR_ADDRESS << 1, buffer, 2, 100);
 buffer[0] = BH1750_CONTINUOUS_HIGH_RES_MODE;
 HAL_I2C_Master_Transmit(&hi2c1, SENSOR_ADDRESS << 1, buffer, 1, 100);
 HAL_Delay(180);
 HAL_I2C_Master_Receive(&hi2c1, SENSOR_ADDRESS << 1, buffer, 2, 100);

Docs: http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf

What's wrong with code ? Thanks for help.

\$\endgroup\$
  • \$\begingroup\$ OK what's the question \$\endgroup\$ – Mitu Raj Dec 5 '17 at 14:02
  • \$\begingroup\$ Is that everything correct in code and it's problem with connections between stm32 and sensor or it's code problem ? Sorry for that but Im new with stm \$\endgroup\$ – kacper1230 Dec 5 '17 at 14:03
1
\$\begingroup\$

Yes this answer is quite late. But...no one else answered this and I'm pretty sure the problem has to do with sending 2 commands simultaneously (and not checking return values for success on function calls doesn't help either). From what I can tell, you cannot send the BH1750_POWER_ON command and the RESET command at the same time (they are not a single command). Also, asynchronous reset is different then the Reset command. The data sheet says the following for RESET (datasheet version 2011.11 - Rev.D page 5):

....... Reset command is for only reset Illuminance data register. ( reset value is '0' ) It is not necessary even power supply sequence .......

Which basically means it doesn't really do much for the user. If you fail a read, you should get an error back. So resetting the data register to '0' won't help to determine if some other problem is occurring. Also, for powering on the device, I have notice a slight delay after sending the command helps the device perform as expected. I've inserted a HAL_Delay(5) after the power on command because of this.

So if the user still wants to use the RESET command, the initialization code would need to be modified as follows:

// Variables
const uint8_t nAddress = (SENSOR_ADDRESS << 1);
uint16_t nLUX = 0;
uint8_t pBuffer = (uint8_t*)&nLUX;  // So LUX value doesn't have to be recombined

// Power On
pBuffer[0] = BH1750_POWER_ON;
if (HAL_I2C_Master_Transmit(&hi2c1, nAddress, pBuffer, 1, 100) != HAL_OK)
   return false;
HAL_Delay(5);

// Reset Illuminance Register
pBuffer[0] = RESET;
if (HAL_I2C_Master_Transmit(&hi2c1, nAddress, pBuffer, 1, 100) != HAL_OK)
   return false;

// Set measurement mode
pBuffer[0] = BH1750_CONTINUOUS_HIGH_RES_MODE;
if (HAL_I2C_Master_Transmit(&hi2c1, nAddress, pBuffer, 1, 100) != HAL_OK)
   return false;
HAL_Delay(180); // Wait for measurement (or come back after 180 ms instead of idling)

// Read measurement
if (HAL_I2C_Master_Receive(&hi2c1, nAddress, pBuffer, 2, 100) != HAL_OK)
   return false;

// nLUX holds your LUX value now...
return true;

Or the version without the RESET

// Variables
const uint8_t nAddress = (SENSOR_ADDRESS << 1);
uint16_t nLUX = 0;
uint8_t pBuffer = (uint8_t*)&nLUX;  // So LUX value doesn't have to be recombined

// Power On
pBuffer[0] = BH1750_POWER_ON;
if (HAL_I2C_Master_Transmit(&hi2c1, nAddress, pBuffer, 1, 100) != HAL_OK)
   return false;
HAL_Delay(5);

// Set measurement mode
pBuffer[0] = BH1750_CONTINUOUS_HIGH_RES_MODE;
if (HAL_I2C_Master_Transmit(&hi2c1, nAddress, pBuffer, 1, 100) != HAL_OK)
   return false;
HAL_Delay(180); // Wait for measurement (or come back after 180 ms instead of idling)

// Read measurement
if (HAL_I2C_Master_Receive(&hi2c1, nAddress, pBuffer, 2, 100) != HAL_OK)
   return false;

// nLUX holds your LUX value now...
return true;

One other note, the large delay after sending in the BH1750_CONTINUOUS_HIGH_RES_MODE isn't necessary after the first read and can be closer to the 120ms time instead. A secondary function that basically checks if 120ms has elapsed since the last read is all that is necessary before another read can be performed (without any other commands sent).

const uint8_t nAddress = (SENSOR_ADDRESS << 1);
uint16_t nLUX = 0;
HAL_I2C_Master_Receive(&hi2c1, nAddress, (uint8_t*)&nLUX, 2, 100);
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.