Solution for Bluetooth SIG hands-on training course
Dependencies: BLE_API mbed-dev-bin nRF51822-bluetooth-mdw
Fork of microbit-dal-bluetooth-mdw_starter by
MicroBitLightSensor.cpp
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 /** 00027 * Class definition for MicroBitLightSensor. 00028 * 00029 * This is an object that interleaves light sensing with MicroBitDisplay. 00030 */ 00031 00032 #include "MicroBitConfig.h" 00033 #include "MicroBitLightSensor.h" 00034 #include "MicroBitDisplay.h" 00035 00036 /** 00037 * After the startSensing method has been called, this method will be called 00038 * MICROBIT_LIGHT_SENSOR_AN_SET_TIME after. 00039 * 00040 * It will then read from the currently selected channel using the AnalogIn 00041 * that was configured in the startSensing method. 00042 */ 00043 void MicroBitLightSensor::analogReady() 00044 { 00045 this->results[chan] = this->sensePin->read_u16(); 00046 00047 analogDisable(); 00048 00049 DigitalOut((PinName)(matrixMap.columnStart + chan)).write(1); 00050 00051 chan++; 00052 00053 chan = chan % MICROBIT_LIGHT_SENSOR_CHAN_NUM; 00054 } 00055 00056 /** 00057 * Forcibly disables the AnalogIn, otherwise it will remain in possession 00058 * of the GPIO channel it is using, meaning that the display will not be 00059 * able to use a channel (COL). 00060 * 00061 * This is required as per PAN 3, details of which can be found here: 00062 * 00063 * https://www.nordicsemi.com/eng/nordic/download_resource/24634/5/88440387 00064 */ 00065 void MicroBitLightSensor::analogDisable() 00066 { 00067 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; 00068 00069 NRF_ADC->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos) | 00070 (ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling << ADC_CONFIG_INPSEL_Pos) | 00071 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | 00072 (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | 00073 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); 00074 } 00075 00076 /** 00077 * Constructor. 00078 * 00079 * Create a representation of the light sensor. 00080 * 00081 * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates. 00082 * Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h. 00083 */ 00084 MicroBitLightSensor::MicroBitLightSensor(const MatrixMap &map) : 00085 analogTrigger(), 00086 matrixMap(map) 00087 { 00088 this->chan = 0; 00089 00090 for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++) 00091 results[i] = 0; 00092 00093 if (EventModel::defaultEventBus) 00094 EventModel::defaultEventBus->listen(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing, MESSAGE_BUS_LISTENER_IMMEDIATE); 00095 00096 this->sensePin = NULL; 00097 } 00098 00099 /** 00100 * This method returns a summed average of the three sections of the display. 00101 * 00102 * A section is defined as: 00103 * ___________________ 00104 * | 1 | | 2 | | 3 | 00105 * |___|___|___|___|___| 00106 * | | | | | | 00107 * |___|___|___|___|___| 00108 * | 2 | | 3 | | 1 | 00109 * |___|___|___|___|___| 00110 * | | | | | | 00111 * |___|___|___|___|___| 00112 * | 3 | | 1 | | 2 | 00113 * |___|___|___|___|___| 00114 * 00115 * Where each number represents a different section on the 5 x 5 matrix display. 00116 * 00117 * @return returns a value in the range 0 - 255 where 0 is dark, and 255 00118 * is very bright 00119 */ 00120 int MicroBitLightSensor::read() 00121 { 00122 int sum = 0; 00123 00124 for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++) 00125 sum += results[i]; 00126 00127 int average = sum / MICROBIT_LIGHT_SENSOR_CHAN_NUM; 00128 00129 average = min(average, MICROBIT_LIGHT_SENSOR_MAX_VALUE); 00130 00131 average = max(average, MICROBIT_LIGHT_SENSOR_MIN_VALUE); 00132 00133 int inverted = (MICROBIT_LIGHT_SENSOR_MAX_VALUE - average) + MICROBIT_LIGHT_SENSOR_MIN_VALUE; 00134 00135 int a = 0; 00136 00137 int b = 255; 00138 00139 int normalised = a + ((((inverted - MICROBIT_LIGHT_SENSOR_MIN_VALUE)) * (b - a))/ (MICROBIT_LIGHT_SENSOR_MAX_VALUE - MICROBIT_LIGHT_SENSOR_MIN_VALUE)); 00140 00141 return normalised; 00142 } 00143 00144 /** 00145 * The method that is invoked by sending MICROBIT_DISPLAY_EVT_LIGHT_SENSE 00146 * using the id MICROBIT_ID_DISPLAY. 00147 * 00148 * @note this can be manually driven by calling this member function, with 00149 * a MicroBitEvent using the CREATE_ONLY option of the MicroBitEvent 00150 * constructor. 00151 */ 00152 void MicroBitLightSensor::startSensing(MicroBitEvent) 00153 { 00154 for(int rowCount = 0; rowCount < matrixMap.rows; rowCount++) 00155 DigitalOut((PinName)(matrixMap.rowStart + rowCount)).write(0); 00156 00157 PinName currentPin = (PinName)(matrixMap.columnStart + chan); 00158 00159 DigitalOut(currentPin).write(1); 00160 00161 DigitalIn(currentPin, PullNone).~DigitalIn(); 00162 00163 if(this->sensePin != NULL) 00164 delete this->sensePin; 00165 00166 this->sensePin = new AnalogIn(currentPin); 00167 00168 analogTrigger.attach_us(this, &MicroBitLightSensor::analogReady, MICROBIT_LIGHT_SENSOR_AN_SET_TIME); 00169 } 00170 00171 /** 00172 * A destructor for MicroBitLightSensor. 00173 * 00174 * The destructor removes the listener, used by MicroBitLightSensor from the default EventModel. 00175 */ 00176 MicroBitLightSensor::~MicroBitLightSensor() 00177 { 00178 if (EventModel::defaultEventBus) 00179 EventModel::defaultEventBus->ignore(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing); 00180 }
Generated on Tue Jul 12 2022 20:39:13 by 1.7.2