2020-02-17 11:22:11 -05:00
|
|
|
//
|
|
|
|
// FILE: ML8511.cpp
|
2023-02-18 14:42:39 -05:00
|
|
|
// AUTHOR: Rob Tillaart
|
|
|
|
// VERSION: 0.1.10
|
|
|
|
// DATE: 2020-02-03
|
2020-02-17 11:22:11 -05:00
|
|
|
// PURPOSE: ML8511 - UV sensor - library for Arduino
|
2023-02-18 14:42:39 -05:00
|
|
|
// URL: https://github.com/RobTillaart/ML8511
|
2021-04-25 13:56:44 -04:00
|
|
|
|
2020-02-17 11:22:11 -05:00
|
|
|
|
|
|
|
#include "ML8511.h"
|
|
|
|
|
2021-04-25 13:56:44 -04:00
|
|
|
|
2020-02-17 11:22:11 -05:00
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
//
|
2022-11-17 14:12:05 -05:00
|
|
|
// PUBLIC
|
2020-02-17 11:22:11 -05:00
|
|
|
//
|
|
|
|
ML8511::ML8511(uint8_t analogPin, uint8_t enablePin)
|
|
|
|
{
|
2021-06-20 03:13:49 -04:00
|
|
|
_analogPin = analogPin;
|
|
|
|
_enablePin = enablePin;
|
2020-11-27 05:20:37 -05:00
|
|
|
if (enablePin != 0xFF)
|
|
|
|
{
|
|
|
|
pinMode(_enablePin, OUTPUT);
|
|
|
|
digitalWrite(_enablePin, LOW);
|
|
|
|
_enabled = false;
|
|
|
|
enable();
|
|
|
|
}
|
2021-12-21 14:51:35 -05:00
|
|
|
else
|
2020-11-27 05:20:37 -05:00
|
|
|
{
|
|
|
|
_enabled = true;
|
|
|
|
}
|
2021-06-20 03:13:49 -04:00
|
|
|
reset();
|
2020-02-17 11:22:11 -05:00
|
|
|
};
|
|
|
|
|
2020-11-27 05:20:37 -05:00
|
|
|
|
2021-06-20 03:13:49 -04:00
|
|
|
void ML8511::reset()
|
|
|
|
{
|
|
|
|
_voltsPerStep = 5.0/1023;
|
2022-11-17 14:12:05 -05:00
|
|
|
_DUVfactor = 1.61; // https://github.com/RobTillaart/ML8511/issues/4
|
2021-06-20 03:13:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-17 11:22:11 -05:00
|
|
|
float ML8511::getUV(uint8_t energyMode)
|
|
|
|
{
|
2020-11-27 05:20:37 -05:00
|
|
|
if (!_enabled)
|
|
|
|
{
|
|
|
|
enable();
|
2022-11-17 14:12:05 -05:00
|
|
|
// datasheet page 5 states wait for max 1 millisecond
|
2020-11-27 05:20:37 -05:00
|
|
|
uint32_t start = micros();
|
|
|
|
while (micros() - start < 1000) yield();
|
|
|
|
}
|
2021-11-09 14:05:19 -05:00
|
|
|
// read the sensor
|
2020-11-27 05:20:37 -05:00
|
|
|
float voltage = analogRead(_analogPin) * _voltsPerStep;
|
2021-11-09 14:05:19 -05:00
|
|
|
// go to low power mode?
|
2020-11-27 05:20:37 -05:00
|
|
|
if (energyMode == LOW)
|
|
|
|
{
|
|
|
|
disable();
|
|
|
|
}
|
2020-02-17 11:22:11 -05:00
|
|
|
|
2021-11-09 14:05:19 -05:00
|
|
|
return voltage2mW(voltage);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// to be used by external ADC
|
|
|
|
float ML8511::voltage2mW(float voltage)
|
|
|
|
{
|
2022-11-17 14:12:05 -05:00
|
|
|
// see datasheet - page 4
|
|
|
|
// mW/cm2 @ 365 nm
|
|
|
|
// @ 25 Celsius
|
|
|
|
// formula estimated on graph
|
2021-12-21 14:51:35 -05:00
|
|
|
if (voltage <= 1.0)
|
2020-11-27 05:20:37 -05:00
|
|
|
{
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
voltage -= 1.0; // subtract for zero point.
|
|
|
|
float mWcm2 = voltage * (15.0 / 1.8);
|
|
|
|
return mWcm2;
|
2020-02-17 11:22:11 -05:00
|
|
|
}
|
|
|
|
|
2021-05-28 07:39:01 -04:00
|
|
|
|
2022-11-17 14:12:05 -05:00
|
|
|
// experimental estimate DUV index ( ==> USE WITH CARE !!)
|
|
|
|
// use setDUVfactor(float w) to calibrate
|
2021-06-20 03:13:49 -04:00
|
|
|
//
|
2022-11-17 14:12:05 -05:00
|
|
|
// input is power in mW per cm2
|
2020-11-27 05:20:37 -05:00
|
|
|
float ML8511::estimateDUVindex(float mWcm2)
|
|
|
|
{
|
2022-11-17 14:12:05 -05:00
|
|
|
// rewrite in 0.1.6
|
|
|
|
// https://github.com/RobTillaart/ML8511/issues/4
|
2021-06-20 03:13:49 -04:00
|
|
|
return mWcm2 * _DUVfactor;
|
|
|
|
};
|
2020-11-27 05:20:37 -05:00
|
|
|
|
2021-06-20 03:13:49 -04:00
|
|
|
|
2021-11-09 14:05:19 -05:00
|
|
|
bool ML8511::setDUVfactor(float factor)
|
2021-06-20 03:13:49 -04:00
|
|
|
{
|
2022-11-17 14:12:05 -05:00
|
|
|
if (factor < 0.01) return false; // enforce positive values
|
2021-12-21 14:51:35 -05:00
|
|
|
_DUVfactor = factor;
|
2021-06-20 03:13:49 -04:00
|
|
|
return true;
|
2020-11-27 05:20:37 -05:00
|
|
|
};
|
|
|
|
|
2021-05-28 07:39:01 -04:00
|
|
|
|
2022-11-17 14:12:05 -05:00
|
|
|
float ML8511::getDUVfactor()
|
|
|
|
{
|
|
|
|
return _DUVfactor;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-02-17 11:22:11 -05:00
|
|
|
void ML8511::setVoltsPerStep(float voltage, uint32_t steps)
|
|
|
|
{
|
2020-11-27 05:20:37 -05:00
|
|
|
if (steps == 0) return;
|
|
|
|
if (voltage > 0.0) _voltsPerStep = voltage / steps;
|
2020-02-17 11:22:11 -05:00
|
|
|
}
|
|
|
|
|
2020-11-27 05:20:37 -05:00
|
|
|
|
2022-11-17 14:12:05 -05:00
|
|
|
float ML8511::getVoltsPerStep()
|
|
|
|
{
|
|
|
|
return _voltsPerStep;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-17 11:22:11 -05:00
|
|
|
void ML8511::enable()
|
|
|
|
{
|
2021-01-29 06:31:58 -05:00
|
|
|
if (_enablePin != 0xFF) digitalWrite(_enablePin, HIGH);
|
2020-11-27 05:20:37 -05:00
|
|
|
_enabled = true;
|
2020-02-17 11:22:11 -05:00
|
|
|
};
|
|
|
|
|
2020-11-27 05:20:37 -05:00
|
|
|
|
2020-02-17 11:22:11 -05:00
|
|
|
void ML8511::disable()
|
|
|
|
{
|
2021-01-29 06:31:58 -05:00
|
|
|
if (_enablePin != 0xFF) digitalWrite(_enablePin, LOW);
|
2020-11-27 05:20:37 -05:00
|
|
|
_enabled = false;
|
2020-02-17 11:22:11 -05:00
|
|
|
};
|
|
|
|
|
2021-05-28 07:39:01 -04:00
|
|
|
|
2022-11-17 14:12:05 -05:00
|
|
|
bool ML8511::isEnabled()
|
|
|
|
{
|
|
|
|
return _enabled;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// -- END OF FILE --
|
2021-12-21 14:51:35 -05:00
|
|
|
|