TEMT6000 Ambient Light Sensor Hookup Guide

Pages
Contributors: Michael Bartlett
Favorited Favorite 5

Introduction

Light sensors have all sorts of practical uses in the modern era, most notably in devices with auto-brightness for their screens and in digital cameras to adjust exposure. With the Ambient Light Sensor Breakout, it's be a breeze to interface with the TEMT6000 Light Sensor so you can bring the ability to detect light levels to any project.

SparkFun Ambient Light Sensor Breakout - TEMT6000

SparkFun Ambient Light Sensor Breakout - TEMT6000

BOB-08688
$4.95
8

As the name suggests, the TEMT6000 Light Sensor will detect the brightness of its surroundings. While there are many properties of light that can help us categorize its brightness, the TEMT6000 measures illuminance (measured in lux (lx), often denoted Ev). Don't worry if illuminance is new to you though, the TEMT6000 is very intuitive to use: brighter = more current, darker = less current.

In this guide, we’ll show you how to quickly get the ambient light sensor breakout up and running, then discuss some of the more technical details of how it functions. After that, we’ll show you how to use it to make a practical DIY nightlight!

Required Materials

Here's what you'll need to follow along with this guide:

Suggested Reading

  • Check out our Light Tutorial for more information on the technical properties of light. An intuitive understanding of light should be enough to make use of the TEMT6000, but, if you're looking for more precise applications, this is worth the read.
  • This sensor is a phototransistor. Knowing how transistors work will be helpful in using the TEMT6000.
  • A voltage divider circuit is used to create a usable signal from the light sensor for a microcontroller. A basic understanding of voltage dividers is recommended.
  • To read the voltage coming from the voltage diverer circuit, an Analog to Digital Converter (ADC) will be necessary. This tutorial will show how to read the voltage on the ADC found on an Arduino microcontroller.
  • We recommend soldering some male header-pins to your TEMT6000 breakout to make it easier to use, so be sure to read our Soldering Tutorial for details on good soldering practice.
  • Knowing more about the TEMT6000 itself couldn't hurt, so here's a link to its datasheet.

Hardware Overview

As you can see from the image below, the TEMT6000 is about as simple as it gets when it comes to breakout boards. The three pins broken out are labeled on the top of the board.

breakout

The function of each pin can be found in the table below.

SymbolDescription
SIGOutput Voltage from the divider circuit
GNDGND (0V)
VCCCollector Voltage (should not exceed 6V)

Being a phototransistor, this sensor acts just like any other NPN transistor -- the greater the incoming light on the Base, the the more current that can flow from the Collector to the Emitter. Only light that falls within the visible spectrum (390–700 nm) will alter the Base. Infrared, ultraviolet, or any other light we can’t directly see will have no effect on the sensor.

This sensor can handle voltages from both 5V and 3.3V devices.

To make taking light measurements as easy as possible, this sensor has been designed into a voltage divider circuit. The TEMT600 acts as one of the resistors in the divider, and, as the light hitting it changes, so too does the voltage on the SIG pin. To read that voltage, simply connect the SIG pin on the TEMT6000 to any analog to digital conversion pin on your microcontroller.

schematic

The TEMT6000 Breakout schematic.

The voltage value returned from the SIG pin will vary depending on what voltage is being used to power the sensor and depending on the resolution of your ADC.

Hardware Assembly

First, let's fire up our light sensor and start collecting readings from it.

We recommend soldering male header-pins to the breakout to make it simpler to prototype with:

headers

The rest is just plugging parts into the RedBoard. Start by taking any basic LED of your preferred color and placing its anode leg (the long leg) into a pin whose label is followed by a ~. This mark on the RedBoard means the pin supports pulse-width modulation (PWM), which is just a technical way of saying we can control the voltage output of the pin digitally; in this case it lets us control the apparent brightness of our LED. We want this because our LED is going to show us the relative brightness of the world through the eyes of our TEMT6000. If you're using a different board, be sure to read its documentation closely to see which of its pins support PWM. Place the other leg into ground (GND).

We used pin 11 on the RedBoard because it is the PWM pin closest to a ground pin. Thus, we didn't have to deform our LED's legs too much. This is the pin we'll be using in the sample code, so be sure to modify that constant if you're using a different physical pin.

