Pages: [1] 2 3 4   Go Down
Author Topic: How to: Light to Frequency Converter - TSL235R?  (Read 10677 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would like to know how to wire and use this light-to-frequency converter sensor (TSL235R):

http://www.sparkfun.com/commerce/product_info.php?products_id=9768

The datasheet explains how to wire it: Vcc to  5V, GND to GND, with a 0.1uF (to 0.01uF) capacitor between ground and Vcc. The OUT  leg goes to the micro-controler unit (Page 5 of the datasheet):
http://www.sparkfun.com/datasheets/Sensors/Imaging/TSL235R-LF.pdf

However, i have a lot of questions...:
1) what is this pin in the arduino (analog 5, analog 4, or any other digital or analog pin?
2) how to obtain data from it?

I think that it should not be so much different from this other sensor TSL230R (http://roamingdrone.wordpress.com/2008/11/13/arduino-and-the-taos-tsl230r-light-sensor-getting-started/) although may be something different since it only have one data leg and not as much outs as the TSL230R.

So, any idea about how to wire it to arduino and how to extract interesting data from this sensor?
Thanks!
« Last Edit: June 10, 2010, 08:00:38 am by madepablo » Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 603
Posts: 33415
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
what is this pin in the arduino
use any of the digital pins set for an input.

Quote
how to obtain data from it?
Use the pulse in function to measure the frequency and hence the light level.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Connect it to one of the IRQ lines so you don't miss any pulse.

Code:
long count = 0;
long threshold = 100;

void setup()
{
  attachInterrupt(0, MyIRQ, CHANGE);
}

void loop()
{
  ...
  if (count > threshold)
  {
     // do some action
     // ...
     count = 0;  // reset the counter
  }
}

void MyIRQ()
{
  count++;
}
Logged

Rob Tillaart

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

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks to both!

Just only one question: what are the IRQ lines?
Thanks!
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

digital pin2 is IRQ 0
digital pin3 is IRQ 1

Logged

Rob Tillaart

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

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see. Thanks! i will try soon.
Cheers!
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Two issues with the code example:



First the long count = 0; should be modified to: volatile long count = 0; as the per this reference: http://arduino.cc/en/Reference/Volatile

Second is your use of an long for the count variable. As it is a four byte variable it is possible that the value can change between the main loops reading of the variable as an interrupt can happen between the fetching of the variable's value in the main loop. While this is not frequent event, it can lead to a very hard to find 'bug'. If you require a longer then byte variable that is going to be changed inside a ISR function, then one should surround the reading of the variable with interrupts() and noInterrupts() functions to force the variable read to be 'atomic'. http://arduino.cc/en/Reference/NoInterrupts

[glow]volatile long count = 0;[/glow]
long threshold = 100;

void setup()
{
  attachInterrupt(0, MyIRQ, CHANGE);
}

void loop()
{
  ...
 glow]interrupts(); [/glow]
  }
}

void MyIRQ()
{
  count++;
}


Lefty
« Last Edit: June 11, 2010, 07:19:24 pm by retrolefty » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanx,

point 1 volatile: agree 100%
point 2 : disabling IRQ implies possible loss of pulses; How bad is that? depends....
At least if you disable the IRQ's it should be as short as possible. e.g. only around the line count =0;

And yes the value of count might change during the loop, so working with a copy might be needed.
Logged

Rob Tillaart

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

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I am writing a complete code to start to test this sensor.

I copied your code (retrolefty), and it return an error.
(Yes, i know that your code is not complete, just only an idea, but is my starting point. I exteded the code, but the error is related to the basic code)
"nointerrupts" is highlighted and this message appear on arduino IDE:
"In function 'void loop()':
error: 'noInterrupts' was not declared in this scope"

Any idea?

[edit]Ok, i reply to my self. Reading the reference from the arduino webpage, it must be "nointerrupts()" and not "nointerrupts". So this part is solved. I will prepare the code and share it here. Thanks[/edit]
« Last Edit: June 12, 2010, 11:24:44 am by madepablo » Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the example code in which i am working. For the moment it only reads the signal from the sensor. It is still not converted to irradiance.

Code:
/* Example: TSL235R
   Collaborative ideas from:
   retrofelty, robtillaart, Gumpy_Mike, and madepablo
  
   Wiring:
   TSL235R    Arduino pins
   GND        GND
   Vcc        +5V
   Out        Digital pin 2
   Wire a 0.1uF capacitator between Vcc and GND
*/

// Pin definitions
# define Sensor 2

