Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions inc/core/MicroBitComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_ID_ACCELEROMETER 4
#define MICROBIT_ID_COMPASS 5
#define MICROBIT_ID_DISPLAY 6
#define MICROBIT_ID_LIGHT_SENSOR 7

//EDGE connector events
#define MICROBIT_IO_PINS 20
Expand Down
6 changes: 5 additions & 1 deletion inc/drivers/MicroBitDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,13 +627,17 @@ class MicroBitDisplay : public MicroBitComponent
* This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
* that the display does not suffer from artifacts.
*
* @param valid_only True to return -1 if full set of results not taken and to return a stale
* but valid reading in the case of invalid results. False to use all results.
* Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
*
* @return an indicative light level in the range 0 - 255.
*
* @note this will return 0 on the first call to this method, a light reading
* will be available after the display has activated the light sensor for the
* first time.
*/
int readLightLevel();
int readLightLevel(bool valid_only = false);

/**
* Destructor for MicroBitDisplay, where we deregister this instance from the array of system components.
Expand Down
36 changes: 30 additions & 6 deletions inc/drivers/MicroBitLightSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ DEALINGS IN THE SOFTWARE.
#include "EventModel.h"
#include "MicroBitMatrixMaps.h"

#define MICROBIT_LIGHT_SENSOR_CHAN_NUM 3
#define MICROBIT_LIGHT_SENSOR_AN_SET_TIME 4000
#define MICROBIT_LIGHT_SENSOR_TICK_PERIOD 5
/**
* Event codes raised by MicroBitDisplay
*/
#define MICROBIT_DISPLAY_EVT_LIGHT_SENSE_READY 1

#define MICROBIT_LIGHT_SENSOR_CHAN_NUM 3
#define MICROBIT_LIGHT_SENSOR_AN_SET_TIME 4000
#define MICROBIT_LIGHT_SENSOR_TICK_PERIOD 5

#define MICROBIT_LIGHT_SENSOR_MAX_VALUE 338
#define MICROBIT_LIGHT_SENSOR_MIN_VALUE 75
#define MICROBIT_LIGHT_SENSOR_MAX_VALUE 338
#define MICROBIT_LIGHT_SENSOR_MIN_VALUE 75

/**
* Class definition for MicroBitLightSensor.
Expand All @@ -50,6 +55,12 @@ class MicroBitLightSensor
//contains the results from each section of the display
int results[MICROBIT_LIGHT_SENSOR_CHAN_NUM];

// The average of the three results.
int average;

// The average of the three results the last time all results were valid.
int valid_average;

//holds the current channel (also used to index the results array)
uint8_t chan;

Expand Down Expand Up @@ -81,6 +92,15 @@ class MicroBitLightSensor
*/
void analogDisable();

/**
* This method updates the average of the three results, as well as the valid_average
* if results are valid. The MICROBIT_DISPLAY_EVT_LIGHT_SENSE_READY event is sent if
* the valid_average is updated.
*
* @return returns a boolean representing whether or not the results are valid.
*/
bool update_averages();

public:

/**
Expand Down Expand Up @@ -111,10 +131,14 @@ class MicroBitLightSensor
*
* Where each number represents a different section on the 5 x 5 matrix display.
*
* @param valid_only True to return -1 if full set of results not taken and to return a stale
* but valid reading in the case of invalid results. False to use all results.
* Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
*
* @return returns a value in the range 0 - 255 where 0 is dark, and 255
* is very bright
*/
int read();
int read(bool valid_only = false);

/**
* The method that is invoked by sending MICROBIT_DISPLAY_EVT_LIGHT_SENSE
Expand Down
14 changes: 9 additions & 5 deletions source/drivers/MicroBitDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1210,21 +1210,25 @@ MicroBitImage MicroBitDisplay::screenShot()
* This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
* that the display does not suffer from artifacts.
*
* @param valid_only True to return -1 if full set of results not taken and to return a stale
* but valid reading in the case of invalid results. False to use all results.
* Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
*
* @return an indicative light level in the range 0 - 255.
*
* @note this will return 0 on the first call to this method, a light reading
* will be available after the display has activated the light sensor for the
* first time.
* @note this will return 255 (previously said 0, which was incorrect)
* on the first call to this method, a light reading will be available
* after the display has activated the light sensor for the first time.
*/
int MicroBitDisplay::readLightLevel()
int MicroBitDisplay::readLightLevel(bool valid_only)
{
if(mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
{
setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE);
this->lightSensor = new MicroBitLightSensor(matrixMap);
}

return this->lightSensor->read();
return this->lightSensor->read(valid_only);
}

/**
Expand Down
46 changes: 39 additions & 7 deletions source/drivers/MicroBitLightSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ void MicroBitLightSensor::analogReady()
chan++;

chan = chan % MICROBIT_LIGHT_SENSOR_CHAN_NUM;

update_averages();
}

/**
Expand Down Expand Up @@ -87,15 +89,43 @@ MicroBitLightSensor::MicroBitLightSensor(const MatrixMap &map) :
{
this->chan = 0;

valid_average = -1;

for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++)
results[i] = 0;
results[i] = -1;

if (EventModel::defaultEventBus)
EventModel::defaultEventBus->listen(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing, MESSAGE_BUS_LISTENER_IMMEDIATE);

this->sensePin = NULL;
}

/**
* This method updates the average of the three results, as well as the valid_average
* if results are valid. The MICROBIT_DISPLAY_EVT_LIGHT_SENSE_READY event is sent if
* the valid_average is updated.
*
* @return returns a boolean representing whether or not the results are valid.
*/
bool MicroBitLightSensor::update_averages()
{
bool valid = true;
int sum = 0;
for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++) {
if (this->results[i] < 0 || this->results[i] > 450) {
valid = false;
}
// Use zero if a result hasn't been used rather than -1.
sum += max(this->results[i], 0);
}
this->average = sum / MICROBIT_LIGHT_SENSOR_CHAN_NUM;
if (valid) {
this->valid_average = this->average;
MicroBitEvent(MICROBIT_ID_LIGHT_SENSOR, MICROBIT_DISPLAY_EVT_LIGHT_SENSE_READY);
}
return valid;
}

/**
* This method returns a summed average of the three sections of the display.
*
Expand All @@ -114,17 +144,19 @@ MicroBitLightSensor::MicroBitLightSensor(const MatrixMap &map) :
*
* Where each number represents a different section on the 5 x 5 matrix display.
*
* @param valid_only True to return -1 if full set of results not taken and to return a stale
* but valid reading in the case of invalid results. False to use all results.
* Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
*
* @return returns a value in the range 0 - 255 where 0 is dark, and 255
* is very bright
*/
int MicroBitLightSensor::read()
int MicroBitLightSensor::read(bool valid_only)
{
int sum = 0;

for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++)
sum += results[i];
int average = valid_only ? this->valid_average : this->average;

int average = sum / MICROBIT_LIGHT_SENSOR_CHAN_NUM;
if (valid_only && average < 0)
return -1;

average = min(average, MICROBIT_LIGHT_SENSOR_MAX_VALUE);

Expand Down