Introduction: Highly Sensitive Arduino Light Sensor

Picture of Highly Sensitive Arduino Light Sensor

In the Bioluminescence Community Project at BioCurious, we've been working with a number of bioluminescent bacteria and algae. We'd love to be able to measure accurately how much light these organisms produce. Unfortunately, the amount of light they produce is quite faint, and although the human eye can easily detect them after adapting to the dark, photographing them in action takes very long exposures (check out our Bioluminescent Hourglass instructable!), and/or professional camera equipment.

Needless to say, quantifying the light output of these faintly glowing moicroorganisms in a small test tube takes some specialized equipment...

What we ended up with is an Arduino with a highly sensitive light sensor inside a copper pipe (to isolate the sample from outside light contamination) writing results to an SD card.  We also added an LCD so that we could see results displayed real time.

Step 1: Materials

Picture of Materials
Total cost: ~$65, not including shipping costs ($75 for version with LCD display).
Most of this is the Arduino Uno ($30) + data logging shield ($20). Everything else is dirt cheap.

At the heart of our light meter is the TSL237S-LF, a highly sensitive Light-to-Frequency converter. This isn't your ordinary photoresistor or photodiode, mind you. Those devices measure light intensity based on voltage or current changes, which means that the smallest light intensity is determined by the smallest voltages or currents you are able to measure. A light-to-frequency converter like the TSL237, on the other hand, converts light intensity into a series of square-wave pulses. The lower the light, the slower the pulses. That means you can trivially increase the sensitivity by increasing the amount of time across which you count the pulses. Which means the lowest intensity is determined by the on-chip noise inside the sensor, resulting in occasional spurious pulses even without light coming in.

This particular sensor has a typical dark frequency of 0.1 Hz - one pulse every 10 seconds (and in practice, we've seen far fewer than that). With an irradiance responsivity of 2.3 kHz / (μW/cm2), that would correspond to 0.000043 μW/cm2. Converting from irradiance to illuminance (Lux) gets complicated because the latter depends on human brightness perception, but that would work out to no more than 0.0003 Lux. In comparison, other commercial light sensors typically bottom out around 0.1-0.2 Lux. If you want to go any more sensitive, you'd have to go to a photomultiplier tube that can literally count individual photons, but that puts you in a very different price range...

To illustrate how sensitive this sensor really is, as I was hooking up the sensor to the arduino, I was covering the sensor with my hand to see the signal drop, and I noticed that it didn't drop to zero - not even close. So I covered the sensor with my second hand... and it still didn't drop to zero! And of course, when we put the sensor inside the copper tube, it *does* go to zero. That means this sensor can see through both my hands - maybe 1.5-2 inch of meat and bones. Not bad for a $3.33 sensor!

Step 2: Preparing Sensor Housing

Picture of Preparing Sensor Housing
The sensor housing consist of a piece of copper tube, cut to the dimensions of the test tubes we wanted to use. Get yourself a cheap pipe cutter. I always get a childish glee out of using one of these: just clamp onto your tube where you want to cut, and tighten the screw on the cutter every couple of turns. After tightening a few times, the tube will fall apart effortlessly.

*Carefully* drill a hole in one of the endcaps, either through the bottom of the cap, or as low as possible on the side. Use eye protection, and a vice or pair of plyers to hold the cap in place - metal shavings in the eye are no fun! After you've drilled the hole, stick the endcap onto the copper pipe, and mark how far you can push it down without obstructing the hole.

A 0.1-μF ceramic decoupling capacitor was soldered between the GND and Vdd leads of the sensor (as recommended in the data sheet). We're using a 12 inch piece of stereo cable from an old pair of earbuds to connect the sensor to the arduino (the data sheet recommends using a buffer or line driver for distances over 12".) The stereo jack also provides us with a very simple 3-wire connector. The cable on these earbuds often looks like it contains two wires, but it actually contains *four*: left channel, right channel, and one or two ground wires. Remember to thread the cable through the hole in the endcap *before* soldering the wires onto the sensor.

The light sensor + capacitor is potted in the endcap using black Sugru. The leads of the sensor were doubled back underneath the sensor to save space. See the cross section above for how everything is packed in. The Sugru serves a bunch of different purposes here:
  • Holds sensor, cap and wires firmly in place - important because we'll be shaking the heck out of this housing!
  • Acts as insulator between the leads
  • Provides a "bumper" so the test tube doesn't bang into the sensor while shaking
  • Prevents light leaking in through the hole in the copper endcap
  • Prevents copper tube from cutting off the cable carrying the signal
  • Provides stress relief for the cable
  • Provides some water proofing (in case we need it)
To encase the sensor, start by putting a layer of Sugru in the bottom of the endcap. Then squish a ball of Sugru onto the back of the sensor+capacitor, and fold the leads of the sensor over that ball. Make sure the Sugru gets in between all the leads and insulates everything. If you're paranoid, you could apply some thin shrink tube or liquid tape on the leads first, but that will take up more space in that very tight endcap. Once you're happy with how you've encapsulated the back of the sensor and all the wires, pull the earbud cable through the hole in the endcap to take up all the slack, and very gently press the sensor wad into the layer of Sugru at the bottom of the endcap. Now form a little donut of Sugru, sick that on the end of a retracted ballpoint pen, and seat that litle donut as a bumper around the front of sensor. Make sure the little dome of the sensor is completely unobstructed. Wet the copper pipe, and push it down into the endcap, stopping before the pipe reaches the hole in the side of the endcap (that's why you marked that level on the outside of the pipe earlier). Gently pull the pipe back out and check it has indented some of the Sugru around the inside edge of the endcap (if not, add a little ribbon of Sugru around the outside edge and try again), without disturbing the sensor itself. As a final touch, squish a tiny bit of Sugru into the hole the earbud cable is coming out until you are confident the metal won't cut the cable there, and then add a good dollop of Sugru more on the outside of the hole, to act as stress relief on the cable.

