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