Sign in to follow this  
Followers 0
Marc

OPT3001 and MSP430

26 posts in this topic

Hi, does anyone have experience with the OPT3001 sensor using custom hardware or interfacing to the msp430 launchpad? I have a sensor on the TI opt3001EVM daughter board, with the SDA pins and SCL pins connected to vdd via 10k resistor, for a msp430fr5969 wolverine launchpad - I am able to read the data from the sensor, but every time I rapidly change a test light source (flash a light on the sensor, or put my hand to cover it), I get a corrupted reading (it reads FFxx). I currently have it set to poll at 100ms, and at autoscale with no mask. The autoscale does work, it's just during transition periods the first byte is read 0xFF.

The sensor works fine using the TI OPT3001EVM module.

Thanks for any insight or help!

  • The configuration register is set to the following value - 0b1100010000010000

    - Automatic full scale setting mode

    - 100ms conversion time

    - Continuous conversion mode

    - Mask field disabled

    - latched mode enabled

 

Share this post


Link to post
Share on other sites

Although it may be something else, one thing you may want to try is lowering the SCL and SDA resistors down to 2-5K.  Depending on your bus capacitance, 10K resistors may not be strong enough pull ups.

Marc likes this

Share this post


Link to post
Share on other sites

I tried various resistors (ranging from 1k-5k) but still no luck...under a scope it looks like the data is being sent correctly from the sensor, it just doesn't reflect the value read within the msp430 processor.

Share this post


Link to post
Share on other sites

While not actively working with the opt3001 yet (it's a component in a design I'm working with), I also have spent more than a little time reading the docs.  What caught my attention is in section 7.4.1 of the specs (sbos681b.pdf):

"If the measurement exceeds the full-scale range, resulting from a fast increasing optical transient event, the
current measurement is aborted. This invalid measurement is not reported. A 10-ms measurement is taken to
assess and properly reset the full-scale range. Then, a new measurement is taken with this proper full-scale
range. Therefore, during a fast increasing optical transient in this mode, a measurement can possibly take longer
to complete and report than indicated by the configuration register conversion time field (CT)."

 

The question is: What is "fast" in regards to "optical transient" and how long is "longer" regarding measurement time? I see you're using a 100ms timing for your reads, but I wonder if the docs are suggesting that you could still be requesting data before a valid conversion has completed?

Further, the device has two "conversion time" modes: 100ms and 800ms, and nothing in between. 

 

Have you tried working with the 800ms mode? I don't know your requirements, but the 3001 needs time in lower light situations to gather enough photons and then calculate a result. 

Are you checking the "Conversion ready field" (pg. 22, table 11) before reading the result?

 

HTH

Bob

Marc and Fmilburn like this

Share this post


Link to post
Share on other sites

Thanks for the insight @@NurseBob! Yes, I do recall reading about the transient response, and have done a side by side comparison with the OPT3001EVM evaluation kit. I have tried experiments where I swing a light across the sensor rapidly across both the evaluation module and my msp430 board. The msp430 board returns a corrupted value, while the evaluation module responds with no problems.

 

I have tried checking the "Conversion Ready" field before making a read, but I still get corrupted values read on the msp430.

 

Also, I have checked the sensor signal coming from a logic probe, and the values do seem to come out as un-corrupted values during rapid transitions. It's odd that they don't on the msp430.

Share this post


Link to post
Share on other sites

Thanks @@Rei Vilo, I am currently using the Energia OPT3001 library, and experiencing the same issues with the example code. I did purchase an educational boosterPack MK-II to make sure it's not a hardware issue, but so far the issue seems to be consistent on both the Wolverine and Tiva C launchpads with the energia library.

Share this post


Link to post
Share on other sites

Marc,

 

I wish I could be a better resource. From your description of "side by side" I'm guessing you have both an EVM and a pcb-mounted 3001?  I'm aware the EVM has a set of "test pads" and the ALS can be disconnected from the USB interface.  Have you tried the same experiment using the EVM's sensor connected to the LP?  That may be a route to tracking down where the errant data is being originated.  My one minor complaint with the EVM  is there's a bit of magic going on in the UI, which hides the code its executing, so there's no "Oh, I see, they're doing 'x' and I'm not..."