Step 3: Hardware Store Project Box

Picture of Hardware Store Project Box

Inspired by the Dirt Cheap Arduino Enclosure Instructable by sonicase, we used a cheap electrical box from the hardware store as a project box. Not bad for a $2 enclosure that fits your Arduino perfectly! You just need to cut a few holes in the side for the power plug on the arduino (conveniently located behind one of the removable tabs on the electrical box), and the USB plug. Plus a slot for the SD card on the data logger shield, and a hole to mount the stereo jack where you plug in the cable coming from the sensor.

If you cram things in really carefully, you can even mount the LCD in the matching plastic cover that you can get at the hardware store as well. However, if you want to use jumper wires to connect the LCD to the Arduino, rather than soldering everything in place, you'll quickly run out of space for all the headers and jumper wires on the data logging shield and LCD. Easy solution: simply get a second electrical box, and mount that one on top of the first! Now you have a double-height project box, with room for one or two more Arduino shields if necessary.

Step 4: Electronics

Picture of Electronics

Hooking up the electronics is fairly straightforward: Mount the Data Logging Shield on top of the Arduino Uno, and install the battery and initialize the Real Time Clock as described on the Adafruit website. Then wire up the stereo jack so GND and Vdd on the sensor are connected to GND and 5V on the Arduino, and the OUT pin from the sensor goes to Digital pin 2, where it can trigger interrupts on the Arduino.

If you're using a 16x2 LCD display, wire it up to headers on the data logging shield as described on the Adafruit website as well (the potentiometer to adjust the LCD contrast can be mounted on the spare prototyping area on the shield). As you can see from the pictures above, connecting the LCD with jumper wires takes a good amount of space. We tried to fold the jumper wires flat to make everything fit under the grey lid, but eventually we wound up stacking a second electrical box, for a double-high enclosure. (Feel free to ignore the additional Cat5 connector that we hooked up to some of the remaining pins. That one is intended for an optional accelerometer - if we're measuring light output of bioluminescent algae in response to shaking, it would be nice to be able to measure exactly how hard we're shaking them. We haven't yet used this feature so far, and the arduino code below doesn't include the accelerometer.)

The Arduino code for the version without LCD can be found here, with LCD here.

Step 5: Results!

Picture of Results!

The chart above shows the results from one of our experiments, testing how quickly dinoflagellates recuperate after having their bioluminescence exhausted by excessive shaking. Dinoflagellates are bioluminescent single-celled algae that light up when being perturbed. However, each cell only contains a limited amount of luciferin, so if you shake them for too long or too hard, their light output will quickly drop off.

The first peak in the graph above is a control test tube (~5ml) of dinoflagellates placed in the sensor tube, and then vortexed to entice bioluminescence. You can see a sharp peak followed by an exponential decay as the cells get exhausted.

