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