sensoresp/include/sensor_ldr.cpp

90 lines
2.6 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;
sensordata data;
}
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]);
}