I was just experimenting with the EVM and trying to see what I could hack via its HID interface, but no luck there, and I don't have the time right now to hook up a logic analyzer to see the communication between their UI and the ALS.

 

Bob

Marc likes this

Share this post


Link to post
Share on other sites

Thanks @@Rei Vilo, I am currently using the Energia OPT3001 library, and experiencing the same issues with the example code. I did purchase an educational boosterPack MK-II to make sure it's not a hardware issue, but so far the issue seems to be consistent on both the Wolverine and Tiva C launchpads with the energia library.

I'll take some time as soon as I can to look at what's happening with the educational booster pack under CCS, maybe something will show up there.

Share this post


Link to post
Share on other sites

Thanks Bob, I really appreciate the help! I took a look at the OPT3001EVM module:

 

It looks like it's reading the configuration bit, waits 13ms, reads the value, then waits another 45ms for the next cycle. There is no signal on the interrupt bit. Here are the captured waveforms.

cd4cf221315d83e340d2a2660a48ddcf.jpg

Instead of my sensor I mounted 2k resistors on the OPT3001EVM daughter board SCL, SDA and INT pins, then connected it directly to the msp430 as you suggested - oddly I am seeing that the configuration bit and the value are correctly captured in the logic probe, but when doing a Serial.print to the captured values on the UART it seems that the first byte for both the configuration bit and the value is read as 0xFF.

 

8fbdf0664e1c77360992a0a773388ce4.jpg

So although the sensor is properly sending out a proper configuration register value and raw value (0xC490 and 0x1EDB), the msp430 somehow misses the first byte (0xFF90 and 0xFFDB).

8496a5c1b36e77911fc1eb3fa0150db7.jpg

I tried it on the TivaC as well, and see the same results.

Share this post


Link to post
Share on other sites

Marc,

The following may, or may not, be of any use, or just plain dumb...

 

per my logic analyzer the I2C comms are like you noted, clean data.

The one thing that jumps out at me when looking at your captures is you have a NAK in your sequence, where the EVM doesn't

I'm not literate enough in this realm to say whether that's of significance or not...

 

0.010158708 I2C Setup Write to [0x88] + ACK

0.010704458 I2C 0x01 + ACK

0.01136225 I2C Setup Read to [0x89] + ACK

0.01192375 I2C 0xC4 + ACK

0.012475292 I2C 0x90 + ACK

0.026159042 I2C Setup Write to [0x88] + ACK

0.026704833 I2C 0x00 + ACK

0.027362625 I2C Setup Read to [0x89] + ACK

0.027924125 I2C 0x03 + ACK

0.028475667 I2C 0x4B + ACK

0.074160167 I2C Setup Write to [0x88] + ACK

0.074705958 I2C 0x01 + ACK

0.075363708 I2C Setup Read to [0x89] + ACK

0.07592525 I2C 0xC4 + ACK

0.07647675 I2C 0x10 + ACK

0.010158708 I2C Setup Write to [0x88] + ACK

0.010704458 I2C 0x01 + ACK

0.01136225 I2C Setup Read to [0x89] + ACK

0.01192375 I2C 0xC4 + ACK

0.012475292 I2C 0x90 + ACK

0.026159042 I2C Setup Write to [0x88] + ACK

0.026704833 I2C 0x00 + ACK

0.027362625 I2C Setup Read to [0x89] + ACK

0.027924125 I2C 0x03 + ACK

0.028475667 I2C 0x4B + ACK

0.074160167 I2C Setup Write to [0x88] + ACK

0.074705958 I2C 0x01 + ACK

0.075363708 I2C Setup Read to [0x89] + ACK

0.07592525 I2C 0xC4 + ACK

0.07647675 I2C 0x10 + ACK

 

However, looking at the USB HID report messaging that follows,

note that every 3rd and 4th report is addressed as 00 FF

while the 1st and 2nd messages are the write request and the read of the data.

FWIW, I don't see how the USB data could be infiltrating your I2C data, but it's interesting...

Hopefully, over the weekend I can connect the sensor to one of my 5529 devices and experiment... (I need to do this for my own project)

If I find out anything new, I'll let yoiu know.

 

(The following is a capture of a few USB report messages using HIDAPI Test Tool - a TI USB utility)

 

 

