Estoy luchando para encontrar una fórmula de conversión real para convertir el valor RAW en un resultado que tenga sentido. Estoy usando un sensor OPT3001 de TI y ATTiny25 como MUC.
He encontrado un ejemplo en línea, pero no da el valor correcto en Lux, la ecuación utilizada es la siguiente:
/*Convert to LUX*/
//extract result & exponent data from raw readings
result = raw&0x0FFF;
exponent = (raw>>12)&0x000F;
lux=0.01*pow(2,eksponent)*result;
Esto da valores erróneos según mi medidor de Lux que tengo como referencia y, por ejemplo, el medidor de lux dice que es 420 lux dentro de Office ... la ecuación anterior me da el resultado 110 Lux , que no es realista. El sensor funciona bien ya que lo reemplacé por uno nuevo, para estar al 100% de que no se trata de un problema relacionado con el sensor.
El resultado está muy cerca si tomo solo result = raw&0x0FFF;
, pero luego falla a valores más altos (cuando coloco mi sensor debajo de la bombilla de la lámpara).
No creo que sea un error dentro de mi código I2C, pero adjuntaré aquí también la parte de mi coude para UpdateLight:
// I2C OPT address
#define OPT_ADDR_W 0x88
#define OPT_ADDR_R 0x89
// I2C OPT registers
#define OPT_RESULT_REG 0x00
#define OPT_CONFIG_REG 0x01
// OPT config bits - automatic full scale mode, 100 ms conversion, single-shot
#define OPT_CONFIGURATION_H 0xC2
#define OPT_CONFIGURATION_L 0x00
void UpdateLight(void)
{
uint8_t error = 0;
// start conversion
I2C_Start();
error |= I2C_Write(OPT_ADDR_W);
error |= I2C_Write(OPT_CONFIG_REG);
error |= I2C_Write(OPT_CONFIGURATION_H);
error |= I2C_Write(OPT_CONFIGURATION_L);
I2C_Stop();
// wait for conversion
_delay_ms(150);
// set result register
I2C_Start();
error |= I2C_Write(OPT_ADDR_W);
error |= I2C_Write(OPT_RESULT_REG);
I2C_Stop();
// read data and update scratchpad
I2C_Start();
error |= I2C_Write(OPT_ADDR_R);
if (error == 0)
{
scratchpad[1] = I2C_Read(1);
scratchpad[0] = I2C_Read(0);
}
else
{
// report error value
scratchpad[1] = 0xFF;
scratchpad[0] = 0xFF;
}
I2C_Stop();
}
Y esta es mi fórmula anterior que se me ocurrió, pero da resultados aún más ridículos que los anteriores de internet:
// calculate light ( LUX = (MANTISA << EXPONENT) / 100 )
light = (int16_t)((float)((uint32_t)((spad[SPAD_MSB] << 8) | spad[SPAD_LSB]) << (uint32_t)((spad[SPAD_MSB] >> 4) & 0x0F)) / (83865.60 / LIGHT_MULTIPLIER));
debug_printf("L_RAW: %02X%02X\r\n", spad[SPAD_MSB], spad[SPAD_LSB]);
debug_printf("L_VAL: %d\r\n", light);
Agregando las líneas de salida de las declaraciones de impresión anteriores:
L: 5460 - 824
L: 5464 - 824
L: 5462 - 824
L: 5462 - 824
El primer valor debe ser RAW MSB y LSB, y el segundo es el valor convertido a Lux, utilizando la fórmula que aparece más arriba.
Además, me sorprende que dentro de la Hoja de datos, TI no haya proporcionado una fórmula de conversión.
Cualquier ayuda es muy apreciada.