Sign In

Interfacing TSL2561 ( Light Flora Sensor From Adafruit) With Atmega328p MCU

John Abdul abdulraooflearner@gmail.com Germany

Hardware: Atmega328P At 16 Mhz Software: C Programming In Eclipse IDE

Dear sir/ Madam

I already implemented piece of code, using I2c Software, but i am unable to Get the exact values.

Lux valvue always return "0"

Kindly help

thank you

Images

Program

#ifndef F_CPU
#define F_CPU           16000000                   // processor clock frequency
#endif



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <avr/io.h>
#include <util/delay.h>

#include "tsl_2561.h"
#include "i2c_master.h"
/*
#include "tsl2561/tsl2561.h"
#include "i2chw/i2cmaster.h"
*/
#include "Uart.h"

/*#include "tsl2561.h"*/

/*#include TSL2561_I2CFLEURYPATH*/

int TSL2561AddressWrite_Float = 0x39<<1;                 // Ground set the address 0x29 / 3.3V (vcc) to set the address 0x49 / leave it floating (unconnected) to use address 0x39
	   
unsigned long Ch0DataHigh,Ch0DataLow,Ch1DataHigh,Ch1DataLow;
	   
unsigned int ch0,ch1;



#define ControlRegister            0x80
#define TurnOnBits                 0x03
#define TimingRegister             0x00  // 0x00 = 13.7ms / 0x01 = 101ms / 0x02 = 402ms (default)
#define iGain                      0x00  // 0x00 = 1x Gain (default) / 0x10 = 16x Gain

#define Data0LowByteMode           0x8C  //Address the Ch0 lower data register
#define Data0HighByteMode          0x8D  //Address the Ch0 upper data register
#define Data1LowByteMode           0x8E  //Address the Ch1 lower data register
#define Data1HighByteMode          0x8F  //Address the Ch1 upper data register

#define LUX_SCALE 14 // scale by 2^14
#define RATIO_SCALE 9 // scale ratio by 2^9
//---------------------------------------------------
// Integration time scaling factors
//---------------------------------------------------
#define CH_SCALE 10 // scale channel values by 2^10
#define CHSCALE_TINT0 0x7517 // 322/11 * 2^CH_SCALE
#define CHSCALE_TINT1 0x0fe7 // 322/81 * 2^CH_SCALE
//---------------------------------------------------
// T Package coefficients
//---------------------------------------------------
// For Ch1/Ch0=0.00 to 0.50
// Lux/Ch0=0.0304-0.062*((Ch1/Ch0)^1.4)
// piecewise approximation
// For Ch1/Ch0=0.00 to 0.125:
// Lux/Ch0=0.0304-0.0272*(Ch1/Ch0)
//
// For Ch1/Ch0=0.125 to 0.250:
// Lux/Ch0=0.0325-0.0440*(Ch1/Ch0)
//
// For Ch1/Ch0=0.250 to 0.375:
// Lux/Ch0=0.0351-0.0544*(Ch1/Ch0)
//
// For Ch1/Ch0=0.375 to 0.50:
// Lux/Ch0=0.0381-0.0624*(Ch1/Ch0)
//
// For Ch1/Ch0=0.50 to 0.61:
// Lux/Ch0=0.0224-0.031*(Ch1/Ch0)
//
// For Ch1/Ch0=0.61 to 0.80:
// Lux/Ch0=0.0128-0.0153*(Ch1/Ch0)
//
// For Ch1/Ch0=0.80 to 1.30:
// Lux/Ch0=0.00146-0.00112*(Ch1/Ch0)
//
// For Ch1/Ch0>1.3:
// Lux/Ch0=0

 /*printf("printing  Intensity in ch0 %lunn", ch0);
 printf("printing  Intensity in ch1 %lunn", ch1);*/
