This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OPT3001-Q1: The INT pin of the OPT3001 has no change when using the latched window-style comparison mode

Part Number: OPT3001-Q1
Other Parts Discussed in Thread: OPT3001

Dears,

I want to achieve the following funciton through OPT3001. When the result register detects that the lux exceeds the value of the high and lower limit registers that I set, INT will output a low level to trigger the interrupt of my board.
According to the manual, I think the latched window-style comparison mod should be used, and I understand that opt3001 will automatically compare each detected lux with the set value of the high and lower limit registers, no need to tell the sensor through code, right?

Configuration register set to 0xCE10

But when the lux (eg 2.xx) detected by the result register is lower than the lower limit register (eg 20), the output level of the sampled INT still does not change.It should have changed from 1 to 0.

Please tell me if I am missing something?

Looking forward to your answers and support, thanks in advance

  • Hi Joheim,

    Can you share what you are setting the lower and upper limit registers to? Also, can you describe what exactly you write to the device and the test setup to probe the INT pin? The INT pin is cleared for every configuration register read, just in case you are reading this register in a loop.

    Thank you,

    Brent Elliott

  • Hi Brent,

    thx for your reply!

    Configuration register set to 0xCE10 //Auto Range, continuous, Fault_One for Fault_Count_Field_Bit, latched_Window_style, Polarity_Field_Bit set 1

    my setting for the low- & high -limit registers:

    --------------------------------------------------

    in opt3001.h

    #define R_Low_Limit 0x02 
    #define R_High_Limit 0x03

    in main() of main.c :

    int LDATA = 20; //low-limit is 20 
    int HDATA = 40000;//high-limit is 40000

    OPT3001_Write_Low_Limit(int LDATA)

    OPT3001_Write_High_Limit(int HDATA)

    in opt3001.c:

    void OPT3001_Write_Low_Limit(int DATA)
    {

    I2c_Master_Send_Byte(R_Low_Limit, DATA);
    }

    void OPT3001_Write_High_Limit(int DATA)
    {

    I2c_Master_Send_Byte(R_High_Limit, DATA);
    }

    //Please note that I2c_Master_Send_Byte() is the I2C host send function, please default it to be valid

    -----------------------------------------------------

    I am connecting the sensor INT to the one of GPIO port in my evb (such as PTA17), while reading the pin value of PTA17 every time the result register is triggered by a keystroke, so that when the value of the result register exceeds the upper and lower limits, the pin of PTA17 should change according to this logic. But in reality it does not, the pin value of PTA17 is always the initial value of 1.

    code in below:

    while(1)
    {
    pinstate = KEY_Proc(1);
    if(pinstate == BTN1_PRES ) //key1 Trigger

    {
    calculate_lux();// read result Reg
    u1_printf("Lux is %f \r\n",calculate_lux());

    PTA17_sample = PINS_DRV_ReadPins(PTA)>>17   & 0x01; //Sampling of PTA17 

    u1_printf("PinValue of PTA17 is %d \r\n",PTA17_sample);
    delay_ms(800);
    }

    }

    //code of calculate_lux():

    float calculate_lux()

    {
    uint16_t iExponent, iMantissa;
    float final_lux;
    uint16_t rawlux = I2c_Master_Read_Byte(R_Result); //Please note that I2c_Master_Read_Byte() is the I2C host read function, please default it to be valid
    iMantissa = rawlux & 0x0FFF;
    iExponent = (rawlux & 0xF000) >> 12;
    final_lux = iMantissa * (0.01 * powf(2, iExponent));
    return final_lux;
    }

  • Hi Joheim,

    If '20' is written to either of these registers, it will not interpret it as 20 lux.

    When writing to the low and high limit registers, the data should be input in the same format as the result register, so the first 4 bits are the exponent value and the last 12 bits are the mantissa.

    Thank you,

    Brent Elliott

  • Hi Brent,

    I read the High and lower limit registers after direct input (such as low-limit 20) and found that the read value is correct.

    E.g
    u1_printf("Data of low-limit: %d \r\n",read_R_Low_Limit_data()); The value read by the serial port is correct, which means that my value has been correctly written to the High and lower limit registers?

    In addition to your suggestion,for the High and lower limit registers, the exponent value and the mantissa value together form the formula of lux, which is equivalent to two unknowns x. When I input, how can I convert the input value into this format (exponent + mantissa) with a fixed formula? Could you please provide me a similar formula? 

     btw I am using Auto-Rang mode

    The formula I have tried is (0xb000) | ((DATA * 100) / 2048), i.e. specifying the exponent field as the maximum value -> max.range. But this formula is not valid for many inputs.

    many thanks! 

  • Hi Joheim,

    For the value of the limit registers, if your low limit is 20 for example, you can choose any exponent, and then set the mantissa portion so that the lux formula results in your desired limit value.

    For example, you could make LE[3:0] = b1011 (highest range) and then set TL[11:0] = 0b1, since the LSB size is 20.48 at the highest range. This will make the low limit equal to 20.48 lux.

    If you want the low limit to be exactly 20 lux, you can use a lower range like range 0 since it has a higher LSB resolution. In this case you would make LE[3:0] = 0, and TL[11:0] = 0b11111010000 (2000 in binary, since 2000 * 0.01 per LSB is 20 lux).

    Also, are you able to provide any information on your application?

    Thank you,

    Brent Elliott

  • thanks for your reply!

    but like the formula I have tried '(0xb000) | ((DATA * 100) / 2048)' , what I hope to achieve is to enter the upper and lower limits, which can be converted into values that the registers can recognize. so does it mean that this register cannot implement this function?

    If each time the upper and lower limit are set, the exponent and mantissa must be used for construction, rather than a packaged function, which is less automatic

    In addition, why do I directly write the decimal number, and then read the upper and lower limit registers, and the returned decimal number is indeed the decimal number I wrote? What is the reason?

  • I think I get it.
    Suppose I enter decimal 20 directly into the register.
    If the value of the register I read is 0b10100, my compiler will think it is 20, but what actually takes effect is the value which calculated by the lux formula by using 0b10100 .

  • Hi Joheim,

    Yes. That is correct.

    Thank you,

    Brent Elliott