Arduino‎ > ‎

TSL230R to Arduino interface

Last edited 02/08/2009

This was originally posted on the TeamPaulC blog, that blog entry will not be updated, but this page will be updated as required.

Thank you c.a. church for the great tutorial no how to get the TSL230R to interface with the Arduino. He did a great job showing how to interface and calculate the frequency. However, his approach required both an interrupt AND a separate poll of the results every second to calculate the frequency.

His approach is absolutely fine, but I would prefer to setup the interrupt and have it also do the frequency calculation every period of time and put the results into a volatile variable. That way I can start the interrupt, never worry about it again, and just read the frequency whenever I need it. To that end, find below a new version of his code, slightly rearranged and with a few new variables and output to the serial monitor for debugging.

oh, also.
If you are not going to use the light sensor, you can always call
noInterrupts()
and
interrupts()
to turn them off and back on. Just remember that the first time that freq is calculated after a call to interrupts() it will be bogus!

Source Code

/*
 * reads TLS230R module
 * sends to serial monitor
 */
 
 // setup the TLS230R to Arduion mapping
#define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt 
#define TSL_S0       3 
#define TSL_S1       4   
#define TSL_S2       5   
#define TSL_S3       6   
#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.begin(57600);
 sensitivity(1);
 Serial.print("Sensitivity  ");
 Serial.println(calcSensitivity, DEC);
 Serial.println("Start...");
 
 // 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_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
 count++;    
 Serial.print(count);
 Serial.print("\tuW/cm: ");
 Serial.print(getUwattCm2(), DEC);
 Serial.print("\tfrequency: ");
 Serial.println(frequency, DEC);
 setSensitivity();
 delay(1000);
}

void add_pulse() {
  // increase pulse count
  pulseCount++;
 
  // 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 );
 
   return(uWattCm2);
}
void setSensitivity()
{
  getUwattCm2();
  if (uWattCm2 <  sensitivityHighThresh)
  {
    sensitivity(3);
    return;
  } 
  if (uWattCm2 > sensitivityLowThresh )
  {
    sensitivity(1);
    return;
  }
  sensitivity(2);
}
void sensitivity(uint8_t level)
{
  switch (level)
  {
    case 1:
       if (calcSensitivity != 10)
       {
         Serial.println("Now at low sensitivity.");
       }
       digitalWrite(TSL_S0, HIGH);  // S0 HIGH and S1 LOW = 1x sensitivity
       digitalWrite(TSL_S1, LOW);
       calcSensitivity = 10;
       break;
    case 2:
       if (calcSensitivity != 100)
       {
         Serial.println("Now at medim sensitivity.");
       }
       digitalWrite(TSL_S0, LOW);  // S0 LOW and S1 HIGH = 10x sensitivity
       digitalWrite(TSL_S1, HIGH);
       calcSensitivity = 100;
       break;
    case 3:
       if (calcSensitivity != 1000)
       {
         Serial.println("Now at high sensitivity.");
       }
       digitalWrite(TSL_S0, HIGH);  // S0 HIGH and S1 HIGH = 100x sensitivity
       digitalWrite(TSL_S1, HIGH);
       calcSensitivity = 1000;
       break;
  }
  return;
}



Comments