Next comes the light sensor breakout. Start by connecting the female ends of some male-to-female jumper cables to the pins we soldered to it earlier. Connect VCC on the sensor to the 5V pin on the RedBoard, GND to GND, and SIG to any analog pin (we'll be using A0 in the sample code). Use the table below to aid in wiring.

TEMT6000 PinArduino Pin
SIGA0
GNDGND
VCC5V

Here's a diagram of how the circuit should look:

Fritzing Diagram

Programming

Now we're finished with the hookup, it's time to upload some.

Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE.

If you have not previously installed an Arduino library, please check out our installation guide.

Using the mini-b USB cable, hook the RedBoard up to a computer with the Arduino IDE installed. Select the appropriate COM port, select Sparkfun RedBoard as your target device, and then upload the following code:

language:c
#define LEDPIN 11         //LED brightness (PWM) writing
#define LIGHTSENSORPIN A0 //Ambient light sensor reading 

void setup() {
  pinMode(LIGHTSENSORPIN,  INPUT);  
  pinMode(LEDPIN, OUTPUT);  
  Serial.begin(9600);
}

void loop() {
  float reading = analogRead(LIGHTSENSORPIN); //Read light level
  float square_ratio = reading / 1023.0;      //Get percent of maximum value (1023)
  square_ratio = pow(square_ratio, 2.0);      //Square to make response more obvious

  analogWrite(LEDPIN, 255.0 * square_ratio);  //Adjust LED brightness relatively
  Serial.println(reading);                    //Display reading in serial monitor
}

Once everything's uploaded, your LED should respond to the relative brightness that's exposed to the TEMT6000. Here's how the end result should look:

action GIF

Try oscillating the TEMT6000 towards the RedBoard's green "ON" LED to see the change.

How Light Detection Works

Now that our sensor is working, let's take a more in-depth look at what is going on inside the senor. As mentioned earlier, the TEMT6000 measures illuminance. If you're unfamiliar with illuminance, it is a measure of the total quantity of visible light emitted by a source (referred to as luminous flux, measured in lumens (lm) divided by an area in square meters. More notationally, 1 lx = 1 lm/m². Along with these, there are other properties of light that are unfortunately all named using the same Latin root for light, so it can be hard to keep them straight. Here's a diagram to hopefully elucidate the differences:

light diagram

Diagram depicting the nuances between the various measurements of light.

Why does the TEMT6000 measure illuminance? In most practices, measuring the intensity of light without factoring in distance is very difficult, and puzzled early astronomers for a long time. In short, there is apparent magnitude (how bright a source appears) and absolute magnitude (how bright the source actually is). Two sources of different absolute magnitudes can have the same apparent magnitude depending on their distance from the observer.

For example, if you have a bright source far away and a dim source very close, they can appear to have the same brightness because the brighter source's light will have to dissipate over a larger volume. This is why the sensor will read a smaller value if you move the same source of light farther away from it, essentially increasing the amount of space that the same amount of light has to fill between the source and the sensor (i.e. reducing the illuminance, as you're dividing by a larger surface area of the light-sphere generated by the source).

Here is a graphical relationship between the current (in µA) and illuminance of the immediate vicinity perceived by the sensor:

sensor graph

Found in the TEMT6000 datasheet.

The TEMT6000 only recognizes light with wavelengths in the range of 390–700 nm, which roughly covers the entire spectrum of visible light. In other words, this won't pick up infrared, ultraviolet, or any other light we can't directly see.

Here's a table of the typical illuminance from common sources of visible light:

illuminance

Now that we understand the TEMT6000 a little better, let's use it in something more interesting and build ourselves a night light that turns itself on and off!

Example Project: Night Light

Required Materials

We'll be reusing a lot of parts from before. In fact, the only difference is we're upping the ante and using an RGB LED instead of a single color LED! Nevertheless, here's a list of everything you'll need:

Hookup

Since we're reusing a lot of the same parts, they're mostly going to occupy the same pins on the RedBoard: VCC on the breakout should connect to 5V on the RedBoard, GND to GND, and SIG to A0.

TEMT6000 PinArduino Pin
SIGA0
GNDGND
VCC5V

The main difference is now we have an RGB LED that has twice as many legs, but the idea is still the same. The longest leg on a common anode RGB LED is going to be the pin that goes to the GND pin. Most Arduino boards have a group of three consecutive PWM pins, and these happen to be pretty close to a GND. If the legs on your LED aren't bent too bad, you should be able to see which is the second longest leg—that's the cathode for the red LED, and that should go to pin 9. Plug the remaining two legs into pins 10 and 11 in the orientation they appear to go in easiest. Use the image below, if you can't tell the difference between the legs.

RGB Polarity

This table should clarify, which pins are connected.

RGB LED PinArduino Pin
Red CathodePin D9
Common AnodeGND
Green CathodePin D10
Blue CathodePin D11

Here's what the setup should look like once everything is plugged in:

Fritzing diagram

Programming

The code for this one is going to look a little different. The challenge is that we want to cycle through all the colors without being stuck in a loop and unable to read light values until the loop is done. The way around this is to use a function that will take a variable that counts and returns a color based on how far that variable has counted. This way, for every "count" (cycle of the loop) we have time to stop and check our TEMT6000 for a reading. There are some other little tricks that are explained in the comments.

The drill for uploading the code is the same as before.

language:c
#define LS_PIN A0  //Light Sensor pin
#define R_PIN  9   //Red pin
#define G_PIN  10  //Green pin
#define B_PIN  11  //Blue pin
#define POWER  4   /* Power to raise the ratio of read-value to largest read-value. 
                    * Higher is less likely to be on during the day,
                    * but too high and it may not turn on once it's night.*/

#define TIME  500 /* The amount of milliseconds before taking a step through the color function.
                   * Higher values = slower transitions between colors.*/

uint16_t  _max =  0;  //Holds the largest brightness reading so far.
byte      count = 0;  //Keeps track of where we are on the color spectrum
float     ratio = 0;  //Stores the ratio of current brightness to largest recorded brightness.

void setup() {
  pinMode(LS_PIN,  INPUT);  //Reading in   
  pinMode(R_PIN,  OUTPUT);  //Writing out*
  pinMode(G_PIN,  OUTPUT);  //*
  pinMode(B_PIN,  OUTPUT);  //*
  Serial.begin(9600);
}

void loop() {
  float reading = analogRead(LS_PIN); //Take brightness reading
  if (reading > _max) _max = reading; //See if it's the brightest so far

  /* Calculate the ratio between the reading and the max, raise the power, and average it with
   * the last reading to get our ratio but minimize flickering. */
  ratio = (ratio + pow(1.0 - reading / float(_max), POWER)) / 2.0;
  /* We're subtracting the ratio from 1 because we want brighter readings to result
   * in a dimmer display of colors, and smaller readings to result in brighter displays. */

  //Write the color from our spot in the spectrum at the relative brightness to the LED
  analogWrite(R_PIN, Rainbow(count + 170) * ratio);
  analogWrite(G_PIN, Rainbow(count + 85)  * ratio);
  analogWrite(B_PIN, Rainbow(count)       * ratio);  
  /* Each color has the same pattern of increasing and decreasing brightness, just not synchronously.
   * We can reuse the same function and carefully offset each color to make sure we get to see all
   * the colors.*/


  if (!(millis() % TIME)) count++;
  /* There's a lot going on in this concise use of syntax. Essentially, whenever millis() (the
   * amount of milliseconds since the arduino has been on) is evenly divisble by TIME (i.e. 
   * TIME milliseconds have passed) then the modulo operator (%) will return 0, which evaluates
   * as FALSE. The ! in front of the expression means invert, so this means every TIME milliseconds,
   * the expression will return TRUE. If it's TRUE, we take a step through the color spectrum. Bytes 
   * can only count to 255 before they reset back to 0. The overflow of "count" is a passive way to
   * take us back to the start of the color spectrum without having to explicitly set "count" to 0.*/
}

/* Returns an appropriate value in 0-255 for a given value in 0-255. With good timing, it can be used
 * to cycle through the entire color spectrum. */
byte Rainbow(byte i) {
  if (i > 213) return i * 6;  
  if (i > 127) return 0;
  if (i > 85)  return 255 - i * 6;  
  return 255;
}

Once the code is uploaded, you should have yourself an automatic mood night light! Here's ours in action:

action GIF

Resources and Going Further

  • The TEMT6000 only detects the amalgamated presence of light with wavelengths in the range of 390–700 nm, but we've got a plethora of different light sensing options:
    • Want a wearable version of the TEMT6000? You're in luck. Build a light-detecting garment, with the LilyPad Light Sensor.
    • The TSL2561 Luminosity Sensor Breakout is an integrated sensor that can detect both visible light and infrared light.
    • The ISL29125 RGB Light Sensor can detect light that is specifically red, green, blue, or any combination thereof.
    • The ML8511 UV Sensor Breakout works similarly to the TEMT6000, but responds to ultraviolet light instead of visible light.
    • The Mini Photocell is a very small alternative to the TEMT6000, however it is a photo resistor (a resistor that changes resistance based on the presence of light) instead of a phototransistor.
  • If you plan on using the nightlight indefinitely, an energy-conscious suggestion would be to integrate a Wake on Shake. The Arduino will constantly be running and checking if its dark, which can use up a lot of energy over time. A Wake on Shake would make the current draw negligible until you bumped the circuit. This way you can easily activate the light in the dark if you need it, and would practically be off otherwise.
  • Want a night light for outdoors? The Sunny Buddy makes keeping a battery charged with solar energy easy. Your night light could store energy during the day, and light the way for you at night! Of course you may want to also invest in a transparent plastic case to keep the elements out.

Or, you can check out these other great light-based tutorials.

RGB Panel Hookup Guide

Make bright, colorful displays using the 32x16, 32x32, and 32x64 RGB LED matrix panels. This hookup guide shows how to hook up these panels and control them with an Arduino.

LilyPad Light Sensor Hookup Guide

How to hook up the LilyPad Light Sensor as well as some project ideas and example code.

Spectral Triad (AS7265x) Hookup Guide

Learn how to wield the power of 18 channels of UV to NIR spectroscopy with AS72651 (UV), AS72652 (VIS), and AS72653 (NIR) sensors!

LumiDrive Hookup Guide

The LumiDrive LED Driver is SparkFun’s foray into all things Python on micro-controllers. With the SparkFun LumiDrive you will be able to control and personalize a whole strand of APA102s directly from the board itself.