89 lines
2.5 KiB
C++
89 lines
2.5 KiB
C++
// High/Low Output LDR Sensor
|
|
// For example: RCWL-0516 (needs 5v input (gnd, vin), 3.3v output level. high for 2seconds when movement detected)
|
|
#include "sensor_ldr.h"
|
|
|
|
|
|
Sensor_LDR::Sensor_LDR(int p)
|
|
{
|
|
pin=p;
|
|
}
|
|
|
|
void Sensor_LDR::init() //Things to be done during setup()
|
|
{
|
|
Serial.println("initializing LDR");
|
|
pinMode(pin, INPUT);
|
|
analogRead(pin); //first reading could be false
|
|
init_ok=true;
|
|
}
|
|
|
|
//Also called during setup()
|
|
void Sensor_LDR::setSettings(float minchange, unsigned long senddelaymax, unsigned long readdelay)
|
|
{
|
|
data.minchange=minchange;
|
|
data.senddelaymax=senddelaymax;
|
|
data.readdelay=readdelay;
|
|
}
|
|
|
|
//Called during setup
|
|
void Sensor_LDR::advertise(HomieNode& p_sensorNode)
|
|
{
|
|
sensorNode = &p_sensorNode;
|
|
sensorNode->advertise("light");
|
|
|
|
}
|
|
|
|
void Sensor_LDR::sensorloop()
|
|
{
|
|
if (init_ok) {
|
|
sensordata &d=data;
|
|
|
|
bool _changed=false;
|
|
if (millis() >= (d.lastreadtime+d.readdelay)) {
|
|
d.value = get_lux(in_ldr, out_ldr, SENSOR_LDR_ARRAYSIZE)/10.0; //read light level in lux
|
|
if (fabs(d.lastsentvalue-d.value)>=d.minchange){
|
|
_changed=true;
|
|
}
|
|
d.lastreadtime=millis();
|
|
}
|
|
|
|
if (_changed || millis() >= (d.lastsent+d.senddelaymax)) {
|
|
Serial.print("Sending LDR. reason=");
|
|
if (_changed) Serial.println("change"); else Serial.println("time");
|
|
|
|
Homie.getLogger() << "light " << ": " << d.value << endl;
|
|
sensorNode->setProperty("light").send(String(d.value));
|
|
d.lastsentvalue=d.value;
|
|
|
|
d.lastsent=millis();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Calculate lux based on rawADC reading from LDR returns value in lux/10
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//quelle: https://groups.google.com/forum/#!topic/souliss/1kMAltPB2ME[1-25]
|
|
int Sensor_LDR::get_lux(const unsigned int* _in, const unsigned int* _out, byte size)
|
|
{
|
|
// take care the value is within range
|
|
// val = constrain(val, _in[0], _in[size-1]);
|
|
unsigned int val = analogRead(pin);
|
|
#ifdef DEBUG //DEBUG++++++++++++++++
|
|
Serial.print("LDR RAW=: ");
|
|
Serial.println(val);
|
|
#endif
|
|
|
|
if (val <= _in[0]) return _out[0];
|
|
if (val >= _in[size-1]) return _out[size-1];
|
|
|
|
// search right interval
|
|
byte pos = 1; // _in[0] allready tested
|
|
while(val > _in[pos]) pos++;
|
|
|
|
// this will handle all exact "points" in the _in array
|
|
if (val == _in[pos]) return _out[pos];
|
|
|
|
// interpolate in the right segment for the rest
|
|
return map(val, _in[pos-1], _in[pos], _out[pos-1], _out[pos]);
|
|
} |