//---------------------------------------------------
#define K1T 0x0040 // 0.125 * 2^RATIO_SCALE
#define B1T 0x01f2 // 0.0304 * 2^LUX_SCALE
#define M1T 0x01be // 0.0272 * 2^LUX_SCALE
#define K2T 0x0080 // 0.250 * 2^RATIO_SCALE
#define B2T 0x0214 // 0.0325 * 2^LUX_SCALE
#define M2T 0x02d1 // 0.0440 * 2^LUX_SCALE
#define K3T 0x00c0 // 0.375 * 2^RATIO_SCALE
#define B3T 0x023f // 0.0351 * 2^LUX_SCALE
#define M3T 0x037b // 0.0544 * 2^LUX_SCALE
#define K4T 0x0100 // 0.50 * 2^RATIO_SCALE
#define B4T 0x0270 // 0.0381 * 2^LUX_SCALE
#define M4T 0x03fe // 0.0624 * 2^LUX_SCALE
#define K5T 0x0138 // 0.61 * 2^RATIO_SCALE
#define B5T 0x016f // 0.0224 * 2^LUX_SCALE
#define M5T 0x01fc // 0.0310 * 2^LUX_SCALE
#define K6T 0x019a // 0.80 * 2^RATIO_SCALE
#define B6T 0x00d2 // 0.0128 * 2^LUX_SCALE
#define M6T 0x00fb // 0.0153 * 2^LUX_SCALE
#define K7T 0x029a // 1.3 * 2^RATIO_SCALE
#define B7T 0x0018 // 0.00146 * 2^LUX_SCALE
#define M7T 0x0012 // 0.00112 * 2^LUX_SCALE
#define K8T 0x029a // 1.3 * 2^RATIO_SCALE
#define B8T 0x0000 // 0.000 * 2^LUX_SCALE
#define M8T 0x0000 // 0.000 * 2^LUX_SCALE
//---------------------------------------------------
// CS package coefficients
//---------------------------------------------------
// For 0 <= Ch1/Ch0 <= 0.52
// Lux/Ch0 = 0.0315-0.0593*((Ch1/Ch0)^1.4)
// piecewise approximation
// For 0 <= Ch1/Ch0 <= 0.13
// Lux/Ch0 = 0.0315-0.0262*(Ch1/Ch0)
// For 0.13 <= Ch1/Ch0 <= 0.26
// Lux/Ch0 = 0.0337-0.0430*(Ch1/Ch0)
// For 0.26 <= Ch1/Ch0 <= 0.39
// Lux/Ch0 = 0.0363-0.0529*(Ch1/Ch0)
// For 0.39 <= Ch1/Ch0 <= 0.52
// Lux/Ch0 = 0.0392-0.0605*(Ch1/Ch0)
// For 0.52 < Ch1/Ch0 <= 0.65
// Lux/Ch0 = 0.0229-0.0291*(Ch1/Ch0)
// For 0.65 < Ch1/Ch0 <= 0.80
// Lux/Ch0 = 0.00157-0.00180*(Ch1/Ch0)
// For 0.80 < Ch1/Ch0 <= 1.30
// Lux/Ch0 = 0.00338-0.00260*(Ch1/Ch0)
// For Ch1/Ch0 > 1.30
// Lux = 0
//---------------------------------------------------
#define K1C 0x0043 // 0.130 * 2^RATIO_SCALE
#define B1C 0x0204 // 0.0315 * 2^LUX_SCALE
#define M1C 0x01ad // 0.0262 * 2^LUX_SCALE
#define K2C 0x0085 // 0.260 * 2^RATIO_SCALE
#define B2C 0x0228 // 0.0337 * 2^LUX_SCALE
#define M2C 0x02c1 // 0.0430 * 2^LUX_SCALE
#define K3C 0x00c8 // 0.390 * 2^RATIO_SCALE
#define B3C 0x0253 // 0.0363 * 2^LUX_SCALE
#define M3C 0x0363 // 0.0529 * 2^LUX_SCALE
#define K4C 0x010a // 0.520 * 2^RATIO_SCALE
#define B4C 0x0282 // 0.0392 * 2^LUX_SCALE
#define M4C 0x03df // 0.0605 * 2^LUX_SCALE
#define K5C 0x014d // 0.65 * 2^RATIO_SCALE
#define B5C 0x0177 // 0.0229 * 2^LUX_SCALE
#define M5C 0x01dd // 0.0291 * 2^LUX_SCALE
#define K6C 0x019a // 0.80 * 2^RATIO_SCALE
#define B6C 0x0101 // 0.0157 * 2^LUX_SCALE
#define M6C 0x0127 // 0.0180 * 2^LUX_SCALE
#define K7C 0x029a // 1.3 * 2^RATIO_SCALE
#define B7C 0x0037 // 0.00338 * 2^LUX_SCALE
#define M7C 0x002b // 0.00260 * 2^LUX_SCALE
#define K8C 0x029a // 1.3 * 2^RATIO_SCALE
#define B8C 0x0000 // 0.000 * 2^LUX_SCALE
#define M8C 0x0000 // 0.000 * 2^LUX_SCALE

unsigned long tsl2561_init(void)
{
	   i2c_start(TSL2561AddressWrite_Float+I2C_WRITE);
       i2c_write(ControlRegister);  
       i2c_write(TurnOnBits);
       i2c_stop();
	   
       i2c_start(TSL2561AddressWrite_Float+I2C_WRITE);
       i2c_write(0x81); 
// 	   i2c_write(iGain); 
	   i2c_write(TimingRegister); 
       i2c_stop();
	   
	   return(0);
}

