Go Down

Topic: Small sketch for TSL235R Light to Frequency sensor (Read 10822 times) previous topic - next topic

robtillaart

May 16, 2011, 05:26 pm Last Edit: May 16, 2011, 08:16 pm by robtillaart Reason: 1
Today I received two TSL235 sensors that convert incoming light to frequency. As there was no article on the playground yet on this particular sensor I wrote a small sketch and added some comments - http://arduino.cc/playground/Main/TSL235R - to get people started. The code does not compensate for anything yet (input voltage, temperature etc) ; maybe some future version.

In contrast to the TSL230R it has no configurable divider for the frequency so the # IRQ's can become quite high. Today's max inhouse ~160000 . Therefor I used only the rising edge for the IRQ routine. When it is really really dark one could use CHANGE edge for the IRQ, to double the precision, but be carefull as your Arduino might get stalled during daylight :)

As always comments and remarks are welcome,

Rob

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

madepablo

Take a look, may be here you could found something interesting.
http://arduino.cc/forum/index.php/topic,21536.0.html

I hope it could helps you.
madepablo

dougstrickland


...In contrast to the TSL230R it has no configurable divider for the frequency so the # IRQ's can become quite high. Today's max inhouse ~160000 . Therefor I used only the rising edge for the IRQ routine. When it is really really dark one could use CHANGE edge for the IRQ, to double the precision, but be carefull as your Arduino might get stalled during daylight :)

As always comments and remarks are welcome,

Rob




I'm seeing this too, if the sensor sees the window the script output stops.  When I shield the sensor from bright light, it starts streaming output again, with the first value read being very high.

How do I set this up to scale for brighter environments? I'm trying to design a logger that tracks how many minutes of sunlight there are at a given location over the course of a day.  Any suggestions on getting this sensor to do the sensing?

Cheers, D 

robtillaart

#3
Jun 10, 2011, 09:48 am Last Edit: Feb 26, 2013, 07:59 pm by robtillaart Reason: 1
For bright sunlight you should use:  attachInterrupt(0, irq1, RISING);  -  but still it can generate too much IRQ's to handle. So if SW cannot handle HW comes in.

check - http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library/ - to get an idea how this can be done.

Please not that this lib affects internal timers so some things may not work anymore.

Another alternative is to make a HW divider before connecting to Arduino. check - http://www.scribd.com/doc/13305418/Building-Dividers-With-Flipflop -




Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

davidbw

Dear Rob,
Thank you for the code. Works great with my Uno on digital pin 2, and on digital pin 3 with small change in code. Can you tell me how to modify it to read two TSL235 sensors?
Best, David

robtillaart

#5
Feb 15, 2013, 11:33 pm Last Edit: Feb 17, 2013, 08:39 pm by robtillaart Reason: 1
two TSL should be something like this (not tested)
Code: [Select]

/*
*    FILE: TSL235R_duo.pde
*  AUTHOR: Rob Tillaart
*    DATE: 2013-02-15
*
* PURPOSE: prototype TSL235R monitoring (double)  
*
* Digital Pin layout ARDUINO
* =============================
*  2     IRQ 0    - to TSL235R
*
* PIN 1 - GND
* PIN 2 - VDD - 5V
* PIN 3 - SIGNAL
*
*/

volatile unsigned long counter1= 0;
volatile unsigned long counter2= 0;
unsigned long oldcnt1 = 0;
unsigned long oldcnt2 = 0;
unsigned long t = 0;
unsigned long last;

void irq1()
{
 counter1++;
}

void irq2()
{
 counter2++;
}

///////////////////////////////////////////////////////////////////
//
// SETUP
//
void setup()
{
 Serial.begin(115200);
 Serial.println("START");
 pinMode(2, INPUT);
 digitalWrite(2, HIGH);
 attachInterrupt(0, irq1, RISING);
 attachInterrupt(1, irq2, RISING);
}

///////////////////////////////////////////////////////////////////
//
// MAIN LOOP
//
void loop()
{
 if (millis() - last > 1000)
 {
   last = millis();
   t = counter1;
   unsigned long hz = t - oldcnt1;
   Serial.print("FREQ: ");
   Serial.print(hz);
   Serial.print("\t = ");
   Serial.print((hz+50)/100);  // +50 == rounding last digit
   Serial.println(" mW/m2");
   oldcnt1 = t;

   t = counter2;
   hz = t - oldcnt2;
   Serial.print("FREQ: ");
   Serial.print(hz);
   Serial.print("\t = ");
   Serial.print((hz+50)/100);  // +50 == rounding last digit
   Serial.println(" mW/m2");
   oldcnt2 = t;
 }
}
// END OF FILE

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

davidbw


robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Corpze

#8
Feb 25, 2013, 11:52 pm Last Edit: Feb 25, 2013, 11:54 pm by Corpze Reason: 1
Is there any change i can use the code for the TSL237 - sensor?
That sensor is way more sensitive for low light, i believe it has a output frequency @ 21.8 ?W/cm2 instead of the TSL235 that has 430 ?W/cm2.

