sensoresp/src/main.cpp

730 lines
19 KiB
C++

//#define DEBUG
//Compile with platformio run --environment sensorespx
//Compile and upload: platformio run --environment sensorespx -t upload
//Spiffs data upload with (comment in data_dir line unter platformio section): platformio run --environment sensorespx -t uploadfs
//GPIO2 is blue led on wemos_d1
#include "Arduino.h"
#ifndef HOMIE_H
#include <Homie.h>
#define HOMIE_H
#endif
#define FW_NAME "sensoresp" //gets printed on topic/$fw/name
#define FW_VERSION "1.0.0" //gets printed on topic/$fw/version
#define STATUSNODE
#include "sensordata.h"
#ifdef SENSOR_DHT22
#include "sensor_dht22.cpp"
Sensor_DHT22 sensor_dht22(SENSOR_DHT22_PIN);
#ifndef SENSOR_DHT22_temperature_minchange
#define SENSOR_DHT22_temperature_minchange 0.2
#endif
#ifndef SENSOR_DHT22_temperature_senddelaymax
#define SENSOR_DHT22_temperature_senddelaymax 5*60*1000
#endif
#ifndef SENSOR_DHT22_temperature_readdelay
#define SENSOR_DHT22_temperature_readdelay 10000
#endif
#ifndef SENSOR_DHT22_humidity_minchange
#define SENSOR_DHT22_humidity_minchange 2.0
#endif
#ifndef SENSOR_DHT22_humidity_senddelaymax
#define SENSOR_DHT22_humidity_senddelaymax 10*60*1000
#endif
#ifndef SENSOR_DHT22_humidity_readdelay
#define SENSOR_DHT22_humidity_readdelay 10000
#endif
#endif
#ifdef SENSOR_BMP180
#include "sensor_bmp180.cpp"
Sensor_BMP180 sensor_bmp180;
#ifndef SENSOR_BMP180_temperature_minchange
#define SENSOR_BMP180_temperature_minchange 0.2
#endif
#ifndef SENSOR_BMP180_temperature_senddelaymax
#define SENSOR_BMP180_temperature_senddelaymax 5*60*1000
#endif
#ifndef SENSOR_BMP180_temperature_readdelay
#define SENSOR_BMP180_temperature_readdelay 10000
#endif
#ifndef SENSOR_BMP180_pressure_minchange
#define SENSOR_BMP180_pressure_minchange 0.5
#endif
#ifndef SENSOR_BMP180_pressure_senddelaymax
#define SENSOR_BMP180_pressure_senddelaymax 30*60*1000
#endif
#ifndef SENSOR_BMP180_pressure_readdelay
#define SENSOR_BMP180_pressure_readdelay 10000
#endif
#endif
#ifdef SENSOR_HTU21D
#include "sensor_htu21d.cpp"
Sensor_HTU21D sensor_htu21d;
#ifndef SENSOR_HTU21D_temperature_minchange
#define SENSOR_HTU21D_temperature_minchange 0.2
#endif
#ifndef SENSOR_HTU21D_temperature_senddelaymax
#define SENSOR_HTU21D_temperature_senddelaymax 300000
#endif
#ifndef SENSOR_HTU21D_temperature_readdelay
#define SENSOR_HTU21D_temperature_readdelay 10000
#endif
#ifndef SENSOR_HTU21D_humidity_minchange
#define SENSOR_HTU21D_humidity_minchange 2.0
#endif
#ifndef SENSOR_HTU21D_humidity_senddelaymax
#define SENSOR_HTU21D_humidity_senddelaymax 10*60*1000
#endif
#ifndef SENSOR_HTU21D_humidity_readdelay
#define SENSOR_HTU21D_humidity_readdelay 10000
#endif
#endif
#ifdef SENSOR_HS1101
#include "sensor_hs1101.cpp"
Sensor_HS1101 sensor_hs1101(SENSOR_HS1101_PIN);
#ifndef SENSOR_HS1101_humidity_minchange
#define SENSOR_HS1101_humidity_minchange 2.0
#endif
#ifndef SENSOR_HS1101_humidity_senddelaymax
#define SENSOR_HS1101_humidity_senddelaymax 10*60*1000
#endif
#ifndef SENSOR_HS1101_humidity_readdelay
#define SENSOR_HS1101_humidity_readdelay 10000
#endif
#endif
#ifdef SENSOR_BH1750
#include "sensor_bh1750.cpp"
Sensor_BH1750 sensor_bh1750;
#ifndef SENSOR_BH1750_light_minchange
#define SENSOR_BH1750_light_minchange 10
#endif
#ifndef SENSOR_BH1750_light_senddelaymax
#define SENSOR_BH1750_light_senddelaymax 5*60*1000
#endif
#ifndef SENSOR_BH1750_light_readdelay
#define SENSOR_BH1750_light_readdelay 1000*10
#endif
#endif
#ifdef SENSOR_ML8511
#include "sensor_ml8511.cpp"
Sensor_ML8511 sensor_ml8511(SENSOR_ML8511_PIN);
#ifndef SENSOR_ML8511_minchange
#define SENSOR_ML8511_minchange 0.2
#endif
#ifndef SENSOR_ML8511_senddelaymax
#define SENSOR_ML8511_senddelaymax 5*60*1000
#endif
#ifndef SENSOR_ML8511_readdelay
#define SENSOR_ML8511_readdelay 1000*10
#endif
#endif
#ifdef SENSOR_HCSR501
#include "sensor_hcsr501.cpp"
Sensor_HCSR501 sensor_hcsr501(SENSOR_HCSR501_PIN);
#ifndef SENSOR_HCSR501_senddelaymax
#define SENSOR_HCSR501_senddelaymax 1000*60*10
#endif
#ifndef SENSOR_HCSR501_readdelayML8511
#define SENSOR_HCSR501_readdelay 100
#endif
#endif
#ifdef SENSOR_RADAR
#include "sensor_radar.cpp"
Sensor_Radar sensor_radar(SENSOR_RADAR_PIN);
#ifndef SENSOR_RADAR_senddelaymax
#define SENSOR_RADAR_senddelaymax 1000*60*10
#endif
#ifndef SENSOR_RADAR_readdelayML8511
#define SENSOR_RADAR_readdelay 100
#endif
#endif
#ifdef SENSOR_LDR
#include "sensor_ldr.cpp"
Sensor_LDR sensor_ldr(SENSOR_LDR_PIN);
#ifndef SENSOR_LDR_minchange
#define SENSOR_LDR_minchange 10.0
#endif
#ifndef SENSOR_LDR_senddelaymax
#define SENSOR_LDR_senddelaymax 1000*60*1
#endif
#ifndef SENSOR_LDR_readdelay
#define SENSOR_LDR_readdelay 1000*2
#endif
#endif
#ifdef SENSOR_MHZ19B
#include "sensor_mhz19b.cpp"
Sensor_MHZ19B sensor_mhz19b(SENSOR_MHZ19B_SERIAL_RX,SENSOR_MHZ19B_SERIAL_TX);
#ifndef SENSOR_MHZ19B_minchange
#define SENSOR_MHZ19B_minchange 10.0
#endif
#ifndef SENSOR_MHZ19B_senddelaymax
#define SENSOR_MHZ19B_senddelaymax 1000*60*10
#endif
#ifndef SENSOR_MHZ19B_readdelay
#define SENSOR_MHZ19B_readdelay 1000*10
#endif
#endif
#ifdef SENSOR_SDS018
#include "sensor_sds018.cpp"
Sensor_SDS018 sensor_sds018(SENSOR_SDS018_SERIAL_RX,SENSOR_SDS018_SERIAL_TX);
#ifndef SENSOR_SDS018_PM10_minchange
#define SENSOR_SDS018_PM10_minchange 10.0
#endif
#ifndef SENSOR_SDS018_PM10_senddelaymax
#define SENSOR_SDS018_PM10_senddelaymax 1000*60*5
#endif
#ifndef SENSOR_SDS018_PM10_readdelay
#define SENSOR_SDS018_PM10_readdelay 1000*10
#endif
#ifndef SENSOR_SDS018_PM25_minchange
#define SENSOR_SDS018_PM25_minchange 10.0
#endif
#ifndef SENSOR_SDS018_PM25_senddelaymax
#define SENSOR_SDS018_PM25_senddelaymax 1000*60*5
#endif
#ifndef SENSOR_SDS018_PM25_readdelay
#define SENSOR_SDS018_PM25_readdelay 1000*10
#endif
#endif
#ifdef SENSOR_TCS34725
#include "sensor_tcs34725.cpp"
Sensor_TCS34725 sensor_tcs34725;
#ifndef SENSOR_TCS34725_LUX_minchange
#define SENSOR_TCS34725_LUX_minchange 500
#endif
#ifndef SENSOR_TCS34725_LUX_senddelaymax
#define SENSOR_TCS34725_LUX_senddelaymax 1000*60*5
#endif
#ifndef SENSOR_TCS34725_LUX_readdelay
#define SENSOR_TCS34725_LUX_readdelay 1000*10
#endif
#ifndef SENSOR_TCS34725_COLORTEMP_minchange
#define SENSOR_TCS34725_COLORTEMP_minchange 100
#endif
#ifndef SENSOR_TCS34725_COLORTEMP_senddelaymax
#define SENSOR_TCS34725_COLORTEMP_senddelaymax 1000*60*5
#endif
#ifndef SENSOR_TCS34725_COLORTEMP_readdelay
#define SENSOR_TCS34725_COLORTEMP_readdelay 1000*10
#endif
#endif
#ifdef SENSOR_VL53L1X
#include "sensor_vl53l1x.cpp"
Sensor_VL53L1X sensor_vl53l1x;
#ifndef SENSOR_VL53L1X_minchange
#define SENSOR_VL53L1X_minchange 100
#endif
#ifndef SENSOR_VL53L1X_senddelaymax
#define SENSOR_VL53L1X_senddelaymax 1000*30
#endif
#ifndef SENSOR_VL53L1X_readdelay
#define SENSOR_VL53L1X_readdelay 1000
#endif
#endif
#ifdef SENSOR_ANEMOMETER
//uses ATS177 Latched hall sensor for rotation sensing
sensordata dataAnemometer;
unsigned long anemometer_lasttimereset=0;
uint16_t anemometer_pulsecounter=0; //counted pulses since last reset
#define ANEMOMETER_DEBOUNCETIME 15 //15ms between pulses is approx 85m/s windspeed
unsigned long anemometer_lastpulse_fordebounce=0;
float value_anemometer=0; // [m/s]
void ICACHE_RAM_ATTR interrupt_anemometer();
void updateAnemometer();
#endif
#ifdef SENSOR_RAINGAUGE
//uses ATS177 Latched Hall Sensor for rauge flip sensing
sensordata dataRaingauge;
unsigned long raingauge_lasttimereset=0;
uint16_t raingauge_pulsecounter=0; //counted pulses since last reset
bool raingauge_idleflag=true;
#define RAINGAUGE_DEBOUNCETIME 1000
unsigned long raingauge_lastpulse_fordebounce=0;
float value_raingauge=0; // [mm] or [L/m^2]
#define RAINGAUGE_FLIPAMOUNT 0.38888 //how much mm rain (L/m^2) per gauge flip. mL (rain to flip) / A (opening area)
//was 0.69292 until 201702
/* Calibration:
* Test1: 1000mL -> 259 Flips
* Test2: 1000mL -> 256 in ca 10min
* -> 3,9mL per Flip, opening diameter =113mm -> A=0,010028749
*/
void ICACHE_RAM_ATTR interrupt_raingauge();
void updateRaingauge();
#endif
// data/homie/config.json hochladen mit platformio run --target uploadfs
// config contains homie device name, mqtt ip and wifi credentials
HomieNode sensorNode("sensors", "Sensors","sensors"); //id, name, type
char tempstring[16]; //for dtostrf
void loopHandler();
void checkESPStatus();
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Booting");
delay(1000); //wait for sensors to get powered
#ifdef SENSOR_DHT22
sensor_dht22.init();
sensor_dht22.setSettings_Temperature(SENSOR_DHT22_temperature_minchange,SENSOR_DHT22_temperature_senddelaymax,SENSOR_DHT22_temperature_readdelay);
sensor_dht22.setSettings_Humidity(SENSOR_DHT22_humidity_minchange,SENSOR_DHT22_humidity_senddelaymax,SENSOR_DHT22_humidity_readdelay);
#endif
#ifdef SENSOR_BMP180
sensor_bmp180.init();
sensor_bmp180.setSettings_Temperature(SENSOR_BMP180_temperature_minchange,SENSOR_BMP180_temperature_senddelaymax,SENSOR_BMP180_temperature_readdelay);
sensor_bmp180.setSettings_Pressure(SENSOR_BMP180_temperature_minchange,SENSOR_BMP180_temperature_senddelaymax,SENSOR_BMP180_temperature_readdelay);
#endif
#ifdef SENSOR_HTU21D
sensor_htu21d.init();
sensor_htu21d.setSettings_Temperature(SENSOR_HTU21D_temperature_minchange,SENSOR_HTU21D_temperature_senddelaymax,SENSOR_HTU21D_temperature_readdelay);
sensor_htu21d.setSettings_Humidity(SENSOR_HTU21D_humidity_minchange,SENSOR_HTU21D_humidity_senddelaymax,SENSOR_HTU21D_humidity_readdelay);
#endif
#ifdef SENSOR_HS1101
sensor_hs1101.init();
sensor_hs1101.setSettings(SENSOR_HS1101_humidity_minchange,SENSOR_HS1101_humidity_senddelaymax,SENSOR_HS1101_humidity_readdelay);
#endif
#ifdef SENSOR_BH1750
sensor_bh1750.init();
sensor_bh1750.setSettings(SENSOR_BH1750_light_minchange,SENSOR_BH1750_light_senddelaymax,SENSOR_BH1750_light_readdelay);
#endif
#ifdef SENSOR_ML8511
sensor_ml8511.init();
sensor_ml8511.setSettings(SENSOR_ML8511_minchange,SENSOR_ML8511_senddelaymax,SENSOR_ML8511_readdelay);
#endif
#ifdef SENSOR_HCSR501
sensor_hcsr501.init();
sensor_hcsr501.setSettings(SENSOR_HCSR501_senddelaymax,SENSOR_HCSR501_readdelay);
#endif
#ifdef SENSOR_RADAR
sensor_radar.init();
sensor_radar.setSettings(SENSOR_RADAR_senddelaymax,SENSOR_RADAR_readdelay);
#endif
#ifdef SENSOR_LDR
sensor_ldr.init();
sensor_ldr.setSettings(SENSOR_LDR_minchange,SENSOR_LDR_senddelaymax,SENSOR_LDR_readdelay);
#endif
#ifdef SENSOR_MHZ19B
sensor_mhz19b.init();
sensor_mhz19b.setSettings(SENSOR_MHZ19B_minchange,SENSOR_MHZ19B_senddelaymax,SENSOR_MHZ19B_readdelay);
#endif
#ifdef SENSOR_SDS018
sensor_sds018.init();
sensor_sds018.setSettings_pm10(SENSOR_SDS018_PM10_minchange,SENSOR_SDS018_PM10_senddelaymax,SENSOR_SDS018_PM10_readdelay);
sensor_sds018.setSettings_pm25(SENSOR_SDS018_PM25_minchange,SENSOR_SDS018_PM25_senddelaymax,SENSOR_SDS018_PM25_readdelay);
#endif
#ifdef SENSOR_TCS34725
sensor_tcs34725.init();
sensor_tcs34725.setSettings_Lux(SENSOR_TCS34725_LUX_minchange,SENSOR_TCS34725_LUX_senddelaymax,SENSOR_TCS34725_LUX_readdelay);
sensor_tcs34725.setSettings_Colortemp(SENSOR_TCS34725_COLORTEMP_minchange,SENSOR_TCS34725_COLORTEMP_senddelaymax,SENSOR_TCS34725_COLORTEMP_readdelay);
#endif
#ifdef SENSOR_VL53L1X
sensor_vl53l1x.init();
sensor_vl53l1x.setSettings(SENSOR_VL53L1X_minchange,SENSOR_VL53L1X_senddelaymax,SENSOR_VL53L1X_readdelay);
#endif
#ifdef SENSOR_ANEMOMETER
pinMode(ANEMOMETERPIN,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ANEMOMETERPIN),interrupt_anemometer,CHANGE); //anemometer interrupt
#ifdef dataAnemometer_minchange
dataAnemometer.minchange=dataAnemometer_minchange;
#endif
#ifdef dataAnemometer_readdelay
dataAnemometer.readdelay=dataAnemometer_readdelay;
#endif
#ifdef dataAnemometer_senddelaymax
dataAnemometer.senddelaymax=dataAnemometer_senddelaymax;
#endif
#endif
#ifdef SENSOR_RAINGAUGE
pinMode(RAINGAUGEPIN,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(RAINGAUGEPIN),interrupt_raingauge,CHANGE); //anemometer interrupt
#ifdef dataRaingauge_senddelaymax
dataRaingauge.senddelaymax=dataRaingauge_senddelaymax;
#endif
#ifdef dataRaingauge_readdelay
dataRaingauge.readdelay=dataRaingauge_readdelay;
#endif
#endif
// ##### Advertise topics below here #####
//Homie_setFirmware(FW_NAME, FW_VERSION);
//Homie_setBrand(FW_NAME);
Homie_setFirmware(FW_NAME, FW_VERSION);
Homie.setLoopFunction(loopHandler);
#ifdef STATUSNODE
//to return some stuff about status, errors etc.
Serial.println("Using status node");
sensorNode.advertise("status");
#endif
#ifdef SENSOR_DHT22
sensor_dht22.advertise(sensorNode);
#endif
#ifdef SENSOR_BMP180
sensor_bmp180.advertise(sensorNode);
#endif
#ifdef SENSOR_HTU21D
sensor_htu21d.advertise(sensorNode);
#endif
#ifdef SENSOR_HS1101
sensor_hs1101.advertise(sensorNode);
#endif
#ifdef SENSOR_BH1750
sensor_bh1750.advertise(sensorNode);
#endif
#ifdef SENSOR_ML8511
sensor_ml8511.advertise(sensorNode);
#endif
#ifdef SENSOR_HCSR501
sensor_hcsr501.advertise(sensorNode);
#endif
#ifdef SENSOR_RADAR
sensor_radar.advertise(sensorNode);
#endif
#ifdef SENSOR_LDR
sensor_ldr.advertise(sensorNode);
#endif
#ifdef SENSOR_MHZ19B
sensor_mhz19b.advertise(sensorNode);
#endif
#ifdef SENSOR_SDS018
sensor_sds018.advertise(sensorNode);
#endif
#ifdef SENSOR_TCS34725
sensor_tcs34725.advertise(sensorNode);
#endif
#ifdef SENSOR_VL53L1X
sensor_vl53l1x.advertise(sensorNode);
#endif
#ifdef SENSOR_ANEMOMETER
sensorNode.advertise("windspeed");
#endif
#ifdef SENSOR_RAINGAUGE
sensorNode.advertise("rain");
#endif
Serial.println("connecting..");
Homie.setup();
Serial.println("");
Serial.println("connected"); //wird nicht ausgegeben. keine ahnung warum.
}
void loop() {
Homie.loop();
}
#ifdef SENSOR_ANEMOMETER
void loop_anemometer()
{
sensordata &d=dataAnemometer;
bool _changed=false;
if (millis() >= (d.lastreadtime+d.readdelay)) {
uint16_t _anepulsesPerMinute=anemometer_pulsecounter/((millis()-anemometer_lasttimereset)/60000.0);
value_anemometer = _anepulsesPerMinute*ANEMOMETER_PPMtoMPS;
if (abs((int)d.lastsentvalue-value_anemometer)>=d.minchange){ //int abs
_changed=true;
}
d.lastreadtime=millis();
}
if (_changed || millis() >= (d.lastsent+d.senddelaymax)) {
Serial.print("Sending windspeed. reason=");
if (_changed) Serial.println("change"); else Serial.println("time");
checkESPStatus();
Homie.getLogger() << "windspeed tcs " << ": " << value_anemometer << endl;
sensorNode.setProperty("windspeed").send(String(value_anemometer));
//reset when sent. makes it more accurate but keeps fast response
anemometer_pulsecounter=0; //reset counter
anemometer_lasttimereset=millis();
d.lastreadtime=millis(); //also set lastread time to avoid having 1 count with a low time = high windspeed
d.lastsentvalue=value_anemometer;
d.lastsent=millis();
}
}
#endif
#ifdef SENSOR_RAINGAUGE
void loop_raingauge()
{
sensordata &d=dataRaingauge;
bool _changed=false;
if (millis() >= (d.lastreadtime+d.readdelay)) {
if (millis()-raingauge_lasttimereset > d.senddelaymax) {
raingauge_idleflag=true; //raingauge didn't flip for a long time
}
if (raingauge_pulsecounter>0){ //if rg flipped
if (raingauge_idleflag) { //last flip is before reset time
value_raingauge=raingauge_pulsecounter*RAINGAUGE_FLIPAMOUNT; //set to fixed amount if flip was exactly at that time
raingauge_idleflag=false;
}else{
value_raingauge=3600000/(millis()-raingauge_lasttimereset)/raingauge_pulsecounter*RAINGAUGE_FLIPAMOUNT;
raingauge_idleflag=false;
}
_changed=true;
}
d.lastreadtime=millis();
}
if (_changed || millis() >= (d.lastsent+d.senddelaymax)) {
Serial.print("Sending rain. reason=");
if (_changed) Serial.println("change"); else Serial.println("time");
checkESPStatus();
if (!_changed) { //no flip since a long time
value_raingauge=0; //set to no rain
}
Homie.getLogger() << "rain " << ": " << value_raingauge << endl;
sensorNode.setProperty("rain").send(String(value_raingauge));
//reset when sent. makes it more accurate but keeps fast response
raingauge_pulsecounter=0; //reset counter
raingauge_lasttimereset=millis();
d.lastsentvalue=value_raingauge;
d.lastsent=millis();
}
}
#endif
void loopHandler() {
checkESPStatus();
#ifdef SENSOR_DHT22
sensor_dht22.sensorloop();
#endif
#ifdef SENSOR_BMP180
sensor_bmp180.sensorloop();
#endif
#ifdef SENSOR_HTU21D
sensor_htu21d.sensorloop();
#endif
#ifdef SENSOR_HS1101
sensor_hs1101.sensorloop();
#endif
#ifdef SENSOR_BH1750
sensor_bh1750.sensorloop();
#endif
#ifdef SENSOR_ML8511
sensor_ml8511.sensorloop();
#endif
#ifdef SENSOR_HCSR501
sensor_hcsr501.sensorloop();
#endif
#ifdef SENSOR_RADAR
sensor_radar.sensorloop();
#endif
#ifdef SENSOR_LDR
sensor_ldr.sensorloop();
#endif
#ifdef SENSOR_MHZ19B
sensor_mhz19b.sensorloop();
#endif
#ifdef SENSOR_SDS018
sensor_sds018.sensorloop();
#endif
#ifdef SENSOR_TCS34725
sensor_tcs34725.sensorloop();
#endif
#ifdef SENSOR_VL53L1X
sensor_vl53l1x.sensorloop();
#endif
#ifdef SENSOR_ANEMOMETER
loop_anemometer();
#endif
#ifdef SENSOR_RAINGAUGE
loop_raingauge();
#endif
}
void checkESPStatus()
{
if (WiFi.status() != WL_CONNECTED) //restart if wifi signal loss
{
ESP.reset();
}
}
#ifdef SENSOR_ANEMOMETER
void ICACHE_RAM_ATTR interrupt_anemometer()
{
if (millis() - anemometer_lastpulse_fordebounce >= ANEMOMETER_DEBOUNCETIME) { //ignore if pulse came too fast
anemometer_pulsecounter++;
anemometer_lastpulse_fordebounce=millis();
}
}
#endif
#ifdef SENSOR_RAINGAUGE
void ICACHE_RAM_ATTR interrupt_raingauge()
{
if (millis() - raingauge_lastpulse_fordebounce >= RAINGAUGE_DEBOUNCETIME) { //ignore if pulse came too fast
raingauge_pulsecounter++;
raingauge_lastpulse_fordebounce=millis();
}
}
#endif
/*##################################
* ######## HELPER FUNCTIONS ########
*/
//quelle: https://groups.google.com/forum/#!topic/souliss/1kMAltPB2ME[1-25]
int get_mapped(const unsigned int* _in, const unsigned int* _out, byte size,int val) //map with constrain
{
// take care the value is within range
// val = constrain(val, _in[0], _in[size-1]);
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]);
}
//The Arduino Map function but for floats
//From: http://forum.arduino.cc/index.php?topic=3922.0
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}