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