/* I2C Light SensorThe circuit:* SD card attached to SPI bus as follows:** MOSI/CMD - PB3** MISO/DAT0 - PB4** CLK - PB5** CS/CD/DAT3 - PD4I2C pins PC4, PC5*/#include <Wire.h>#include <math.h>#include <stdlib.h>#include <SD.h>#define chipSelect 10 //PB2#define address 0x44 // A0 = L#define LIGHT_ENABLE 1#define LIGHT_DISABLE 0#define LIGHT_ONETIME 0#define LIGHT_CONTINUOUS 1#define LIGHT_SENSE_VIS 0#define LIGHT_SENSE_IR 1#define LIGHT_INTERNAL_16 0b00000000#define LIGHT_INTERNAL_12 0b00000100#define LIGHT_INTERNAL_8 0b00001000#define LIGHT_INTERNAL_4 0b00001100#define LIGHT_EXTERNAL_ADC 0b00010000#define LIGHT_EXTERNAL_TIMER 0b00010100//#define LIGHT_AUTORANGE 0#define LIGHT_RANGE1 0b00000000#define LIGHT_RANGE2 0b00000001#define LIGHT_RANGE3 0b00000010#define LIGHT_RANGE4 0b00000011#include "WProgram.h"void setup();void led_blink();int set_light_sensor(int en, int mode, int light, int res, int range);float get_light_measurement();void loop();char filename[13];void setup(){int count=0;Wire.begin(); // join i2c bus (address optional for master)pinMode(3, OUTPUT); // LED pro blikani, aby bylo videt, ze to neco delapinMode(5, OUTPUT); // LED pro blikani, aby bylo videt, ze to neco delaSerial.begin(9600); // Zmerena intenzita osvetleni se bude vypisovat na seriovou linkuSerial.println("LABduino SD card logging luxmeter - (c) MLAB.cz, kaklik 2012");Serial.print("Initializing SD card...");// make sure that the default chip select pin is set to// output, even if you don't use it:pinMode(10, OUTPUT);// see if the card is present and can be initialized:if (!SD.begin(chipSelect)) {Serial.println("Card failed, or not present");// don't do anything more:while(true);}Serial.println("card initialized.");Serial.print("searching for files...");do{sprintf(filename,"Lux%d.txt",count);count++;}while(SD.exists(filename));Serial.print("Using ");Serial.println(filename);}void led_blink(){digitalWrite(3, HIGH); // set the LED ondelay(20);digitalWrite(3, LOW); // set the LED off// digitalWrite(3, LOW); // set the LED off// delay(20);// digitalWrite(3, HIGH); // set the LED on}/*int light_sensor_write( unsigned int data, unsigned int address){}*/int set_light_sensor(int en, int mode, int light, int res, int range){int command=0;command = (command & 0b01111111) | (en << 7);command = (command & 0b10111111) | (mode << 6);command = (command & 0b11011111) | (light << 5);command = (command & 0b11100011) | (res << 2);command = (command & 0b11111100) | (range);// Setup deviceWire.beginTransmission(address);Wire.write(byte(0x00)); // sends addressWire.write(byte(command)); // setup (eye light sensing; one time measurement; measurement range 1)Wire.endTransmission(); // stop transmitting// Connect to device and set register addressWire.beginTransmission(address);Wire.write(byte(0x00)); // sends address (command register)Wire.endTransmission(); // stop transmitting// verify written command byteWire.beginTransmission(address);Wire.requestFrom(address, 1);if (command != Wire.read()){Serial.println("Error in sensor setting");return 4;}Wire.endTransmission(); // stop transmittingreturn 0;}float get_light_measurement(){unsigned int ret=0;unsigned int setting=0; // variable to storage readed settingsunsigned long int resolution; // parsed ADC bit resolutionunsigned int range; // parsed measurement range// Connect to device and set register addressWire.beginTransmission(address);Wire.write(0x01); // sends address of LSB reagisterWire.endTransmission(); // stop transmitting// Connect to device and request first byteWire.beginTransmission(address);Wire.requestFrom(address, 1);ret = Wire.read();Wire.endTransmission(); // stop transmitting// Connect to device and set register addressWire.beginTransmission(address);Wire.write(0x02); // sends address of MSB registerWire.endTransmission(); // stop transmitting// Connect to device and request second byteWire.beginTransmission(address);Wire.requestFrom(address, 1);ret +=256 * Wire.read();Wire.endTransmission(); // stop transmitting// Connect to device and set register addressWire.beginTransmission(address);Wire.write(byte(0x00)); // sends address (command register)Wire.endTransmission(); // stop transmitting// get sensor settingWire.beginTransmission(address);Wire.requestFrom(address, 1);setting = Wire.read();Wire.endTransmission(); // stop transmittingswitch (setting & 0b00011100) // determine ADC resolution{case LIGHT_INTERNAL_16:resolution=65536;break;case LIGHT_INTERNAL_12:resolution=4096;break;case LIGHT_INTERNAL_8:resolution=256;break;case LIGHT_INTERNAL_4:resolution=16;break;}switch (setting & 0b00000011) // determine measurement range{case LIGHT_RANGE1:range=1000;break;case LIGHT_RANGE2:range=4000;break;case LIGHT_RANGE3:range=16000;break;case LIGHT_RANGE4:range=64000;break;}return ((500000.0*range)/(510000.0*resolution)*ret); // calculate output value}void loop(){float luxVIS=0;float luxIR=0;float time;set_light_sensor(LIGHT_ENABLE, LIGHT_ONETIME, LIGHT_SENSE_VIS, LIGHT_INTERNAL_16, LIGHT_RANGE3); //setup sensor for visible measuringled_blink(); // Delay for measurementdelay(500);luxVIS=get_light_measurement();time=millis()/1000.0;set_light_sensor(LIGHT_ENABLE, LIGHT_ONETIME, LIGHT_SENSE_IR, LIGHT_INTERNAL_16, LIGHT_RANGE3); // setup sensor for infrared measuringled_blink(); // Delay for measurementdelay(500);luxIR=get_light_measurement();// open the file. note that only one file can be open at a time,// so you have to close this one before opening another.File dataFile = SD.open(filename, FILE_WRITE);// if the file is available, write to it:if (dataFile) {dataFile.print("$LUX0.1 ");dataFile.print(time,3);dataFile.print(" ");dataFile.print(luxVIS,3);dataFile.print(" ");dataFile.println(luxIR,3);dataFile.close();// print to the serial port too:Serial.print("$LUX0.1 ");Serial.print(time,3);Serial.print(" ");Serial.print(luxVIS,3);Serial.print(" ");Serial.println(luxIR,3);}// if the file isn't open, pop up an error:else {Serial.print("error opening ");Serial.println(filename);}delay(2000);}