It may be some other differences to? Here is the PDF for it: https://docs.google.com/viewer?a=v&q=cache:Plvrk-_pFQwJ:www.ams.com/eng/content/download/250250/975933/file/TSL237-J.pdf+TSL237&hl=sv&pid=bl&srcid=ADGEESjUTdu6N77Fo19CfVUS9QH3XGxoRrMVamEsH0Ks55GQgOfOke8V-DaDA0qYjHfaNHOmm9-tUJVo5ovLYqdlAONPu6ZyLsKOm_iwdDCqSC2U_2hMFH2ynBy48mAt6bFnG9jLaAYl&sig=AHIEtbShhuCFzTVDeFqfAbEUaVrjHy2ypw

The reason i want to use this is that when i push a button i want to take a reading from the sensor, (or two-three readings and use a median value for better accuracy) and then calculate that value to Magnitude / square arc second http://old.nightwise.org/magnitudes.htm

so i dont wanna do a continous reading, just when i press a button, take a reading, display the magnitude/ square arc second on a lcd for about 10 sec. and then my arduino will continue with the rest of my code (witch is stepper motor controll with steps printout and a DHT-sensor.

Can this be done with this code?

BR/ Daniel

robtillaart

#9
Feb 26, 2013, 07:58 pm Last Edit: Feb 26, 2013, 08:10 pm by robtillaart Reason: 1
Quote
Is there any change i can use the code for the TSL237 - sensor?

You need to compare the datasheets and if the only diff is the light intensity/frequency relation it should be possible.

-update-
A quick look says yes as the output signal is typically 4.5V that is enough to trigger an IRQ I think. Otherwise you can add an extra transistor to make it 5V pulses.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart

The link to the TSL237 datasheet - http://www.ams.com/eng/content/download/250250/975933/file/TSL237-J.pdf -

At least a bit shorter ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

lemorlenny


two TSL should be something like this (not tested)
Code: [Select]

/*
*    FILE: TSL235R_duo.pde
*  AUTHOR: Rob Tillaart
*    DATE: 2013-02-15
*
* PURPOSE: prototype TSL235R monitoring (double)  
*
* Digital Pin layout ARDUINO
* =============================
*  2     IRQ 0    - to TSL235R
*
* PIN 1 - GND
* PIN 2 - VDD - 5V
* PIN 3 - SIGNAL
*
*/

volatile unsigned long counter1= 0;
volatile unsigned long counter2= 0;
unsigned long oldcnt1 = 0;
unsigned long oldcnt2 = 0;
unsigned long t = 0;
unsigned long last;

void irq1()
{
 counter1++;
}

void irq2()
{
 counter2++;
}

///////////////////////////////////////////////////////////////////
//
// SETUP
//
void setup()
{
 Serial.begin(115200);
 Serial.println("START");
 pinMode(2, INPUT);
 digitalWrite(2, HIGH);
 attachInterrupt(0, irq1, RISING);
 attachInterrupt(1, irq2, RISING);
}

///////////////////////////////////////////////////////////////////
//
// MAIN LOOP
//
void loop()
{
 if (millis() - last > 1000)
 {
   last = millis();
   t = counter1;
   unsigned long hz = t - oldcnt1;
   Serial.print("FREQ: ");
   Serial.print(hz);
   Serial.print("\t = ");
   Serial.print((hz+50)/100);  // +50 == rounding last digit
   Serial.println(" mW/m2");
   oldcnt1 = t;

   t = counter2;
   hz = t - oldcnt2;
   Serial.print("FREQ: ");
   Serial.print(hz);
   Serial.print("\t = ");
   Serial.print((hz+50)/100);  // +50 == rounding last digit
   Serial.println(" mW/m2");
   oldcnt2 = t;
 }
}
// END OF FILE




I need to create a sensor array, Its possible check more than 2 sensor? (almost 7-10).

Regards


robtillaart

Yes that would be possible but not for the very bright signals. Check the (PCI) PinChangeInterrupt library - http://playground.arduino.cc/Main/PinChangeInt - and give every sensor  its own counter.

As the PCI-lib is a SW lib it takes more time to handle every pulse than the HW based interrupts mentioned above so this will limit the amount of pulses per second that can be handled.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

madsci

Hi,

Is there a way to sample a reading, by that I mean just take ONE reading from the sensor and then stop the loop in this sketch? I'm not too familiar with the attachInterrupt concept and am a little confused as to how to get just one reading rather than loop it over and over again. I tried running it the code in the void setup() portion but that isn't working. Or can I write another function to say sample one reading? But that would require passing variables from function to function.

Sorry for the lack of knowledge on my part.

Pole92

Hi,

Is there a way to sample a reading, by that I mean just take ONE reading from the sensor and then stop the loop in this sketch? (...)
Or can I write another function to say sample one reading? But that would require passing variables from function to function.

Sorry for the lack of knowledge on my part.
Does anybody know how to implement that? At least some clues what to search for :)
Arduino Leonardo

Go Up