// Variables
volatile long count = 0;   // Counter of measurements of the TSL235R
long threshold = 100;      // Minimum of measurements
long counter = 0;          // Counter of measurements during the test
int frequency;             // Read the frequency from the digital pin

void setup()
{
  Serial.begin(9600);                           // Start and configure the serial port
  pinMode(frequency, INPUT);                    // Declare the pin such as an input of data
  attachInterrupt(0, MyIRQ, CHANGE);
  Serial.println("Testing a TSL235R sensor:");  // Splash screen
  Serial.println("-------------------------");
  Serial.println();  
}

void loop()
{
 counter = counter + 1;       // Increase the number of measurement
 noInterrupts();
 if (count > threshold)
 {
   frequency=digitalRead(Sensor);  // Read the sensor
   Serial.print(counter);     // Print the measurement number
   Serial.print("  ");
   Serial.println(frequency); // print the signal
   count = 0;                 // reset the counter
   interrupts();  
 }
 delay (1000);               // wait 1 seconds until the next measurement
}

void MyIRQ()
{
 count++;
}

Binary sketch size: 3138 bytes



However, the code is not correct, since what it produces is:
Quote
Testing a TSL235R sensor:
-------------------------

1  1
2  0
3  0
4  1
5  0
6  1
7  0
8  1
9  0
10  1

I will read different posts about other sensor (TSL230R) in order to see how should i modify the code:

http://www.sensorpedia.com/blog/how-to-interface-an-irradiance-sensor-with-sensorpedia/
http://roamingdrone.wordpress.com/2008/11/13/arduino-and-the-taos-tsl230r-light-sensor-getting-started/
http://roamingdrone.wordpress.com/2008/11/28/arduino-and-the-tsl230r-photographic-conversions/

Updates coming soon...
« Last Edit: June 12, 2010, 12:37:20 pm by madepablo » Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, second round!

I saw this other code for TSL230R:
http://www.teampaulc.org/2009/01/tsl230r-to-arduino-interface.html

I taked this idea to modify the first code a little bit to apply it to the TSL235R, and it seems to run.

This is the code of my second try:
Code:
/* Example: TSL235R
   Collaborative ideas from:
   retrofelty, robtillaart, Gumpy_Mike, and madepablo
  
   Sensor:
   http://www.sparkfun.com/datasheets/Sensors/Imaging/TSL235R-LF.pdf
   measurement area: 0.92mm2
  
   Wiring:
   TSL235R    Arduino pins
   GND        GND
   Vcc        +5V
   Out        Digital pin 2
   Wire a 0.1uF capacitator between Vcc and GND close to the sensor
*/

// Pin definitions
# define TSL235R 2                      // Out of TSL235R connected to Digital pin 2

// Constants
int period = 1000;                     // Miliseconds of each light frecuency measurement
int ScalingFactor = 1;                 // Scaling factor of this sensor
float area = 0.0092;                   // Sensing area of TSL235R device (cm2)

// Variables
unsigned long counter = 0;             // Counter of measurements during the test
unsigned long currentTime = millis();  
unsigned long startTime = currentTime;
volatile long pulses = 0;              // Counter of measurements of the TSL235R
unsigned long frequency;               // Read the frequency from the digital pin (pulses/second)
float irradiance;                      // Calculated irradiance (uW/cm2)


void setup() {
  Serial.begin(9600);                           // Start and configure the serial port
  attachInterrupt(0, PulseCount, RISING);
  pinMode(TSL235R, INPUT);                    // Declare the pin such as an input of data
  Serial.println("Testing a TSL235R sensor:");  // Splash screen
  Serial.println("-------------------------");
  Serial.println();  
}

void loop(){
  counter++;                           // Increase the number of measurement
  Serial.print(counter);               // Print the measurement number
  getfrequency();                      // Request to measure the frequency
  Serial.print("  ");
  Serial.print(frequency);             // print the frequency (pulses/second)
  Serial.print(" pulses/second    ");
  getirradiance();                     // Request to calculate the irradiance (uW/cm2)
  Serial.print("  ");
  Serial.print(irradiance);             // print the frequency (pulses/second)
  Serial.println(" uW/cm2");
  pulses = 0;                          // reset the pulses counter
  delay (4000);                        // wait 4 seconds until the next measurement
}


void PulseCount()
{
 pulses++;
}

unsigned long getfrequency () {
  noInterrupts();
  frequency = pulses /(period/1000);    // Calculate the frequency (pulses/second)
  interrupts();
  return (frequency);
}

float getirradiance () {
  irradiance = frequency / area;      // Calculate Irradiance (uW/cm2)
  return (irradiance);
}
Binary sketch size: 4556 bytes


