This project can be used to measure UV light levels. It uses an ML8511 UV sensors and outputs its value over BLE in units of mW/cm^2
UVSensor.h@1:ab9f0e572c98, 2020-08-27 (annotated)
- Committer:
- f3d
- Date:
- Thu Aug 27 12:42:55 2020 +0000
- Revision:
- 1:ab9f0e572c98
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
f3d | 1:ab9f0e572c98 | 1 | #ifndef __UVSENSOR_H |
f3d | 1:ab9f0e572c98 | 2 | #define __UVSENSOR_H |
f3d | 1:ab9f0e572c98 | 3 | #include <mbed.h> |
f3d | 1:ab9f0e572c98 | 4 | #include <BLE.h> |
f3d | 1:ab9f0e572c98 | 5 | AnalogIn UVSignalIn(P0_28); |
f3d | 1:ab9f0e572c98 | 6 | |
f3d | 1:ab9f0e572c98 | 7 | class UVService { |
f3d | 1:ab9f0e572c98 | 8 | public: |
f3d | 1:ab9f0e572c98 | 9 | const static uint16_t UV_SERVICE_UUID = 0xA012; |
f3d | 1:ab9f0e572c98 | 10 | const static uint16_t UV_CHARACTERISTIC_UUID = 0xA013; |
f3d | 1:ab9f0e572c98 | 11 | |
f3d | 1:ab9f0e572c98 | 12 | UVService(BLE &_ble, int16_t initialUVValue) : |
f3d | 1:ab9f0e572c98 | 13 | ble(_ble), UVValue(UV_CHARACTERISTIC_UUID, &initialUVValue) |
f3d | 1:ab9f0e572c98 | 14 | { |
f3d | 1:ab9f0e572c98 | 15 | GattCharacteristic *charTable[] = {&UVValue}; |
f3d | 1:ab9f0e572c98 | 16 | GattService uvservice(UV_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); |
f3d | 1:ab9f0e572c98 | 17 | ble.addService(uvservice); |
f3d | 1:ab9f0e572c98 | 18 | } |
f3d | 1:ab9f0e572c98 | 19 | |
f3d | 1:ab9f0e572c98 | 20 | GattAttribute::Handle_t getValueHandle() const { |
f3d | 1:ab9f0e572c98 | 21 | return UVValue.getValueHandle(); |
f3d | 1:ab9f0e572c98 | 22 | } |
f3d | 1:ab9f0e572c98 | 23 | void updateUVValue(uint16_t newValue) { |
f3d | 1:ab9f0e572c98 | 24 | ble.gattServer().write(UVValue.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t)); |
f3d | 1:ab9f0e572c98 | 25 | } |
f3d | 1:ab9f0e572c98 | 26 | |
f3d | 1:ab9f0e572c98 | 27 | void poll() |
f3d | 1:ab9f0e572c98 | 28 | { |
f3d | 1:ab9f0e572c98 | 29 | uint16_t ADCIn = UVSignalIn.read_u16(); |
f3d | 1:ab9f0e572c98 | 30 | // Need to scale this to mW/cm^2 |
f3d | 1:ab9f0e572c98 | 31 | // To convert to a voltage : * 3.6/4095 |
f3d | 1:ab9f0e572c98 | 32 | // To convert voltage to mW/cm^2 see page 8 of datasheet for ML8511 sensor |
f3d | 1:ab9f0e572c98 | 33 | // This graph is for 3.0V, but the supply in this example is 3.3V. |
f3d | 1:ab9f0e572c98 | 34 | // I'm ASSUMING that the device output is not a function of voltage supply (within reason) |
f3d | 1:ab9f0e572c98 | 35 | // From Graph : UV power / area is roughly given by: |
f3d | 1:ab9f0e572c98 | 36 | // Power = (Voltage - 1) * 7; |
f3d | 1:ab9f0e572c98 | 37 | // Need to avoid unsigned overflow |
f3d | 1:ab9f0e572c98 | 38 | // An input of 1V should give an ADC Value of (1/3.6)*4095 = 1137.5 (1138) |
f3d | 1:ab9f0e572c98 | 39 | if (ADCIn >= 1137 ) |
f3d | 1:ab9f0e572c98 | 40 | ADCIn = ADCIn - 1137; |
f3d | 1:ab9f0e572c98 | 41 | else |
f3d | 1:ab9f0e572c98 | 42 | ADCIn = 0; |
f3d | 1:ab9f0e572c98 | 43 | ADCIn = ADCIn / 163; // 4095 / (7*3.6) = 163 |
f3d | 1:ab9f0e572c98 | 44 | updateUVValue(ADCIn); |
f3d | 1:ab9f0e572c98 | 45 | } |
f3d | 1:ab9f0e572c98 | 46 | private: |
f3d | 1:ab9f0e572c98 | 47 | BLE &ble; |
f3d | 1:ab9f0e572c98 | 48 | ReadOnlyGattCharacteristic<int16_t> UVValue; |
f3d | 1:ab9f0e572c98 | 49 | |
f3d | 1:ab9f0e572c98 | 50 | }; |
f3d | 1:ab9f0e572c98 | 51 | #endif |