Received 32 bytes:
00 88 00 01  00 00 00 89  00 c4 00 90  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 88 00 00  00 00 00 89  00 03 00 7c  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 ff 00 00  00 00 00 00  00 00 00 00  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 ff 00 00  00 00 00 00  00 00 00 00  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 88 00 01  00 00 00 89  00 c4 00 10  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 88 00 00  00 00 00 89  00 03 00 7c  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 ff 00 00  00 00 00 00  00 00 00 00  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 ff 00 00  00 00 00 00  00 00 00 00  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 88 00 01  00 00 00 89  00 c4 00 90  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 88 00 00  00 00 00 89  00 03 00 7c  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 ff 00 00  00 00 00 00  00 00 00 00  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01  

Received 32 bytes:
00 ff 00 00  00 00 00 00  00 00 00 00  00 00 00 00  
00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 01

Share this post


Link to post
Share on other sites

Thanks for sharing @BobNurse, it's interesting that it's a NAK instead of an ACK. I wonder if this has to do something with Energia's wire implementation?

 

It's interesting that the USB messages also reflect 'missed' data reports. To see if the USB reporting had anything to interfere with the i2c, I tried an experiment where instead of reporting the received data on the USB after each i2c read, I had it so that the msp would log 10 data points, and then spit out the 10 readings via USB once the 10 i2c readings were completed. The results however still indicated that the data still was corrupted during the i2c reads (that technically had no USB interference). It really is an odd issue.

Share this post


Link to post
Share on other sites

When I look at your logic analyzer results, it feels like there's either a bit being dropped, or that there's been a shift in the interpretation of the data.  The NAK may be an artifact.

I am out the door in a few to do my "real" job as a nursing instructor, but on my return I'm going to be exploring in greater depth the output I'm seeing from the educational booster pack.  The serial output I'm seeing is not sensible or consistent. So I plan to step through the Energia Sketch code for the opt3001 to see what's happening.  Having control over the rate of communication should allow me to see both sides of the I2C exchange, and maybe identify what's so odd.

 

File Capture data: - device positioned a  few inches away and below a "white" screen, readings once per second

LUX Readings = 40
LUX Readings = 40
LUX Readings = 41
LUX Readings = 3976 ?
LUX Readings = 150
LUX Readings = 4090
LUX Readings = 66
LUX Readings = 41
LUX Readings = 40
LUX Readings = 40
LUX Readings = 40
LUX Readings = 4053 - hand covers the sensor
LUX Readings = 1
LUX Readings = 1
LUX Readings = 0
LUX Readings = 24
LUX Readings = 40
LUX Readings = 4016 - sensor briefly uncovered
LUX Readings = 0  - sensor completely obscured
LUX Readings = 0
LUX Readings = 0
LUX Readings = 40 - uncovered
LUX Readings = 40
LUX Readings = 40
LUX Readings = 40
LUX Readings = 21
LUX Readings = 21
LUX Readings = 21
LUX Readings = 21
LUX Readings = 21
LUX Readings = 21
LUX Readings = 21
LUX Readings = 21
LUX Readings = 40
LUX Readings = 40
LUX Readings = 40
 

Share this post


Link to post
Share on other sites

Thanks @@Rei Vilo, I am currently using the Energia OPT3001 library, and experiencing the same issues with the example code. I did purchase an educational boosterPack MK-II to make sure it's not a hardware issue, but so far the issue seems to be consistent on both the Wolverine and Tiva C launchpads with the energia library.

 

 

Are you referring to this library at SensorsWeather_Library

 

It works fine on my CC3200 LaunchPad.

Marc likes this

Share this post


Link to post
Share on other sites

One thing I think I'll try is a non-Energia I2C direct approach to see if Energia timing issues are playing a role. I'll be adapting the F5529 sample code to read the device and then send it to a USB display. My reason for a non-serial display approach is based on the USB's ability to handle conversations on a millisecond time frame. And, a good learning experience.

Share this post


Link to post
Share on other sites

I know how you feel @@NurseBob, wow nursing instructor at day, developer at night?

 

Thanks @@Rei Vilo, I downloaded the SensorsWeather_Library and hooked up my sensor to the CC3200 launchpad. It works without glitches now!

There is still a NAK at the end of the wire transmission, but the CC3200 seems to have no problem getting the correct value.

I am more convinced that it is some timing issue with the energia wire implementation.

