qtmobility/plugins/sensors/n900/n900lightsensor.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    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