TSL2591 light sensor using hardware interrupt

Hello everyone - I have am working on an interesting project and need some guidance. The tutorials and sample code I have found so far does not illustrate everything that I need to get done.

The project is to detect light events in a cave. Normally a cave is completely dark, and I mean COMPLETELY dark. It is not just close to zero lux, it IS zero lux. We want to place a sensor in a cave which will detect even a faint amount of light, wake up and record the time, then go back to sleep. Any amount of light however small means a human was there.

The system will be visited for service no more than twice per year and may sometimes go a full year between service. Battery life is a challenge.

I have Arduino ProMini, a real-time clock, an SD card reader and a TSL2591 light sensor. The immediate question is how to get the TSL2591 to work with HARDWARE interrupts. I have seen how to make it work with software interrupts. That won't work for this system because the Arduino must go to full sleep mode between events.

The idea is to set thresholds on the TSL2591, then make the Arduino go to full sleep. When the TSL2591 detects light, it triggers a hardware interrupt that wakes up the Arduino. An event is recorded to the SD card, then the system goes back to sleep.

Full sleep mode is critical to achieving the battery life we expect.

I have successfully done a project where the RTC generates a hardware interrupt every XX seconds which wakes up the Arduino. The temperature chip is read, the values and a time stamp recorded, and the Arduino goes back to sleep.

Now I need to do something similar, except the interrupts do not occur at regular intervals and they come from the TSL2591.

Has anyone done anything like this? Is there any sample code that shows how to use the hardware interrupt line from the TSL2591?

Thanks - Bill Gee

Are you using a Low Power library for putting your Arduino ProMini into deep sleep or are doing it “hard core”.

The idea is to set thresholds on the TSL2591, then make the Arduino go to full sleep. When the TSL2591 detects light, it triggers a hardware interrupt that wakes up the Arduino. An event is recorded to the SD card, then the system goes back to sleep.

Yes that sounds feasible. The TSL2591 consumes less than 5 uA when in power-down mode.

You’ll have to set up the i2c registers to allow for the TSL2591 interrupt pin to trigger when the light level has changed etc.

Then you’ll need to make sure that TSL2591 interrupt pin is corrected to an Arduino ProMini GPIO that can accept external interrupts. GPIO’s 2 or 3 are safe bets. Suggest reading the Arduino Reference guide to explain further.

Beware of mixing 5 volt devices with 3 volt devices. The TSL2591 light sensor interrupt pin may not be able to interrupt a 5 volt device. Testing will be necessary.

Paul

Regarding low-power library - I have not got that far yet. The test program that I have for reading the RTC temperature sensor does it the hard way. Well, I think it is the hard way! It did not seem that hard ... The sketch includes a library called avr/sleep.h, and the function calls are sleep_enable(), set_sleep_mode() and sleep_cpu().

Regarding voltage - I am using 3.3 volt/8mhz Arduino ProMini devices. I have found articles on removing various LEDs and taking out the voltage regulator. On my test bed the LEDs are gone but the regulator is still there.

I ran the temperature recording test for about a month running on three AAA NiMH batteries. The wakeup interval was five minutes. It probably could have run longer.

One of my friends has proposed using a phototransistor. I bought a package of them from eBay, but they ship from the U.K. and won't be here for a while. The value of the biasing resistor will be critical, but the programming might be easier.

Another concern I have with the TLS2591 is the sensitivity to IR. I think the interrupt is triggered based on light collected by the total detector - not the visible detector. That means bats could trigger an interrupt with their body heat. Advantage to the phototransistor since it is not sensitive to IR.

Bill Gee

You wrote: "Another concern I have with the TLS2591 is the sensitivity to IR. I think the interrupt is triggered based on light collected by the total detector - not the visible detector. That means bats could trigger an interrupt with their body heat. Advantage to the phototransistor since it is not sensitive to IR.".

By the data sheet, the interrupt is caused by the light level being either above the high level you set up or below the low level you set up when you program the device. There are limits for both visible light and IR.

Paul

That means bats could trigger an interrupt with their body heat.

The TSL2591 is completely unresponsive to the IR wavelengths (about 10 microns) emitted by warm bodies.

The general term "IR" covers an extremely broad range of wavelengths and no single detector covers all of them.

gerrikoio:
Yes that sounds feasible. The TSL2591 consumes less than 5 uA when in power-down mode.