We then shook a bunch of test tubes simultaneously until almost exhausted, and took one tube every five minutes to test in the light meter - shaking the tube again on the vortexer while measuring its light output. You can see that over the course of forty minutes, the cells show a marginal amount of recovery. A longer set of experiments we performed later suggested that the recovery half-time for these cells is likely to be on the order of several hours, so once the dinoflagellates are exhausted, it may take them most of the rest of the night to recover...

The graph shows raw pulse counts, integrated over 5 second intervals. Our control tube peaked at 44 pulses in 5 seconds, or 8.8Hz. Given an irradiance responsivity of 2.3 kHz/(μW/cm2), that corresponds to 0.0038 μW/cm2, or about 0.026 Lux.

Mission accomplished - quantitative light measurements on tiny volumes of faintly glowing bugs :-)

Comments

metapulp made it! (author)2017-03-05

I have been working with this project and built it without the clock or LCD monitor, outputting to the serial monitor (and Cooltech). I transferred the initial data to Excel. (I am a total newbie to Arduino by the way, so anyone can do this project.) Here is a chart showing pulse count per second and corresponding uWatt/cm2 on my second successful trial. The high pulse count comes from sensing computer monitor light, the low from covering the sensor. The other image shows how to easily put this project onto a breadboard.

wyldbyl (author)2015-08-04

Hi,

I subsequently built the LCD version and it worked OK except that the CSV files logged had no header written to them. I found out that you need to open the log file, write to the log file, and then close the log file to have the header properly written to it.

I changed your code in this section:

logFile.println("millis1,time1,count,uWattpercm2,millis2,time2");
#if ECHO_TO_SERIAL
Serial.println("millis1,time1,count,uWattpercm2,millis2,time2");
#endif // attempt to write out the header to the file

To this:

logFile= SD.open(fileName, FILE_WRITE);
logFile.println("millis1,time1,count,uWattpercm2,millis2,time2");
logFile.close();
#if ECHO_TO_SERIAL
Serial.println("millis1,time1,count,uWattpercm2,millis2,time2");
#endif // attempt to write out the header to the file

The changed code will now write the header to the CSV file.

I also had to use older Arduino IDE version 1.0.5-r2 to compile the sketch.

I had compiling errors when I used the latest Arduino IDE version 1.6.

wyldbyl (author)2015-07-30

Hi,

I just finished building this
project and I am hoping you can help me with a problem I am having. The
CSV logger files that it is generating have no data in them. I built the
version with no LCD display. The data logging shield was activated
properly. The light sensor is also working OK because I just just
checked the output (Arduino digital pin2) on my oscilloscope and it is
putting out a nice 5v square wave, the frequency of which, increases
with increased light input. No matter what the light intensity is I just
keep getting empty CSV logger files with no data in them.

I
initially had trouble getting your ino file to compile with the latest
version of Arduino IDE ( ver 1.60 ) . I kept getting errors that said it
could not find some libraries.

I uninstalled v1.6 and installed
earlier version v1.0.5 r2 and it compiled and uploaded to the Arduino
Uno just fine. I am planning to measure light levels of
Electroluminescent light panels that I am building from scratch by
making my own EL inks. I 3D printed an enclosure for the sensor that I
can place on top of my EL panels and measure the light intensities. I am
real a newbie at using Arduino microprocessors and hope you can help
me. Thanks.

EhrenW (author)2015-03-09

This project looks awesome. In step 4 you say, "Then wire up the stereo jack so GND and Vdd on the sensor are connected
to GND and 5V on the Arduino, and the OUT pin from the sensor goes to
Digital pin 2, where it can trigger interrupts on the Arduino." I didn't see a stereo jack listed in the materials. Could you point me to an appropriate part to order? Thanks for instruction, I'm excited to get started.

je-jerem (author)2014-11-16

Hi!

Many thanks for this Instructable which was really Instructable! However, I still have a little problem and I wonder if you could help me. I did everything and everything works well but my LCD displays weird characters (see picture) and I cannot fix the problem. I dont know why. My wirings are good and if I try with an example from LCD libraries (Arduino) it works well.. I thought it was a baud rate problem but actually I am not really sure.. My Arduino is a UNO ATMEGA328P 16MHz and my LCD reference is NHD‐0216K1Z‐NSPG‐FBW‐L.. I, ever, you could help me I would be really pleased.

Many thanks anyways and thanks again for this instructable.

briandegger (author)2013-12-17

great stuff!

About This Instructable

33,608views

61favorites

License:

More by Patrik:Highly sensitive Arduino light sensorGhost Heart in a Jar!Small leatherwork projects
Add instructable to: