No Changes

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit

Fork of microbit-dal by Lancaster University

Committer:
Asimov
Date:
Fri Jan 13 21:14:06 2017 +0000
Revision:
75:ae9a17da71af
Parent:
8:ec4465853952
No Changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for MicroBitLightSensor.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * This is an object that interleaves light sensing with MicroBitDisplay.
Jonathan Austin 1:8aa5cdb4ab67 30 */
Jonathan Austin 1:8aa5cdb4ab67 31
Jonathan Austin 1:8aa5cdb4ab67 32 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitLightSensor.h"
Jonathan Austin 1:8aa5cdb4ab67 34 #include "MicroBitDisplay.h"
Jonathan Austin 1:8aa5cdb4ab67 35
Jonathan Austin 1:8aa5cdb4ab67 36 /**
Jonathan Austin 1:8aa5cdb4ab67 37 * After the startSensing method has been called, this method will be called
Jonathan Austin 1:8aa5cdb4ab67 38 * MICROBIT_LIGHT_SENSOR_AN_SET_TIME after.
Jonathan Austin 1:8aa5cdb4ab67 39 *
Jonathan Austin 1:8aa5cdb4ab67 40 * It will then read from the currently selected channel using the AnalogIn
Jonathan Austin 1:8aa5cdb4ab67 41 * that was configured in the startSensing method.
Jonathan Austin 1:8aa5cdb4ab67 42 */
Jonathan Austin 1:8aa5cdb4ab67 43 void MicroBitLightSensor::analogReady()
Jonathan Austin 1:8aa5cdb4ab67 44 {
Jonathan Austin 1:8aa5cdb4ab67 45 this->results[chan] = this->sensePin->read_u16();
Jonathan Austin 1:8aa5cdb4ab67 46
Jonathan Austin 1:8aa5cdb4ab67 47 analogDisable();
Jonathan Austin 1:8aa5cdb4ab67 48
Jonathan Austin 1:8aa5cdb4ab67 49 DigitalOut((PinName)(matrixMap.columnStart + chan)).write(1);
Jonathan Austin 1:8aa5cdb4ab67 50
Jonathan Austin 1:8aa5cdb4ab67 51 chan++;
Jonathan Austin 1:8aa5cdb4ab67 52
Jonathan Austin 1:8aa5cdb4ab67 53 chan = chan % MICROBIT_LIGHT_SENSOR_CHAN_NUM;
Jonathan Austin 1:8aa5cdb4ab67 54 }
Jonathan Austin 1:8aa5cdb4ab67 55
Jonathan Austin 1:8aa5cdb4ab67 56 /**
Jonathan Austin 1:8aa5cdb4ab67 57 * Forcibly disables the AnalogIn, otherwise it will remain in possession
Jonathan Austin 1:8aa5cdb4ab67 58 * of the GPIO channel it is using, meaning that the display will not be
Jonathan Austin 1:8aa5cdb4ab67 59 * able to use a channel (COL).
Jonathan Austin 1:8aa5cdb4ab67 60 *
Jonathan Austin 1:8aa5cdb4ab67 61 * This is required as per PAN 3, details of which can be found here:
Jonathan Austin 1:8aa5cdb4ab67 62 *
Jonathan Austin 1:8aa5cdb4ab67 63 * https://www.nordicsemi.com/eng/nordic/download_resource/24634/5/88440387
Jonathan Austin 1:8aa5cdb4ab67 64 */
Jonathan Austin 1:8aa5cdb4ab67 65 void MicroBitLightSensor::analogDisable()
Jonathan Austin 1:8aa5cdb4ab67 66 {
Jonathan Austin 1:8aa5cdb4ab67 67 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;
Jonathan Austin 1:8aa5cdb4ab67 68
Jonathan Austin 1:8aa5cdb4ab67 69 NRF_ADC->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 70 (ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling << ADC_CONFIG_INPSEL_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 71 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 72 (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 73 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
Jonathan Austin 1:8aa5cdb4ab67 74 }
Jonathan Austin 1:8aa5cdb4ab67 75
Jonathan Austin 1:8aa5cdb4ab67 76 /**
Jonathan Austin 1:8aa5cdb4ab67 77 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 78 *
Jonathan Austin 1:8aa5cdb4ab67 79 * Create a representation of the light sensor.
Jonathan Austin 1:8aa5cdb4ab67 80 *
Jonathan Austin 1:8aa5cdb4ab67 81 * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
Jonathan Austin 1:8aa5cdb4ab67 82 * Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
Jonathan Austin 1:8aa5cdb4ab67 83 */
Jonathan Austin 1:8aa5cdb4ab67 84 MicroBitLightSensor::MicroBitLightSensor(const MatrixMap &map) :
Jonathan Austin 1:8aa5cdb4ab67 85 analogTrigger(),
Jonathan Austin 1:8aa5cdb4ab67 86 matrixMap(map)
Jonathan Austin 1:8aa5cdb4ab67 87 {
Jonathan Austin 1:8aa5cdb4ab67 88 this->chan = 0;
Jonathan Austin 1:8aa5cdb4ab67 89
LancasterUniversity 8:ec4465853952 90 for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++)
LancasterUniversity 8:ec4465853952 91 results[i] = 0;
LancasterUniversity 8:ec4465853952 92
Jonathan Austin 1:8aa5cdb4ab67 93 if (EventModel::defaultEventBus)
Jonathan Austin 1:8aa5cdb4ab67 94 EventModel::defaultEventBus->listen(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing, MESSAGE_BUS_LISTENER_IMMEDIATE);
Jonathan Austin 1:8aa5cdb4ab67 95
Jonathan Austin 1:8aa5cdb4ab67 96 this->sensePin = NULL;
Jonathan Austin 1:8aa5cdb4ab67 97 }
Jonathan Austin 1:8aa5cdb4ab67 98
Jonathan Austin 1:8aa5cdb4ab67 99 /**
Jonathan Austin 1:8aa5cdb4ab67 100 * This method returns a summed average of the three sections of the display.
Jonathan Austin 1:8aa5cdb4ab67 101 *
Jonathan Austin 1:8aa5cdb4ab67 102 * A section is defined as:
Jonathan Austin 1:8aa5cdb4ab67 103 * ___________________
Jonathan Austin 1:8aa5cdb4ab67 104 * | 1 | | 2 | | 3 |
Jonathan Austin 1:8aa5cdb4ab67 105 * |___|___|___|___|___|
Jonathan Austin 1:8aa5cdb4ab67 106 * | | | | | |
Jonathan Austin 1:8aa5cdb4ab67 107 * |___|___|___|___|___|
Jonathan Austin 1:8aa5cdb4ab67 108 * | 2 | | 3 | | 1 |
Jonathan Austin 1:8aa5cdb4ab67 109 * |___|___|___|___|___|
Jonathan Austin 1:8aa5cdb4ab67 110 * | | | | | |
Jonathan Austin 1:8aa5cdb4ab67 111 * |___|___|___|___|___|
Jonathan Austin 1:8aa5cdb4ab67 112 * | 3 | | 1 | | 2 |
Jonathan Austin 1:8aa5cdb4ab67 113 * |___|___|___|___|___|
Jonathan Austin 1:8aa5cdb4ab67 114 *
Jonathan Austin 1:8aa5cdb4ab67 115 * Where each number represents a different section on the 5 x 5 matrix display.
Jonathan Austin 1:8aa5cdb4ab67 116 *
Jonathan Austin 1:8aa5cdb4ab67 117 * @return returns a value in the range 0 - 255 where 0 is dark, and 255
Jonathan Austin 1:8aa5cdb4ab67 118 * is very bright
Jonathan Austin 1:8aa5cdb4ab67 119 */
Jonathan Austin 1:8aa5cdb4ab67 120 int MicroBitLightSensor::read()
Jonathan Austin 1:8aa5cdb4ab67 121 {
Jonathan Austin 1:8aa5cdb4ab67 122 int sum = 0;
Jonathan Austin 1:8aa5cdb4ab67 123
Jonathan Austin 1:8aa5cdb4ab67 124 for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++)
Jonathan Austin 1:8aa5cdb4ab67 125 sum += results[i];
Jonathan Austin 1:8aa5cdb4ab67 126
Jonathan Austin 1:8aa5cdb4ab67 127 int average = sum / MICROBIT_LIGHT_SENSOR_CHAN_NUM;
Jonathan Austin 1:8aa5cdb4ab67 128
Jonathan Austin 1:8aa5cdb4ab67 129 average = min(average, MICROBIT_LIGHT_SENSOR_MAX_VALUE);
Jonathan Austin 1:8aa5cdb4ab67 130
Jonathan Austin 1:8aa5cdb4ab67 131 average = max(average, MICROBIT_LIGHT_SENSOR_MIN_VALUE);
Jonathan Austin 1:8aa5cdb4ab67 132
Jonathan Austin 1:8aa5cdb4ab67 133 int inverted = (MICROBIT_LIGHT_SENSOR_MAX_VALUE - average) + MICROBIT_LIGHT_SENSOR_MIN_VALUE;
Jonathan Austin 1:8aa5cdb4ab67 134
Jonathan Austin 1:8aa5cdb4ab67 135 int a = 0;
Jonathan Austin 1:8aa5cdb4ab67 136
Jonathan Austin 1:8aa5cdb4ab67 137 int b = 255;
Jonathan Austin 1:8aa5cdb4ab67 138
Jonathan Austin 1:8aa5cdb4ab67 139 int normalised = a + ((((inverted - MICROBIT_LIGHT_SENSOR_MIN_VALUE)) * (b - a))/ (MICROBIT_LIGHT_SENSOR_MAX_VALUE - MICROBIT_LIGHT_SENSOR_MIN_VALUE));
Jonathan Austin 1:8aa5cdb4ab67 140
Jonathan Austin 1:8aa5cdb4ab67 141 return normalised;
Jonathan Austin 1:8aa5cdb4ab67 142 }
Jonathan Austin 1:8aa5cdb4ab67 143
Jonathan Austin 1:8aa5cdb4ab67 144 /**
Jonathan Austin 1:8aa5cdb4ab67 145 * The method that is invoked by sending MICROBIT_DISPLAY_EVT_LIGHT_SENSE
Jonathan Austin 1:8aa5cdb4ab67 146 * using the id MICROBIT_ID_DISPLAY.
Jonathan Austin 1:8aa5cdb4ab67 147 *
Jonathan Austin 1:8aa5cdb4ab67 148 * @note this can be manually driven by calling this member function, with
Jonathan Austin 1:8aa5cdb4ab67 149 * a MicroBitEvent using the CREATE_ONLY option of the MicroBitEvent
Jonathan Austin 1:8aa5cdb4ab67 150 * constructor.
Jonathan Austin 1:8aa5cdb4ab67 151 */
Jonathan Austin 1:8aa5cdb4ab67 152 void MicroBitLightSensor::startSensing(MicroBitEvent)
Jonathan Austin 1:8aa5cdb4ab67 153 {
Jonathan Austin 1:8aa5cdb4ab67 154 for(int rowCount = 0; rowCount < matrixMap.rows; rowCount++)
Jonathan Austin 1:8aa5cdb4ab67 155 DigitalOut((PinName)(matrixMap.rowStart + rowCount)).write(0);
Jonathan Austin 1:8aa5cdb4ab67 156
Jonathan Austin 1:8aa5cdb4ab67 157 PinName currentPin = (PinName)(matrixMap.columnStart + chan);
Jonathan Austin 1:8aa5cdb4ab67 158
Jonathan Austin 1:8aa5cdb4ab67 159 DigitalOut(currentPin).write(1);
Jonathan Austin 1:8aa5cdb4ab67 160
Jonathan Austin 1:8aa5cdb4ab67 161 DigitalIn(currentPin, PullNone).~DigitalIn();
Jonathan Austin 1:8aa5cdb4ab67 162
Jonathan Austin 1:8aa5cdb4ab67 163 if(this->sensePin != NULL)
Jonathan Austin 1:8aa5cdb4ab67 164 delete this->sensePin;
Jonathan Austin 1:8aa5cdb4ab67 165
Jonathan Austin 1:8aa5cdb4ab67 166 this->sensePin = new AnalogIn(currentPin);
Jonathan Austin 1:8aa5cdb4ab67 167
Jonathan Austin 1:8aa5cdb4ab67 168 analogTrigger.attach_us(this, &MicroBitLightSensor::analogReady, MICROBIT_LIGHT_SENSOR_AN_SET_TIME);
Jonathan Austin 1:8aa5cdb4ab67 169 }
Jonathan Austin 1:8aa5cdb4ab67 170
Jonathan Austin 1:8aa5cdb4ab67 171 /**
Jonathan Austin 1:8aa5cdb4ab67 172 * A destructor for MicroBitLightSensor.
Jonathan Austin 1:8aa5cdb4ab67 173 *
Jonathan Austin 1:8aa5cdb4ab67 174 * The destructor removes the listener, used by MicroBitLightSensor from the default EventModel.
Jonathan Austin 1:8aa5cdb4ab67 175 */
Jonathan Austin 1:8aa5cdb4ab67 176 MicroBitLightSensor::~MicroBitLightSensor()
Jonathan Austin 1:8aa5cdb4ab67 177 {
Jonathan Austin 1:8aa5cdb4ab67 178 if (EventModel::defaultEventBus)
Jonathan Austin 1:8aa5cdb4ab67 179 EventModel::defaultEventBus->ignore(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing);
LancasterUniversity 8:ec4465853952 180 }