Data sheet says max 4 µA in sleep mode, but can't find whether interrupts are active in that mode.

Paul_KD7HB:
Beware of mixing 5 volt devices with 3 volt devices. The TSL2591 light sensor interrupt pin may not be able to interrupt a 5 volt device.

It is an open drain output, but unclear whether that means it can safely be pulled up to 5V when the device itself is running on 3.3V.

Data sheet says max 4 µA in sleep mode, but can't find whether interrupts are active in that mode.

The data sheet is ridiculous in that regard. I looked over it carefully and was aghast at how little information is provided. What function does "sleep mode" serve?

It is incredibly stupid that you have to buy one of the sensors and experiment with it, in order to figure out what it actually does.

What function does "sleep mode" serve?

Looking at datasheet:

Pg 6: Operating Characteristics table: Sleep state - no I²C activity. So, does this mean one cannot communicate via I2C when in sleep mode or when no I2C comms then will go to sleep.

Then Pg15 describes the Enable Register (0x00):

NPIEN (bit 7) set, is the No Persist Interrupt Enable. When asserted NP Threshold conditions will generate an interrupt, bypassing the persist filter.

SAI (bit 6) set, then will Sleep after interrupt. When asserted, the device will power down at the end of an ALS cycle if an interrupt has been generated.

AIEN (bit 4) set, enables ALS Interrupt. When asserted permits ALS interrupts to be generated, subject to the persist filter.

AEN (bit 1) set, is ALS Enable. This field activates ALS function. Writing a one activates the ALS. Writing a zero disables the ALS.

PON (bit 0) set is Power ON. This field activates the internal oscillator to permit the timers and ADC channels to operate. Writing a one activates the oscillator. Writing a zero disables the oscillator.

All other bits reserved so stay set to 0.

Datasheet description of the Interrupt function is interesting. So in this case the "current light level would need to be 0" and when light above this value by x amount and remains so by t time then triggers an interrupt...

Extract: The TSL2591 also supports an interrupt feature that simplifies and improves system efficiency by eliminating the need to poll a sensor for a light intensity value. The primary purpose of the interrupt function is to detect a meaningful change in light intensity. The concept of a meaningful change can be defined by the user both in terms of light intensity and time, or persistence, of that change in intensity. The device has the ability to define two sets of thresholds, both above and below the current light level. An interrupt is generated when the value of a conversion exceeds either of these limits. One set of thresholds can be configured to trigger an interrupt only when the ambient light exceeds them for a configurable amount of time (persistence) while the other set can be configured to trigger an immediate interrupt.

Please post a link where you found that datasheet.

The one I have, "TSL2591 Datasheet - Apr. 2013 - ams163.5", has different page numbering and very little of that information.

Details and datasheet can be found here: TSL25911 | ams

That data sheet is more informative, but still has no information on whether interrupts are active during sleep mode.

@bgee11 please experiment and let us know if sleep mode is actually useful.

Update - The package of phototransistors arrived a few days ago. Using a 1 megohm resistor in series, I can definitely see the voltage across the photoresistor change depending on the light level. That is not connected to the Arduino - just a voltage source, phototransistor and resistor. Judging by the voltage levels produced, I think the resistor will have to be in the range of 3 or 4 megohm. I don't have such a critter ... I ordered a resistor assortment from Amazon.

Just for grins, I hooked the phototransistor up to the Arduino and ran a sketch that was taking interrupts from the RTC. I disconnected that line. The PT is hooked from VCC- to the interrupt pin, and the 1 megohm resistor from the interrupt pin to VCC+. No interrupts are generated. I am pretty sure that is because the sketch is enabling the internal pull-up resistor.

I can't get anything new onto the Arduino right now due to problems with the IDE not opening the serial port. That is an issue for another post.

Stay tuned, I will update as things happen.

Bill Gee

To measure low light levels using a photodiode, you need a high impedance, precision op amp circuit called a transimpedance amplifier. The Arduino alone won't work.

Here is one example of such a circuit, with some design information.

Hmmm..... Except this is not a photodiode. It is a phototransistor. Does that change things?

My understanding is that a phototransistor is a three-layer device where the emitter and collector function as normal. The base lead is the photo-sensitive middle layer, so light can be considered as providing the base voltage.

Bill Gee

Which exact phototransistor? Let’s start with that. It may not be suitable for your particular application.

You want to measure extremely low levels of light, which may last very short to boot. Not an easy thing to do.

First of all you have to define in absolute terms what the actual level is you want to detect. No doubt there are detectors out there that can count single photons, that’d be “the faintest amount of light”, taken to the extreme. Not going to be cheap, such a sensor.

Common detectors include indeed photodiodes and phototransistors. At least the photodiode can work in two ways: photovoltaic and photoconductive. A phototransistor only has the second option. Wikipedia says that both perform about the same for low light situations, with the photodiode the faster of the two.

In any case noise is probably going to be the main issue you have to deal with. The circuit as given in the link of #13 mentions 500 µV/lux as output, that’s no doubt a far too low voltage for your application. You want to go well below 1 lux, I suppose you will want to get an output of 5V at 1 lux, or at even lower light levels.

If you want to get serious about this project, you will have to define "even a faint amount of light" in quantitative terms.

I think this will be difficult for you, as detection of very low light levels requires considerable electronics expertise, carefully selected components and circuit design, and special PCB construction techniques. Absolutely NO MOISTURE can be allowed to get into a high impedance circuit.

It should be obvious that there is no point in building and placing a detector that cannot detect the light levels of interest.

Absolutely NO MOISTURE can be allowed to get into a high impedance circuit.

Major challenge in a cave (100% humidity at all times) and a circuit that's in sleep mode most of the time (no self-heating whatsoever). This probably requires potting.

Replying to several people at once here ...

The exact phototransistor I bought is a TEPT4400. The link on eBay is https://www.ebay.com/itm/5PCS-TEPT4400-AMBIENT-LIGHT-SENSOR-3MM-570NM-LOT-OF-5-UK-COMPANY-SINCE1983/202841326238 I tried it in several dark situations to see how it works. It seems quite sensitive. Hooked in series with a one megohm resistor and using a 3.6 volt supply (3xAAA NiMH in series), I put it inside a 6 quart cooler. It registered a voltage drop of about 80 mv. When I put a heavy jacket over the cooler, the voltage drop was less than 1mv which is the limit of my voltmeter. Raising a corner of the jacket and shining a flashlight on the outside of the cooler caused a drop of about 17mv. Based on that, the pull-up resistor should probably be in the range of 3 to 5 megohms. I have ordered a resistor assortment which includes those values.

Quantifying the light level to be measured ... We don't have an exact number. In general terms - As low as possible, but greater than zero.

Yes, the cave environment will make things difficult in some ways. At least the temperature is stable! The relative humidity is 100%, but it is almost never condensing because there is no temperature variation. Our idea is to put the entire device - Arduino, battery, sensors - inside a clear plastic jar. An empty peanut butter jar or mayo jar would work. A Nalgene bottle would be even better, but they are not as transparent.

At this point the whole thing is an idea. It is something to test. We don't know if it can be made to work. Photo transistor vs. TSL2591 is part of the testing and development effort. The use of interrupts seems to be about the only way to get enough battery life to make it practical.

One of my inspirations is a project to build water depth data loggers for use in caves. The project is documented at https://thecavepearlproject.org/ He pots the pressure sensor, but the rest of the circuit is in a fairly ordinary plastic container.

There are many challenges to my project. The most immediate challenge has nothing to do with the sensors! My main workstation will no longer open the serial monitor. I posted a question about that in another part of this forum. It is all for naught if I cannot get the sketch onto the Arduino.

Bill Gee

With resistors over about 1 MΩ you have to seriously start to worry about noise.

You're in the mV range, no chance there to get an interrupt, either. You have to poll the analog input - where a single unit in the reading represents about 1 mV when using the 1V internal reference. Probably not good enough for you.

You will have to boost this tiny voltage. I'd be looking at making your phototransistor part of a Wheatstone bridge, and amplify the signal with e.g. a HX711 instrumentation amplifier - those things are typically used for load cells, which are also measured using a Wheatstone bridge. To get your interrupt the output of the HX711 could then be further amplified with an OpAmp and/or be fed to a comparator which in turn can produce the voltage for the interrupt. A separate connection to the analog input would allow you to measure the actual light level upon interrupt; assuming the signal lasts long enough (a very short flash may have extinguished by the time the Arduino has woken and taken an analog reading).