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: Unexpected value of configuration register

Part Number: OPT3001
Other Parts Discussed in Thread: OPT3007

Hi, all

We have used opt3001 sensor on imx6dl platform, and using the driver with https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/iio/light/opt3001.c to read/write lux in our products.

we read the device node file of  in_illuminance_input to get lux every 2 seconds in our program. 

It can not work normally when the program run for serveral days, and I using cat command to get lux, the result is:

# cat in_illuminance_input
cat: read error: Connection timed out

using i2cget command to read the configuration register from opt3001, the result is:

 i2cget -f 5 0x44  1 w

0x9fc0

From the result, I found POL and FC bits has been changed, in default, the POL is 0, and FC=00, but when it can't work normally, POL is 1, and FC=11

I analyzed the source code of opt3001.c and found POL and FC fileds of the configuration register is only changed in
opt3001_configure, but it only called when the driver has been probed.

So, I don't know which operation will change the value of POL and FC, and set them to unexpect value.

Best

Liang. Zhou

  • Hi Liang,

    If the result from the configuration register is 0x9FC0, then FC=00 and POL=0 since these are bits 2:0 of the configuration register. What is the configuration register result when POL=1 and FC=11?

    Thank you,

    Brent Elliott

  • Thank you for your reply.

    1. 

    I am Using "i2cget -f 5 0x44  1 w"  to get the value of configuration register , the result is 0x9FC0 ( bits 7:0 is 0x9F because of the byte order), so bits 2:0 is 111b.

    I have done a further test by using i2cset to set the configuration  register:

    i2cset -f -y 5 0x44 1 0x17C0 w     (bits 7:0  is 0x17,   so this command can set PL to 0)

    By doing this, we can read lux from in_illuminance_input, the result is:

    root@ /sys/bus/iio/devices/iio:device0# cat in_illuminance_input
    30.540000

    2.  The same problem occurred on another machine, and the result from configuration register is: 0x1ffa, the real value of the
    configuration register is 0xfa1f because of the byte order.

    Thank you

  • Hi Liang,

    I'm taking a look at this and I will get back to you soon.

    Thank you,

    Brent Elliott

  • OK, thank you!

    Liang. Zhou

  • Hi Liang,

    It seems like for some reason the I2C is changing the configuration register after a certain point in time. This is not expected to happen and may require some troubleshooting on your side to determine how long it takes for this issue to occur and if there are other factors that could contribute to it since the opt3001.c file should not set the configuration register to these values.

    Thank you,

    Brent Elliott

  • Hi Brent Elliott,

    we have done some tests, the problem arises when the machine is running for about five days,  and there is only one program operates on the opt3001 device file.

    If the value of configuration register is not correct, the driver will failed at line 280 in https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/iio/light/opt3001.c

    Thank you!

    Liang

  • Hi Liang,

    Are you able to capture the I2C waveform during the failure?

    This code is not directly supported so we will not be able to be able to help with debugging it. We do have a c code drive which we are more able to support and can be run on any platform including Linux.

    https://e2e.ti.com/support/sensors-group/sensors/f/sensors-forum/872229/faq-opt300x-family-parts-what-are-the-available-drivers-for-ti-s-family-of-ambient-light-sensors

    Thank you,

    Brent Elliott

  • Hi, The driver we used is as same as you refer to, and we are still doing more test on opt3001, we will try to capture the I2C waveform when we encount the failure.

    Thank you

  • Hi Liang,

    The driver I was referring to in the link I shared is called "52520.OPT3007-C-Driver-Example.zip". It is configured for the OPT3007, but you can configure it for OPT3001 by updating the TI_OPT3007_BUSADDRESS defined on line 15 of opt3007_hostControl.h.

    Thank you,

    Brent Elliott

  • Hi Liang,

    I am closing this thread for now. Please let me know if you need further help.

    Thank you,

    Brent Elliott

  • Hi, Brent Elliott

    OK, we are doing more test on opt3001, and the unexpected configuration register value is hard to reproduce, If we find more clues, I will consult you.

    Thank you!

  • Hi, Brent Elliott
    we have using an Arduino microcontroller to read the configuration register, and there is only opt3001 has connected to the microcontroller, the test program is continuously read the value of the configuration register, the value is correct at first, but after it runs for sixteen days, it value is become invalid,
    the value of configuration register is toggles between 0xFE9F and 0xFE1F.

    when we reboot opt3001, the read value is normal again(The value is 0xc810).

    Thank you!

    Liang

  • Hi Liang,

    Were you able to capture the waveform of the failure? Have you tried using the OPT3007 driver to see if the failure still occurs or have you written your own code on the Arduino?

    Thank you,

    Brent Elliott

  • 1. We use out own code on the Arduino , the test program run on Arduino is as below, it is only read value from configuration register and determine if this value is correct:

    #include <U8glib.h>
    #include <Wire.h>
    #include <math.h>
    #include <stdlib.h>

    //Init LCD Init pins
    #define SCK 13
    #define MOSI 11
    #define CS 10
    U8GLIB_ST7920_128X64_1X u8g(SCK, MOSI, CS); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17

    //control pins
    #define REMOTE_CTR 2
    unsigned int value;
    unsigned int reading = 0;

    void show_running(unsigned long value)
    {
    char value_str[10];
    sprintf(value_str, "%s %d","value:", value);

    //Display configuration register value on LCD
    u8g.firstPage();
    do {
    u8g.drawStr( 0, 60, value_str);
    } while ( u8g.nextPage() );
    }

    //Display error message
    void show_error_setting(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "error");
    }


    //Display normal message
    void show_right_setting(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "right");
    }

    void setup()
    {
    Wire.begin();
    Serial.begin(9600);//init Serail band rate
    }

    void loop()
    {
    Wire.beginTransmission(0x44); // transmit to device #112
    Wire.write(byte(0x01)); // sets register pointer to echo #1 register (0x02)

    // request reading from opt3001 sensor
    Wire.endTransmission();
    Wire.requestFrom(0x44,2);
    if (2<= Wire.available())
    {
    reading = Wire.read(); // receive high byte (overwrites previous reading)
    reading = reading << 8; // shift high byte to be high 8 bits
    reading |= Wire.read(); // receive low byte as lower 8 bits
    value=reading;

    // print the reading
    delay(300);

    if (value==0xc810) //
    {

    Serial.println("right");
    u8g.setFont(u8g_font_unifont);

    u8g.firstPage();
    do{
    show_right_setting();
    }while ( u8g.nextPage() );
    }
    else
    {
    Serial.println("error");
    Serial.println(value);
    u8g.setFont(u8g_font_unifont);

    u8g.firstPage();
    do{
    show_running(value);
    }while ( u8g.nextPage() );
    }

    }
    else
    {
    Serial.println("error");
    u8g.setFont(u8g_font_unifont);
    show_error_setting();
    u8g.firstPage();
    do{
    show_error_setting();
    }while ( u8g.nextPage() );
    }
    }

    2. The Arduino hardware schematic is as below:

    Arduino_Uno_Rev3-schematic.pdf
    The opt3001 is connected to AD4 and AD5 of Arduino, and it connect with a 10-kΩ resistor to power supply.



    3. As we described previously, the invalid value appeared when this program runs for 16 days. 

    4. We have captured a failure waveform before when the program runs for about 10 days, but the waveform is too short, it only shows the incorrect value reading from the
    configuration register.
  • Hi Liang,

    It looks like you do not have any pull-up resistors between your I2C lines and Vdd. You have a pull-up resistor for your INT pin but you need one for each I2C line as well. This could be the cause of the issue unless you have set internal pull-ups in the Arduino.

    Thank you,

    Brent Elliott

  • Hi, Brent Elliott

     We have connected an external 10-kΩ resistor for each i2c lines in this test,  I am sorry for that the pull-up resistors of I2C lines is not shown in the picture.

    Thank you

    Liang

  • Hi Liang,

    Do you have a picture of the I2C lines? Also, since this post has been open for 30 days, could you post a new thread with the same issue, this post may lock soon due to being open for too long.

    Thank you,

    Brent Elliott

  • Closing this thread and picking this up in the new thread.