microbit: integrated MicroBitLightSensor with MicroBitDisplay

Previously, to light sense a user would have to configure a
MicroBitLightSensor instance themselves, and flip the display mode
manually. This is difficult in languages that target our API.

This commit resolves that by adding a new method readLightLevel which
flips the display mode, and instantiates a light sensor.

When changing the mode, the tickSpeed is also modified to reduce
artefacts on the display.
This commit is contained in:
James Devine 2016-01-29 14:13:41 +00:00
parent 2049e63039
commit 6b0e9cf489
2 changed files with 59 additions and 0 deletions

View File

@ -160,6 +160,9 @@ class MicroBitDisplay : public MicroBitComponent
// The number of pixels the image is shifted on the display in each quantum.
int8_t scrollingImageStride;
// A pointer to an instance of light sensor, if in use
MicroBitLightSensor* lightSensor;
// Flag to indicate if image has been rendered to screen yet (or not)
bool scrollingImageRendered;
@ -574,6 +577,19 @@ public:
*/
MicroBitImage screenShot();
/**
* Constructs an instance of a MicroBitLightSensor if not already configured
* and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
*
* This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
* that the display does not suffer from artifacts.
*
* @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();
/**
* Destructor for MicroBitDisplay, so that we deregister ourselves as a systemComponent
*/

View File

@ -44,6 +44,8 @@ MicroBitDisplay::MicroBitDisplay(uint16_t id, uint8_t x, uint8_t y) :
this->mode = DISPLAY_MODE_BLACK_AND_WHITE;
this->animationMode = ANIMATION_MODE_NONE;
this->lightSensor = NULL;
uBit.flags |= MICROBIT_FLAG_DISPLAY_RUNNING;
}
@ -922,6 +924,25 @@ int MicroBitDisplay::setBrightness(int b)
*/
void MicroBitDisplay::setDisplayMode(DisplayMode mode)
{
if(mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
{
//to reduce the artifacts on the display - increase the tick
if(uBit.getTickPeriod() != MICROBIT_LIGHT_SENSOR_TICK_PERIOD)
uBit.setTickPeriod(MICROBIT_LIGHT_SENSOR_TICK_PERIOD);
}
if(this->mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE && mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
{
//if we previously were in light sense mode - return to our default.
if(uBit.getTickPeriod() != MICROBIT_DEFAULT_TICK_PERIOD)
uBit.setTickPeriod(MICROBIT_DEFAULT_TICK_PERIOD);
delete this->lightSensor;
this->lightSensor = NULL;
}
this->mode = mode;
}
@ -1126,6 +1147,28 @@ MicroBitImage MicroBitDisplay::screenShot()
return image.crop(0,0,MICROBIT_DISPLAY_WIDTH,MICROBIT_DISPLAY_HEIGHT);
}
/**
* Constructs an instance of a MicroBitLightSensor if not already configured
* and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
*
* This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
* that the display does not suffer from artifacts.
*
* @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 MicroBitDisplay::readLightLevel()
{
if(mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
{
setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE);
this->lightSensor = new MicroBitLightSensor();
}
return this->lightSensor->read();
}
/**
* Destructor for MicroBitDisplay, so that we deregister ourselves as a systemComponent
*/