And those are some results:
Quote
Testing a TSL235R sensor:
-------------------------

1  829 pulses/second      90108.70 uW/cm2
2  58078 pulses/second      6312826.00 uW/cm2
3  58699 pulses/second      6380326.00 uW/cm2
4  59522 pulses/second      6469782.50 uW/cm2
5  60496 pulses/second      6575652.00 uW/cm2
6  61998 pulses/second      6738913.00 uW/cm2
7  63468 pulses/second      6898695.50 uW/cm2
8  65027 pulses/second      7068152.00 uW/cm2
9  66750 pulses/second      7255434.50 uW/cm2
10  68678 pulses/second      7465000.00 uW/cm2
11  63612 pulses/second      6914347.50 uW/cm2
12  69222 pulses/second      7524130.50 uW/cm2
13  73932 pulses/second      8036087.00 uW/cm2
14  75284 pulses/second      8183043.50 uW/cm2
15  76368 pulses/second      8300869.50 uW/cm2
16  76559 pulses/second      8321630.50 uW/cm2
17  76397 pulses/second      8304021.50 uW/cm2
18  76609 pulses/second      8327065.00 uW/cm2
19  76452 pulses/second      8310000.00 uW/cm2
20  76103 pulses/second      8272065.00 uW/cm2
21  75690 pulses/second      8227173.50 uW/cm2
22  75322 pulses/second      8187173.50 uW/cm2
23  75044 pulses/second      8156956.50 uW/cm2
24  74896 pulses/second      8140869.50 uW/cm2
25  28622 pulses/second      3111087.00 uW/cm2
26  11296 pulses/second      1227826.00 uW/cm2
27  10381 pulses/second      1128369.50 uW/cm2
28  10275 pulses/second      1116847.75 uW/cm2
29  63848 pulses/second      6940000.00 uW/cm2
30  76921 pulses/second      8360978.00 uW/cm2
31  77279 pulses/second      8399891.00 uW/cm2
32  76754 pulses/second      8342826.00 uW/cm2
33  78276 pulses/second      8508261.00 uW/cm2
34  78996 pulses/second      8586522.00 uW/cm2
35  80594 pulses/second      8760217.00 uW/cm2
36  82096 pulses/second      8923478.00 uW/cm2
37  83554 pulses/second      9081956.00 uW/cm2
38  85081 pulses/second      9247935.00 uW/cm2
39  86520 pulses/second      9404348.00 uW/cm2
40  87924 pulses/second      9556956.00 uW/cm2

I saw a lot of fluctuations and a clear increase in pulses/second in few seconds, so is it normal?
May be is better to calculate it along 5 seconds and return an average value?

I am interested on measurements time to time, not continuous, so may be it is better??

I will modify a little bit the code in order to express the results in Hz, KHz, MHz... and also in W/m2 depending of the results in each moment.

Any other ideas about this code or how to improve it?
Thanks
« Last Edit: June 12, 2010, 04:30:05 pm by madepablo » Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If I was starting such a project I think I might try to use an existing proven frequency counter library as a starting point, rather then roll my own. Just a thought.

http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library/

Lefty
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ummh! Good point Lefty.

However, it made me ask more things... TSL235R should be connected to pin 2 (or pin3) or to pin 5 to use this library according to the information provided in the link?

Is it necessary extra hardware (amplifiers proposed in the webpage) to obtain accurate data from this sensor? or not in the case of this sensor?

What is the compensation? and how it runs?

I think that this library could be great if it increase the accuracy of the lecture. However, it could be an small problem if it is necessary extra hardware, and if it increase so much the bytes of the final code. In any case, i will explore this option to see whats happend.

Thanks Lefty for the link!
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is it necessary extra hardware (amplifiers proposed in the webpage) to obtain accurate data from this sensor? or not in the case of this sensor?

Not the case for this sensor, it already outputs TTL logic voltages. The input conditioning circuits show are for when you are trying to measure low level analog signals.

What is the compensation? and how it runs?

I haven't used this library yet, but the compensation function seems to allow for small digital trimming factor used to make small calibration corrections if desired. Probably something you can ignore.

Lefty
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 449
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Lefty,

I was checking yesterday the library, and it doesn´t run for me. Ok, at least the examples. I downloaded the library and the example, and i tested it. The examples (this one from the webpage and the other that could be downloaded) does do anything except to write the first line in the serial monitor, but no data.

I tested quickly so i assume that the problem is the wiring of my sensor. I will try again in few days to see if i could obtain something from this library.

Thanks for your answers!
Logged

Pages: [1] 2 3 4   Go Up
Jump to: