--- a/qtmobility/plugins/sensors/n900/n900lightsensor.cpp Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/plugins/sensors/n900/n900lightsensor.cpp Mon May 03 13:18:40 2010 +0300
@@ -40,6 +40,7 @@
****************************************************************************/
#include "n900lightsensor.h"
+#include <QFile>
#include <QDebug>
#include <time.h>
@@ -50,8 +51,65 @@
: n900filebasedsensor(sensor)
{
setReading<QAmbientLightReading>(&m_reading);
+ // Sensor takes 12-400ms to complete one reading and is triggered by
+ // a read of the /sys file (no interrupt/timing loop/etc. is used).
+ // Since no continuous operation is possible, don't set a data rate.
+ addDataRate(2, 2); // Close enough to 2 Hz
+ sensor->setDataRate(2);
+ setDescription(QLatin1String("tsl2563"));
}
+void n900lightsensor::start()
+{
+ if (!QFile::exists(QLatin1String(filename)))
+ goto error;
+
+ n900filebasedsensor::start();
+ return;
+
+error:
+ sensorStopped();
+}
+
+struct lux_limit {
+ int min;
+ int max;
+};
+
+// Defines the min and max lux values that a given level has.
+// These are used to add histeresis to the sensor.
+// If the previous level is below a level, the lux must be at or above the minimum.
+// If the previous level is above a level, the lux muyt be at or below the maximum.
+static lux_limit limits[] = {
+ { 0, 0 }, // Undefined (not used)
+ { 0, 5 }, // Dark
+ { 10, 50 }, // Twilight
+ { 100, 200 }, // Light
+ { 500, 2000 }, // Bright
+ { 5000, 0 } // Sunny
+};
+
+#if 0
+// Used for debugging
+static QString light_level(int level)
+{
+ switch (level) {
+ case 1:
+ return QLatin1String("Dark");
+ case 2:
+ return QLatin1String("Twilight");
+ case 3:
+ return QLatin1String("Light");
+ case 4:
+ return QLatin1String("Bright");
+ case 5:
+ return QLatin1String("Sunny");
+ default:
+ return QLatin1String("Undefined");
+ }
+}
+#endif
+
void n900lightsensor::poll()
{
FILE *fd = fopen(filename, "r");
@@ -61,21 +119,37 @@
fclose(fd);
if (rs != 1) return;
- QAmbientLightReading::LightLevel lightLevel = QAmbientLightReading::Undefined;
- if (lux < 10)
- lightLevel = QAmbientLightReading::Dark;
- else if (lux < 50)
- lightLevel = QAmbientLightReading::Twilight;
- else if (lux < 100)
- lightLevel = QAmbientLightReading::Light;
- else if (lux < 150)
- lightLevel = QAmbientLightReading::Bright;
- else
- lightLevel = QAmbientLightReading::Sunny;
+ // It's unweildly dealing with these constants so make some
+ // local aliases that are shorter. This makes the code below
+ // much easier to read.
+ enum {
+ Undefined = QAmbientLightReading::Undefined,
+ Dark = QAmbientLightReading::Dark,
+ Twilight = QAmbientLightReading::Twilight,
+ Light = QAmbientLightReading::Light,
+ Bright = QAmbientLightReading::Bright,
+ Sunny = QAmbientLightReading::Sunny
+ };
- m_reading.setTimestamp(clock());
- m_reading.setLightLevel(lightLevel);
+ int lightLevel = m_reading.lightLevel();
+ // Check for change direction to allow for histeresis
+ if (lightLevel < Sunny && lux >= limits[Sunny ].min) lightLevel = Sunny;
+ else if (lightLevel < Bright && lux >= limits[Bright ].min) lightLevel = Bright;
+ else if (lightLevel < Light && lux >= limits[Light ].min) lightLevel = Light;
+ else if (lightLevel < Twilight && lux >= limits[Twilight].min) lightLevel = Twilight;
+ else if (lightLevel < Dark && lux >= limits[Dark ].min) lightLevel = Dark;
+ else if (lightLevel > Dark && lux <= limits[Dark ].max) lightLevel = Dark;
+ else if (lightLevel > Twilight && lux <= limits[Twilight].max) lightLevel = Twilight;
+ else if (lightLevel > Light && lux <= limits[Light ].max) lightLevel = Light;
+ else if (lightLevel > Bright && lux <= limits[Bright ].max) lightLevel = Bright;
- newReadingAvailable();
+ //qDebug() << "lightLevel" << light_level(lightLevel) << "lux" << lux;
+
+ if (static_cast<int>(m_reading.lightLevel()) != lightLevel) {
+ m_reading.setTimestamp(clock());
+ m_reading.setLightLevel(static_cast<QAmbientLightReading::LightLevel>(lightLevel));
+
+ newReadingAvailable();
+ }
}