Using the TSL230- Measuring Light Intensity and Activating Motors

Colleen Carrier, Sara Range

Program Description:

Through the use of the TSL230 Light Intensity to Light Frequency chip, one can sense different intensities within the room. By hooking up a DC motor to the bread board, we programmed the motor to turn on when the chip detects different intensities. Soon we'll have a car that drives or stops based on the intensity of light.

Project Problems:

1.) When we first bought this chip that nobody knew how to work it, we were under the impression that it detects frequency. However, it does not. It detects intensity and is supposed to convert intensity to frequency. Once we found this out, we were able write the coding properly and be able to read the numbers that the chip was giving us. Also because it detects different intensities instead of frequencies and we did not find this out till last minute, we had to change our project completely to fit the idea of intensity instead of frequency. Originally, we were supposed to develop a car that stops when it sees a red light, and goes when it sees green-- like a stop light.

2.) The lessons that we looked at online were not much help to us, so we had to basically develop our own code and figure out the exact circuitry ourselves. we researched a lot of new coding to make this project work for us.

3.) We burnt out a chip or two.

Le Code:

#define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt

#define mo 3

#define TSL_S0 5

#define TSL_S1 6

#define TSL_S2 7

#define TSL_S3 8

#define READ_TM 1000 // milleseconds between frequency calculations

int calcSensitivity;

unsigned long sensitivityHighThresh = 2000;

unsigned long sensitivityLowThresh = 100000;

unsigned long pulseCount = 0;

unsigned long currentTime = millis();

unsigned long startTime = currentTime;

unsigned int tm_diff = 0;

// freq will be modified by the interrupt handler so needs to be volatile

// freq holds the latest frequency calculation

unsigned long frequency;

float uWattCm2;

volatile unsigned long curPulseCount;

unsigned int count = 0;

unsigned int scale; // holds the TLS scale value, see below

void setup() {


Serial.print("Sensitivity ");

Serial.println(calcSensitivity, DEC);


// attach interrupt to pin2, send output pin of TSL230R to arduino 2

// call handler on each rising pulse

attachInterrupt(0, add_pulse, RISING);


pinMode(mo, OUTPUT);

pinMode(TSL_S0, OUTPUT);

pinMode(TSL_S1, OUTPUT);

pinMode(TSL_S2, OUTPUT);

pinMode(TSL_S3, OUTPUT);

digitalWrite(TSL_S0, LOW); // S0 LOW and S1 HIGH = 10x sensitivity

digitalWrite(TSL_S1, HIGH);

digitalWrite(TSL_S2, HIGH); // S2 and S3 HIGH = /100 output scaling

digitalWrite(TSL_S3, HIGH);

scale = 100; // set this to match TSL_S2 and TSL_S3


void loop() {

// this is just for debugging

// it shows that you can sample freq whenever you need it

// even though it is calculated once a second

// I am dislplaying it every 2 seconds

// note that the first time that freq is calculated, it is bogus



Serial.print("\tuW/cm: ");

Serial.print(getUwattCm2(), DEC);

Serial.print("\tfrequency: ");

Serial.println(frequency, DEC);


if (frequency > 5000)


Serial.println("cmon work!"); // this is just to tell us that the chip is in fact detecting something

digitalWrite(mo, LOW); // the motor is off when light intensity is more than 5000




{ digitalWrite(mo, HIGH); // when the chip is detecting light intensity less than 5000, the motor turns on




void add_pulse() {

// increase pulse count


// DON'T calculate the frequency every READ_TM ms

// just store the pulse count to be used outside of the interrupt

currentTime = millis();

if( currentTime - startTime >= READ_TM )


curPulseCount = pulseCount; // use curPulseCount for calculating freq/uW

pulseCount = 0;

startTime = millis();



long getUwattCm2() {

// copy pulse counter and multiply.

// the multiplication is necessary for the current

// frequency scaling level.

frequency = curPulseCount * scale;

// get uW observed - assume 640nm wavelength

// calc_sensitivity is our divide-by to map to a given signal strength

// for a given sensitivity (each level of greater sensitivity reduces the signal

// (uW) by a factor of 10)

float uw_cm2 = (float) frequency / (float) calcSensitivity;

// extrapolate into entire cm2 area

uWattCm2 = uw_cm2 * ( (float) 1 / (float) 0.0136 );

digitalWrite(TSL_S0, HIGH); // S0 HIGH and S1 HIGH = 100x sensitivity

digitalWrite(TSL_S1, HIGH);

calcSensitivity = 1000;