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
- Committer:
- f3d
- Date:
- 2020-08-27
- Revision:
- 1:ab9f0e572c98
File content as of revision 1:ab9f0e572c98:
#ifndef __UVSENSOR_H #define __UVSENSOR_H #include <mbed.h> #include <BLE.h> AnalogIn UVSignalIn(P0_28); class UVService { public: const static uint16_t UV_SERVICE_UUID = 0xA012; const static uint16_t UV_CHARACTERISTIC_UUID = 0xA013; UVService(BLE &_ble, int16_t initialUVValue) : ble(_ble), UVValue(UV_CHARACTERISTIC_UUID, &initialUVValue) { GattCharacteristic *charTable[] = {&UVValue}; GattService uvservice(UV_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.addService(uvservice); } GattAttribute::Handle_t getValueHandle() const { return UVValue.getValueHandle(); } void updateUVValue(uint16_t newValue) { ble.gattServer().write(UVValue.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t)); } void poll() { uint16_t ADCIn = UVSignalIn.read_u16(); // Need to scale this to mW/cm^2 // To convert to a voltage : * 3.6/4095 // To convert voltage to mW/cm^2 see page 8 of datasheet for ML8511 sensor // This graph is for 3.0V, but the supply in this example is 3.3V. // I'm ASSUMING that the device output is not a function of voltage supply (within reason) // From Graph : UV power / area is roughly given by: // Power = (Voltage - 1) * 7; // Need to avoid unsigned overflow // An input of 1V should give an ADC Value of (1/3.6)*4095 = 1137.5 (1138) if (ADCIn >= 1137 ) ADCIn = ADCIn - 1137; else ADCIn = 0; ADCIn = ADCIn / 163; // 4095 / (7*3.6) = 163 updateUVValue(ADCIn); } private: BLE &ble; ReadOnlyGattCharacteristic<int16_t> UVValue; }; #endif