Rei Vilo likes this

Share this post


Link to post
Share on other sites

I think I have found the issue:

 

In the energia opt3001.cpp code (line 77) the implementation for the register read readRegister(uint8_t registerName) declared the lsb, msb and result variables as int8_t.

 

(line 79, OPT3001.cpp)

int8_t lsb;
int8_t msb;
int16_t result;
 
I changed this to unsigned, as they are supposed to be:
uint8_t lsb;
uint8_t msb;
uint16_t result;
 
The code now works. Thank you for sharing your library @@Rei Vilo, I was able to realize this by doing a side by side comparison with your code. I hope this will prevent any issues you may have with your project @@NurseBob!

Share this post


Link to post
Share on other sites

 

I think I have found the issue:

 

In the energia opt3001.cpp code (line 77) the implementation for the register read readRegister(uint8_t registerName) declared the lsb, msb and result variables as int8_t.

 

(line 79, OPT3001.cpp)

int8_t lsb;
int8_t msb;
int16_t result;
 
I changed this to unsigned, as they are supposed to be:
uint8_t lsb;
uint8_t msb;
uint16_t result;
 
The code now works. Thank you for sharing your library @@Rei Vilo, I was able to realize this by doing a side by side comparison with your code. I hope this will prevent any issues you may have with your project @@NurseBob!

 

Ahh!!!  A bit of magic. :)

Great catch.

Share this post


Link to post
Share on other sites

I suspect there is a math error in the OPT301.cpp file.  Shining a bright source on the sensor I see the sketch reporting a value of 131040 lux.  The maximum value the sensor can report is 83806 lux. After looking more closely at a pair of logic traces, I am wondering about the handling of the I2C transactions on the Energia side. I see ACK with the EVM, and NAK with the Energia code, though the magnatude of the values are close (0xBFFF for the Energia code, and 0xCC10 for the EVM)

Share this post


Link to post
Share on other sites

I believe there is still a problem in OPT3001.cpp.  The device has a max Lux value of 83886, but the readResult() method returns 131040 after a left shift of the raw result.
(forgive the double post; I thought the previous had not been sent...)

Share this post


Link to post
Share on other sites

Yes, another issue with the OPT3001.cpp (or is it?) is that instead of using the calculation methods of the datasheet, they use a shortcut using bit shifting to approximate the exponent multiplication constant. This is probably to keep the data as a uint32_t instead of a float.

 

To get the exact data as the OPT3001EVM, I replaced the opt3001::readResult() function on 146 of OPT3001.cpp (and the prototype in OPT3001.h to a float) to:

 

float opt3001::readResult()
{
uint16_t exponent = 0;
float result = 0;
int16_t raw;
raw = readRegister(RESULT_REG);
 
/*Convert to LUX*/
//extract result & exponent data from raw readings
result = raw&0x0FFF;
exponent = (raw>>12)&0x000F;
 
//convert raw readings to LUX
switch(exponent){
case 0: //*0.015625
result = result*0.01;
break;
case 1: //*0.03125
result = result*0.02;
break;
case 2: //*0.0625
result = result*0.04;
break;
case 3: //*0.125
result = result*0.08;
break;
case 4: //*0.25
result = result*0.16;
break;
case 5: //*0.5
result = result*0.32;
break;
case 6:
result = result*0.64;
break;
case 7: //*2
result = result*1.28;
break;
case 8: //*4
result = result*2.56;
break;
case 9: //*8
result = result*5.12;
break;
case 10: //*16
result = result*10.24;
break;
case 11: //*32
result = result*20.48;
break;
default:
result = 0;
}
 
return result;
 
}
NurseBob likes this

Share this post


Link to post
Share on other sites

Thanks for the clarification. I had also come to the realization that the bit shift was a shortcut that simplified coding, and in many cases wouldn't cause a problem with a board designed to show principles.

Share this post


Link to post
Share on other sites

I see I may need to further edit the algorthim for readResult(), since I want to see the decimal portion - my application is working in low light levels (between 0.05 and 0.5 lux).  So an integral result of 0 is a problem.  Ultimately, I won't really need the conversion as the intent is to set a range for the interrupts and change the state of my app based on the high/low interrupts.  But for now, I the serial output is handy for debugging.  So, back to the docs on page 20 calculating Lux.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0