unsigned long tsl2561_lux(void)
{
	   i2c_start(TSL2561AddressWrite_Float+I2C_WRITE);
       i2c_write(Data0LowByteMode);                             // 8 is the command register and C is the data low register of channel 0 
       i2c_rep_start(TSL2561AddressWrite_Float+I2C_READ);       // set device address and read mode
       Ch0DataLow  = i2c_read_ack();                             // read one byte from EEPROM
       Ch0DataHigh = i2c_read_ack();                             // read one byte from EEPROM
       Ch1DataLow  = i2c_read_ack();                             // read one byte from EEPROM
       Ch1DataHigh = i2c_read_ack();                             // read one byte from EEPROM
       i2c_stop();	
	   
   ch0 = 256 * Ch0DataHigh + Ch0DataLow; //Shift Data0High to upper byte
   ch1 = 256 * Ch1DataHigh + Ch1DataLow; //Shift Data1High to upper byte
   
   /*printf("printing  Intensity in ch0 %unn", ch0);
   printf("printing  Intensity in ch1 %unn", ch1);
*/
// lux equation approximation without floating point calculations
//////////////////////////////////////////////////////////////////////////////
// Routine: unsigned int CalculateLux(unsigned int ch0, unsigned int ch0, int iType)
//
// Description: Calculate the approximate illuminance (lux) given the raw
// channel values of the TSL2560. The equation if implemented
// as a piece-wise linear approximation.
//
// Arguments: unsigned int iGain - gain, where 0:1X, 1:16X
// unsigned int tInt - integration time, where 0:13.7mS, 1:100mS, 2:402mS,
// 3:Manual
// unsigned int ch0 - raw channel value from channel 0 of TSL2560
// unsigned int ch1 - raw channel value from channel 1 of TSL2560
// unsigned int iType - package type (T or CS)
//
// Return: unsigned int - the approximate illuminance (lux)
//
/////////////////////////////////////////////////////////////////////////////



//------------------------------------------------------------------------
// first, scale the channel values depending on the gain and integration time
// 16X, 402mS is nominal.
// scale if integration time is NOT 402 msec

   volatile uint32_t overFlowCounter = 100;
unsigned long chScale;
unsigned long channel1;
unsigned long channel0;

printf("printing overFlowCounters %lun", overFlowCounter);

switch (tInt)
{
case 0: // 13.7 msec
chScale = CHSCALE_TINT0;
break;
case 1: // 101 msec
chScale = CHSCALE_TINT1;
break;
default: // assume no scaling
chScale = (1 << CH_SCALE);
break;
}


// scale if gain is NOT 16X
if (!iGain) chScale = chScale << 4; // scale 1X to 16X
// scale the channel values
channel0 = (ch0 * chScale) >> CH_SCALE;
channel1 = (ch1 * chScale) >> CH_SCALE;
//------------------------------------------------------------------------
// find the ratio of the channel values (Channel1/Channel0)
// protect against divide by zero
unsigned long ratio1 = 0;
if (channel0 != 0) ratio1 = (channel1 << (RATIO_SCALE+1)) / channel0;
// round the ratio value
unsigned long ratio = (ratio1 + 1) >> 1;
// is ratio <= eachBreak ?

/*printf("printing  ratio in  %lunn", ratio);*/

switch (iType)
{
case 0: // T package
if ((ratio >= 0) && (ratio <= K1T))
{b=B1T; m=M1T;}
else if (ratio <= K2T)
{b=B2T; m=M2T;}
else if (ratio <= K3T)
{b=B3T; m=M3T;}
else if (ratio <= K4T)
{b=B4T; m=M4T;}
else if (ratio <= K5T)
{b=B5T; m=M5T;}
else if (ratio <= K6T)
{b=B6T; m=M6T;}
else if (ratio <= K7T)
{b=B7T; m=M7T;}
else if (ratio > K8T)
{b=B8T; m=M8T;}
break;
case 1:// CS package
if ((ratio >= 0) && (ratio <= K1C))
{b=B1C; m=M1C;}
else if (ratio <= K2C)
{b=B2C; m=M2C;}
else if (ratio <= K3C)
{b=B3C; m=M3C;}
else if (ratio <= K4C)
{b=B4C; m=M4C;}
else if (ratio <= K5C)
{b=B5C; m=M5C;}
else if (ratio <= K6C)
{b=B6C; m=M6C;}
else if (ratio <= K7C)
{b=B7C; m=M7C;}
else if (ratio > K8C)
{b=B8C; m=M8C;}
break;
}
unsigned long temp;
temp = ((channel0 * b) - (channel1 * m));
// do not allow negative lux value
if (temp < 0) temp = 0;
// round lsb (2^(LUX_SCALE-1))
temp += (1 << (LUX_SCALE-1));
// strip off fractional portion
unsigned long lux = temp >> LUX_SCALE;


   if ( lux > 65500)
   {
     lux = 65500;
   }



return(lux);

printf("printing  Intensity in  %lunn", lux);

}

Post a reply to John Abdul

Think you can help John Abdul ? Then post your thoughts that might help John Abdul. You will earn a lot of reputation in the technical community.

If your program is in multiple files, then ZIP the entire folder and attach below

Images and Screenshots

These helps other better understand your suggestion.