Rev Author Line No. Line
3021 kaklik 1 /* I2C Light Sensor
2  
3 The circuit:
4 * SD card attached to SPI bus as follows:
5 ** MOSI/CMD - PB3
6 ** MISO/DAT0 - PB4
7 ** CLK - PB5
8 ** CS/CD/DAT3 - PD4
9  
10 I2C pins PC4, PC5
11  
12 */
13  
14 #include <Wire.h>
15 #include <math.h>
16 #include <stdlib.h>
17 #include <SD.h>
18  
19 #define chipSelect 10 //PB2
20  
21 #define address 0x44 // A0 = L
22  
23 #define LIGHT_ENABLE 1
24 #define LIGHT_DISABLE 0
25  
26 #define LIGHT_ONETIME 0
27 #define LIGHT_CONTINUOUS 1
28  
29 #define LIGHT_SENSE_VIS 0
30 #define LIGHT_SENSE_IR 1
31  
32 #define LIGHT_INTERNAL_16 0b00000000
33 #define LIGHT_INTERNAL_12 0b00000100
34 #define LIGHT_INTERNAL_8 0b00001000
35 #define LIGHT_INTERNAL_4 0b00001100
36 #define LIGHT_EXTERNAL_ADC 0b00010000
37 #define LIGHT_EXTERNAL_TIMER 0b00010100
38  
39 //#define LIGHT_AUTORANGE 0
40  
41 #define LIGHT_RANGE1 0b00000000
42 #define LIGHT_RANGE2 0b00000001
43 #define LIGHT_RANGE3 0b00000010
44 #define LIGHT_RANGE4 0b00000011
45  
46 #include "WProgram.h"
47 void setup();
48 void led_blink();
49 int set_light_sensor(int en, int mode, int light, int res, int range);
50 float get_light_measurement();
51 void loop();
52 char filename[13];
53  
54 void setup()
55 {
56 int count=0;
57  
58 Wire.begin(); // join i2c bus (address optional for master)
59  
60 pinMode(3, OUTPUT); // LED pro blikani, aby bylo videt, ze to neco dela
61 pinMode(5, OUTPUT); // LED pro blikani, aby bylo videt, ze to neco dela
62 Serial.begin(9600); // Zmerena intenzita osvetleni se bude vypisovat na seriovou linku
63  
64 Serial.println("LABduino SD card logging luxmeter - (c) MLAB.cz, kaklik 2012");
65 Serial.print("Initializing SD card...");
66 // make sure that the default chip select pin is set to
67 // output, even if you don't use it:
68 pinMode(10, OUTPUT);
69  
70 // see if the card is present and can be initialized:
71 if (!SD.begin(chipSelect)) {
72 Serial.println("Card failed, or not present");
73 // don't do anything more:
74 while(true);
75 }
76 Serial.println("card initialized.");
77 Serial.print("searching for files...");
78  
79 do
80 {
81 sprintf(filename,"Lux%d.txt",count);
82 count++;
83 }
84 while(SD.exists(filename));
85 Serial.print("Using ");
86 Serial.println(filename);
87 }
88  
89 void led_blink()
90 {
91 digitalWrite(3, HIGH); // set the LED on
92 delay(20);
93 digitalWrite(3, LOW); // set the LED off
94  
95 // digitalWrite(3, LOW); // set the LED off
96 // delay(20);
97 // digitalWrite(3, HIGH); // set the LED on
98 }
99  
100 /*int light_sensor_write( unsigned int data, unsigned int address)
101 {
102 }
103 */
104  
105  
106 int set_light_sensor(int en, int mode, int light, int res, int range)
107 {
108 int command=0;
109  
110 command = (command & 0b01111111) | (en << 7);
111 command = (command & 0b10111111) | (mode << 6);
112 command = (command & 0b11011111) | (light << 5);
113 command = (command & 0b11100011) | (res << 2);
114 command = (command & 0b11111100) | (range);
115  
116 // Setup device
117 Wire.beginTransmission(address);
118 Wire.write(byte(0x00)); // sends address
119 Wire.write(byte(command)); // setup (eye light sensing; one time measurement; measurement range 1)
120 Wire.endTransmission(); // stop transmitting
121  
122 // Connect to device and set register address
123 Wire.beginTransmission(address);
124 Wire.write(byte(0x00)); // sends address (command register)
125 Wire.endTransmission(); // stop transmitting
126 // verify written command byte
127 Wire.beginTransmission(address);
128 Wire.requestFrom(address, 1);
129 if (command != Wire.read())
130 {
131 Serial.println("Error in sensor setting");
132 return 4;
133 }
134 Wire.endTransmission(); // stop transmitting
135 return 0;
136 }
137  
138 float get_light_measurement()
139 {
140 unsigned int ret=0;
141 unsigned int setting=0; // variable to storage readed settings
142  
143 unsigned long int resolution; // parsed ADC bit resolution
144 unsigned int range; // parsed measurement range
145  
146 // Connect to device and set register address
147 Wire.beginTransmission(address);
148 Wire.write(0x01); // sends address of LSB reagister
149 Wire.endTransmission(); // stop transmitting
150  
151 // Connect to device and request first byte
152 Wire.beginTransmission(address);
153 Wire.requestFrom(address, 1);
154 ret = Wire.read();
155 Wire.endTransmission(); // stop transmitting
156  
157 // Connect to device and set register address
158 Wire.beginTransmission(address);
159 Wire.write(0x02); // sends address of MSB register
160 Wire.endTransmission(); // stop transmitting
161  
162 // Connect to device and request second byte
163 Wire.beginTransmission(address);
164 Wire.requestFrom(address, 1);
165 ret +=256 * Wire.read();
166 Wire.endTransmission(); // stop transmitting
167  
168  
169 // Connect to device and set register address
170 Wire.beginTransmission(address);
171 Wire.write(byte(0x00)); // sends address (command register)
172 Wire.endTransmission(); // stop transmitting
173 // get sensor setting
174 Wire.beginTransmission(address);
175 Wire.requestFrom(address, 1);
176 setting = Wire.read();
177 Wire.endTransmission(); // stop transmitting
178  
179 switch (setting & 0b00011100) // determine ADC resolution
180 {
181 case LIGHT_INTERNAL_16:
182 resolution=65536;
183 break;
184  
185 case LIGHT_INTERNAL_12:
186 resolution=4096;
187 break;
188  
189 case LIGHT_INTERNAL_8:
190 resolution=256;
191 break;
192  
193 case LIGHT_INTERNAL_4:
194 resolution=16;
195 break;
196 }
197  
198 switch (setting & 0b00000011) // determine measurement range
199 {
200 case LIGHT_RANGE1:
201 range=1000;
202 break;
203  
204 case LIGHT_RANGE2:
205 range=4000;
206 break;
207  
208 case LIGHT_RANGE3:
209 range=16000;
210 break;
211  
212 case LIGHT_RANGE4:
213 range=64000;
214 break;
215 }
216 return ((500000.0*range)/(510000.0*resolution)*ret); // calculate output value
217 }
218  
219 void loop()
220 {
221 float luxVIS=0;
222 float luxIR=0;
223 float time;
224  
225 set_light_sensor(LIGHT_ENABLE, LIGHT_ONETIME, LIGHT_SENSE_VIS, LIGHT_INTERNAL_16, LIGHT_RANGE3); //setup sensor for visible measuring
226 led_blink(); // Delay for measurement
227 delay(500);
228 luxVIS=get_light_measurement();
229  
230 time=millis()/1000.0;
231  
232 set_light_sensor(LIGHT_ENABLE, LIGHT_ONETIME, LIGHT_SENSE_IR, LIGHT_INTERNAL_16, LIGHT_RANGE3); // setup sensor for infrared measuring
233 led_blink(); // Delay for measurement
234 delay(500);
235 luxIR=get_light_measurement();
236  
237 // open the file. note that only one file can be open at a time,
238 // so you have to close this one before opening another.
239 File dataFile = SD.open(filename, FILE_WRITE);
240  
241 // if the file is available, write to it:
242 if (dataFile) {
243 dataFile.print("$LUX0.1 ");
244 dataFile.print(time,3);
245 dataFile.print(" ");
246 dataFile.print(luxVIS,3);
247 dataFile.print(" ");
248 dataFile.println(luxIR,3);
249 dataFile.close();
250  
251 // print to the serial port too:
252 Serial.print("$LUX0.1 ");
253 Serial.print(time,3);
254 Serial.print(" ");
255 Serial.print(luxVIS,3);
256 Serial.print(" ");
257 Serial.println(luxIR,3);
258 }
259 // if the file isn't open, pop up an error:
260 else {
261 Serial.print("error opening ");
262 Serial.println(filename);
263 }
264 delay(2000);
265 }
266  
267