38 ** $QT_END_LICENSE$ |
38 ** $QT_END_LICENSE$ |
39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "n900lightsensor.h" |
42 #include "n900lightsensor.h" |
|
43 #include <QFile> |
43 #include <QDebug> |
44 #include <QDebug> |
44 #include <time.h> |
45 #include <time.h> |
45 |
46 |
46 const char *n900lightsensor::id("n900.ambientlight"); |
47 const char *n900lightsensor::id("n900.ambientlight"); |
47 const char *n900lightsensor::filename("/sys/class/i2c-adapter/i2c-2/2-0029/lux"); |
48 const char *n900lightsensor::filename("/sys/class/i2c-adapter/i2c-2/2-0029/lux"); |
48 |
49 |
49 n900lightsensor::n900lightsensor(QSensor *sensor) |
50 n900lightsensor::n900lightsensor(QSensor *sensor) |
50 : n900filebasedsensor(sensor) |
51 : n900filebasedsensor(sensor) |
51 { |
52 { |
52 setReading<QAmbientLightReading>(&m_reading); |
53 setReading<QAmbientLightReading>(&m_reading); |
|
54 // Sensor takes 12-400ms to complete one reading and is triggered by |
|
55 // a read of the /sys file (no interrupt/timing loop/etc. is used). |
|
56 // Since no continuous operation is possible, don't set a data rate. |
|
57 addDataRate(2, 2); // Close enough to 2 Hz |
|
58 sensor->setDataRate(2); |
|
59 setDescription(QLatin1String("tsl2563")); |
53 } |
60 } |
|
61 |
|
62 void n900lightsensor::start() |
|
63 { |
|
64 if (!QFile::exists(QLatin1String(filename))) |
|
65 goto error; |
|
66 |
|
67 n900filebasedsensor::start(); |
|
68 return; |
|
69 |
|
70 error: |
|
71 sensorStopped(); |
|
72 } |
|
73 |
|
74 struct lux_limit { |
|
75 int min; |
|
76 int max; |
|
77 }; |
|
78 |
|
79 // Defines the min and max lux values that a given level has. |
|
80 // These are used to add histeresis to the sensor. |
|
81 // If the previous level is below a level, the lux must be at or above the minimum. |
|
82 // If the previous level is above a level, the lux muyt be at or below the maximum. |
|
83 static lux_limit limits[] = { |
|
84 { 0, 0 }, // Undefined (not used) |
|
85 { 0, 5 }, // Dark |
|
86 { 10, 50 }, // Twilight |
|
87 { 100, 200 }, // Light |
|
88 { 500, 2000 }, // Bright |
|
89 { 5000, 0 } // Sunny |
|
90 }; |
|
91 |
|
92 #if 0 |
|
93 // Used for debugging |
|
94 static QString light_level(int level) |
|
95 { |
|
96 switch (level) { |
|
97 case 1: |
|
98 return QLatin1String("Dark"); |
|
99 case 2: |
|
100 return QLatin1String("Twilight"); |
|
101 case 3: |
|
102 return QLatin1String("Light"); |
|
103 case 4: |
|
104 return QLatin1String("Bright"); |
|
105 case 5: |
|
106 return QLatin1String("Sunny"); |
|
107 default: |
|
108 return QLatin1String("Undefined"); |
|
109 } |
|
110 } |
|
111 #endif |
54 |
112 |
55 void n900lightsensor::poll() |
113 void n900lightsensor::poll() |
56 { |
114 { |
57 FILE *fd = fopen(filename, "r"); |
115 FILE *fd = fopen(filename, "r"); |
58 if (!fd) return; |
116 if (!fd) return; |
59 int lux; |
117 int lux; |
60 int rs = fscanf(fd, "%i", &lux); |
118 int rs = fscanf(fd, "%i", &lux); |
61 fclose(fd); |
119 fclose(fd); |
62 if (rs != 1) return; |
120 if (rs != 1) return; |
63 |
121 |
64 QAmbientLightReading::LightLevel lightLevel = QAmbientLightReading::Undefined; |
122 // It's unweildly dealing with these constants so make some |
65 if (lux < 10) |
123 // local aliases that are shorter. This makes the code below |
66 lightLevel = QAmbientLightReading::Dark; |
124 // much easier to read. |
67 else if (lux < 50) |
125 enum { |
68 lightLevel = QAmbientLightReading::Twilight; |
126 Undefined = QAmbientLightReading::Undefined, |
69 else if (lux < 100) |
127 Dark = QAmbientLightReading::Dark, |
70 lightLevel = QAmbientLightReading::Light; |
128 Twilight = QAmbientLightReading::Twilight, |
71 else if (lux < 150) |
129 Light = QAmbientLightReading::Light, |
72 lightLevel = QAmbientLightReading::Bright; |
130 Bright = QAmbientLightReading::Bright, |
73 else |
131 Sunny = QAmbientLightReading::Sunny |
74 lightLevel = QAmbientLightReading::Sunny; |
132 }; |
75 |
133 |
76 m_reading.setTimestamp(clock()); |
134 int lightLevel = m_reading.lightLevel(); |
77 m_reading.setLightLevel(lightLevel); |
135 // Check for change direction to allow for histeresis |
|
136 if (lightLevel < Sunny && lux >= limits[Sunny ].min) lightLevel = Sunny; |
|
137 else if (lightLevel < Bright && lux >= limits[Bright ].min) lightLevel = Bright; |
|
138 else if (lightLevel < Light && lux >= limits[Light ].min) lightLevel = Light; |
|
139 else if (lightLevel < Twilight && lux >= limits[Twilight].min) lightLevel = Twilight; |
|
140 else if (lightLevel < Dark && lux >= limits[Dark ].min) lightLevel = Dark; |
|
141 else if (lightLevel > Dark && lux <= limits[Dark ].max) lightLevel = Dark; |
|
142 else if (lightLevel > Twilight && lux <= limits[Twilight].max) lightLevel = Twilight; |
|
143 else if (lightLevel > Light && lux <= limits[Light ].max) lightLevel = Light; |
|
144 else if (lightLevel > Bright && lux <= limits[Bright ].max) lightLevel = Bright; |
78 |
145 |
79 newReadingAvailable(); |
146 //qDebug() << "lightLevel" << light_level(lightLevel) << "lux" << lux; |
|
147 |
|
148 if (static_cast<int>(m_reading.lightLevel()) != lightLevel) { |
|
149 m_reading.setTimestamp(clock()); |
|
150 m_reading.setLightLevel(static_cast<QAmbientLightReading::LightLevel>(lightLevel)); |
|
151 |
|
152 newReadingAvailable(); |
|
153 } |
80 } |
154 } |
81 |
155 |