You are here

TSL230R

Sensor Type: 
Light
Connection: 
Digital
Features: 
PWM output, selectable sensitivity and scaling

The TAOS TSL230 is a light to frequency converter IC. Here is the datasheet: http://www.ams.com/eng/content/download/250243/975877/file/TSL230RD_TSL230ARD_TSL230BRD-P.pdf

The Roaming Drone has put together a top of the line explanation of the ic and how to use it on Arduino:



http://roamingdrone.wordpress.com/2008/11/13/arduino-and-the-taos-tsl230r-light-sensor-getting-started/

What I like about this blog posts related to the TSL230 (there are a few, do a search on the site) is that he is actually doing a build document on how to make a top of the line light meter for photographic usage, including doing all sorts of related calculations such as intensity, wattage, and luminance. I particularly like the LUX conversion. I used this in my solar eclipse data collector project http://diy-scib.org/blog/solar-eclipse-light-level-data

The only problem with the blog is that code is broken into digestable chunks. Normally I would say this is a good thing. However in this case, it is hard to see how it all fits together.

I cut a fair chunk of the code, and am reprinting it here as a complete project, which will output to the serial port:

 

/* TAOS TSL230R Arduino sample applicaton original source url: <a href="http://roamingdrone.wordpress.com/2008/11/13/arduino-and-the-taos-tsl230r-light-sensor-getting-started/">http://roamingdrone.wordpress.com/2008/11/13/arduino-and-the-taos-tsl230...</a> */ #define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt #define TSL_S0 5 #define TSL_S1 6 #define TSL_S2 7 #define TSL_S3 8 // 1000ms = 1s #define READ_TM 1000 unsigned long pulse_cnt=0; // time tracking variables unsigned long cur_tm = millis(); unsigned long pre_tm = cur_tm; // time passed unsigned int tm_diff = 0; // sensitivity scale // 1x = 10 // 10x = 100 // 100x = 1000 int calc_sensitivity = 1000; // freq multiplier default 1 // maps to output frequency scale of 100x int freq_mult = 100; void setup(){ Serial.begin(9600); // attach interrupt to pin2, send output pin of TSL230R to Arduino 2 // call handler on each rising pulse attachInterrupt(0, add_pulse, RISING); pinMode(TSL_FREQ_PIN, INPUT); pinMode(TSL_S0, OUTPUT); pinMode(TSL_S1, OUTPUT); pinMode(TSL_S2, OUTPUT); pinMode(TSL_S3, OUTPUT); digitalWrite(TSL_S0, HIGH); digitalWrite(TSL_S1, LOW); digitalWrite(TSL_S2, HIGH); digitalWrite(TSL_S3, HIGH); } void loop () { // scale function check set_scaling(100); // check the value of the sensor every READ_TM ms //Calc how much time has passed pre_tm = cur_tm; cur_tm = millis(); if(cur_tm &gt; pre_tm) { tm_diff += cur_tm - pre_tm; } else if(cur_tm &lt; pre_tm){ // handler for overflow / rollover tm_diff +=(cur_tm + (34359737 - pre_tm)); } // if enough time has passed, perform a reading if (tm_diff &gt;= READ_TM){ //reset ms counter tm_diff = 0; //get current frequency unsigned long frequency = get_tsl_freq(); Serial.print("frequency = "); Serial.println(frequency); // calc radiant energy float uw_cm2 = calc_uwcm2(frequency); Serial.print("Energy(uW) = "); Serial.println(uw_cm2); // calc illuminance float lux = calc_lux_single(uw_cm2, 0.175); Serial.print("LUX = "); Serial.println(lux); Serial.println(); } } float calc_lux_single(float uw_cm2, float efficiency){ /* calculate lux (lm/m^2), using standard formula: Xv = Xl * V(l) * Km Xl is W/m^2 (calculate actual receied uW/cm^2, extrapolate from sensor size (0.0136cm^2) to whole cm size, then convert uW to W) V(l) = efficiency function (provided via argument) Km = constant, lm/W @ 555nm = 683 (555nm has efficiency function of nearly 1.0) Only a single wavelength is calculated - you'd better make sure that your source is of a single wavelength... Otherwise, you should be using calc_lux_gauss() for multiple wavelengths convert to w_m2 */ float w_m2 = (uw_cm2 / (float) 1000000) * (float) 100; // calculate lux float lux = w_m2 * efficiency * (float) 683; return(lux); } void set_scaling(int what){ // set output freq scale // adj freq multiplier and set pin values // scale = 2 == freq_mult = 2 // scale = 10 == freq_mult = 10 // scale = 100 == freq_mult = 100 int pin_2 = HIGH; int pin_3 = HIGH; switch(what) { case 2: pin_3 = LOW; freq_mult = 2; break; case 10: pin_2 = LOW; freq_mult = 10; break; case 100: freq_mult = 100; break; default: // dont recognize the level setting? Get out now. ITS A TRAP! return; } // set pins digitalWrite(TSL_S2, pin_2); digitalWrite(TSL_S3, pin_3); return; } void sensitivity( bool dir ){ // adjust sensitivy int pin_0; int pin_1; if(dir == true){ // increase sensitivity // check already maxed? if (calc_sensitivity == 1000) return; if (calc_sensitivity == 100){ //increase to max sensitivity pin_0 = true; pin_1 = true; } else { //increase to med. sensitivy pin_0 = false; pin_1 = true; } // set sensitivity divider calc_sensitivity *=10; } else { //reduce sensitivy //check lowest level? if (calc_sensitivity == 10) return; if (calc_sensitivity == 100){ // move to lowest level pin_0 = true; pin_1 = false; } else { // move to medium level pin_0 = false; pin_1 = true; } // reduce divider calc_sensitivity = calc_sensitivity / 10; } //change pin states digitalWrite(TSL_S0, pin_0); digitalWrite(TSL_S1, pin_1); return; } float calc_uwcm2(unsigned long freq){ // get uw observed - assume 640nm wavelength // note divide by factor of 10 maps to sensitivity of 1x float uw_cm2 = (float) freq / (float) 10; // extrapolate to entire cm2 area uw_cm2 *= ((float) 1 / (float) 0.0236); return(uw_cm2); } unsigned long get_tsl_freq() { //copy pulse counter and multiply //multiplication is needed for current freq scaling level unsigned long freq = pulse_cnt *100; //reset pulse counter pulse_cnt = 0; return(freq); } void add_pulse(){ //increase pulse count pulse_cnt++; return; }

Comments

tsl230 is a light to frequency converter not pwm

Thanks for the correction. I somehow had both pwm and frequency in there. Correcting it now.

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer