diff --git a/src/barometer.c b/src/barometer.c
--- a/src/barometer.c
+++ /dev/null
@@ -1,1891 +0,0 @@
-/**
- * collectd - src/barometer.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; only version 2.1 of the License is
- * applicable.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Tomas Menzl
- **/
-
-#include "collectd.h"
-#include "common.h"
-#include "utils_cache.h"
-#include "plugin.h"
-
-#include <stdint.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <linux/i2c-dev.h>
-#include <math.h>
-
-/* ------------ MPL115 defines ------------ */
-/* I2C address of the MPL115 sensor */
-#define MPL115_I2C_ADDRESS 0x60
-
-/* register addresses */
-#define MPL115_ADDR_CONV 0x00
-#define MPL115_ADDR_COEFFS 0x04
-
-/* register sizes */
-#define MPL115_NUM_CONV 4
-#define MPL115_NUM_COEFFS 12
-
-/* commands / addresses */
-#define MPL115_CMD_CONVERT_PRESS 0x10
-#define MPL115_CMD_CONVERT_TEMP 0x11
-#define MPL115_CMD_CONVERT_BOTH 0x12
-
-#define MPL115_CONVERSION_RETRIES 5
-
-
-/* ------------ MPL3115 defines ------------ */
-/* MPL3115 I2C address */
-#define MPL3115_I2C_ADDRESS 0x60
-
-/* register addresses (only the interesting ones) */
-#define MPL3115_REG_STATUS 0x00
-#define MPL3115_REG_OUT_P_MSB 0x01
-#define MPL3115_REG_OUT_P_CSB 0x02
-#define MPL3115_REG_OUT_P_LSB 0x03
-#define MPL3115_REG_OUT_T_MSB 0x04
-#define MPL3115_REG_OUT_T_LSB 0x05
-#define MPL3115_REG_DR_STATUS 0x06
-#define MPL3115_REG_WHO_AM_I 0x0C
-#define MPL3115_REG_SYSMOD 0x11
-#define MPL3115_REG_PT_DATA_CFG 0x13
-#define MPL3115_REG_BAR_IN_MSB 0x14
-#define MPL3115_REG_BAR_IN_LSB 0x15
-#define MPL3115_REG_CTRL_REG1 0x26
-#define MPL3115_REG_CTRL_REG2 0x27
-#define MPL3115_REG_CTRL_REG3 0x28
-#define MPL3115_REG_CTRL_REG4 0x29
-#define MPL3115_REG_CTRL_REG5 0x2A
-#define MPL3115_REG_OFF_P 0x2B
-#define MPL3115_REG_OFF_T 0x2C
-#define MPL3115_REG_OFF_H 0x2D
-
-/* Register values, masks */
-#define MPL3115_WHO_AM_I_RESP 0xC4
-
-#define MPL3115_PT_DATA_DREM 0x04
-#define MPL3115_PT_DATA_PDEF 0x02
-#define MPL3115_PT_DATA_TDEF 0x01
-
-#define MPL3115_DR_STATUS_TDR 0x02
-#define MPL3115_DR_STATUS_PDR 0x04
-#define MPL3115_DR_STATUS_PTDR 0x08
-#define MPL3115_DR_STATUS_DR (MPL3115_DR_STATUS_TDR | MPL3115_DR_STATUS_PDR | MPL3115_DR_STATUS_PTDR)
-
-#define MPL3115_DR_STATUS_TOW 0x20
-#define MPL3115_DR_STATUS_POW 0x40
-#define MPL3115_DR_STATUS_PTOW 0x80
-
-#define MPL3115_CTRL_REG1_ALT 0x80
-#define MPL3115_CTRL_REG1_RAW 0x40
-#define MPL3115_CTRL_REG1_OST_MASK 0x38
-#define MPL3115_CTRL_REG1_OST_1 0x00
-#define MPL3115_CTRL_REG1_OST_2 0x08
-#define MPL3115_CTRL_REG1_OST_4 0x10
-#define MPL3115_CTRL_REG1_OST_8 0x18
-#define MPL3115_CTRL_REG1_OST_16 0x20
-#define MPL3115_CTRL_REG1_OST_32 0x28
-#define MPL3115_CTRL_REG1_OST_64 0x30
-#define MPL3115_CTRL_REG1_OST_128 0x38
-#define MPL3115_CTRL_REG1_RST 0x04
-#define MPL3115_CTRL_REG1_OST 0x02
-#define MPL3115_CTRL_REG1_SBYB 0x01
-#define MPL3115_CTRL_REG1_SBYB_MASK 0xFE
-
-#define MPL3115_NUM_CONV_VALS 5
-
-
-/* ------------ BMP085 defines ------------ */
-/* I2C address of the BMP085 sensor */
-#define BMP085_I2C_ADDRESS 0x77
-
-/* register addresses */
-#define BMP085_ADDR_ID_REG 0xD0
-#define BMP085_ADDR_VERSION 0xD1
-
-#define BMP085_ADDR_CONV 0xF6
-
-#define BMP085_ADDR_CTRL_REG 0xF4
-#define BMP085_ADDR_COEFFS 0xAA
-
-/* register sizes */
-#define BMP085_NUM_COEFFS 22
-
-/* commands, values */
-#define BMP085_CHIP_ID 0x55
-
-#define BMP085_CMD_CONVERT_TEMP 0x2E
-
-#define BMP085_CMD_CONVERT_PRESS_0 0x34
-#define BMP085_CMD_CONVERT_PRESS_1 0x74
-#define BMP085_CMD_CONVERT_PRESS_2 0xB4
-#define BMP085_CMD_CONVERT_PRESS_3 0xF4
-
-/* in us */
-#define BMP085_TIME_CNV_TEMP 4500
-
-#define BMP085_TIME_CNV_PRESS_0 4500
-#define BMP085_TIME_CNV_PRESS_1 7500
-#define BMP085_TIME_CNV_PRESS_2 13500
-#define BMP085_TIME_CNV_PRESS_3 25500
-
-
-/* ------------ Normalization ------------ */
-/* Mean sea level pressure normalization methods */
-#define MSLP_NONE 0
-#define MSLP_INTERNATIONAL 1
-#define MSLP_DEU_WETT 2
-
-/** Temperature reference history depth for averaging. See #get_reference_temperature */
-#define REF_TEMP_AVG_NUM 5
-
-
-/* ------------------------------------------ */
-
-/** Supported sensor types */
-enum Sensor_type {
- Sensor_none = 0,
- Sensor_MPL115,
- Sensor_MPL3115,
- Sensor_BMP085
-};
-
-static const char *config_keys[] =
-{
- "Device",
- "Oversampling",
- "PressureOffset", /**< only for MPL3115 */
- "TemperatureOffset", /**< only for MPL3115 */
- "Altitude",
- "Normalization",
- "TemperatureSensor"
-};
-
-static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
-
-static char * config_device = NULL; /**< I2C bus device */
-static int config_oversample = 1; /**< averaging window */
-
-static double config_press_offset = 0.0; /**< pressure offset */
-static double config_temp_offset = 0.0; /**< temperature offset */
-
-static double config_altitude = NAN; /**< altitude */
-static int config_normalize = 0; /**< normalization method */
-
-static _Bool configured = 0; /**< the whole plugin config status */
-
-static int i2c_bus_fd = -1; /**< I2C bus device FD */
-
-static enum Sensor_type sensor_type = Sensor_none; /**< detected/used sensor type */
-
-static __s32 mpl3115_oversample = 0; /**< MPL3115 CTRL1 oversample setting */
-
-// BMP085 configuration
-static unsigned bmp085_oversampling; /**< BMP085 oversampling (0-3) */
-static unsigned long bmp085_timeCnvPress; /**< BMP085 conversion time for pressure in us */
-static __u8 bmp085_cmdCnvPress; /**< BMP085 pressure conversion command */
-
-
-/* MPL115 conversion coefficients */
-static double mpl115_coeffA0;
-static double mpl115_coeffB1;
-static double mpl115_coeffB2;
-static double mpl115_coeffC12;
-static double mpl115_coeffC11;
-static double mpl115_coeffC22;
-
-/* BMP085 conversion coefficients */
-static short bmp085_AC1;
-static short bmp085_AC2;
-static short bmp085_AC3;
-static unsigned short bmp085_AC4;
-static unsigned short bmp085_AC5;
-static unsigned short bmp085_AC6;
-static short bmp085_B1;
-static short bmp085_B2;
-static short bmp085_MB;
-static short bmp085_MC;
-static short bmp085_MD;
-
-
-
-/* ------------------------ averaging ring buffer ------------------------ */
-/* Used only for MPL115. MPL3115 supports real oversampling in the device so */
-/* no need for any postprocessing. */
-
-static _Bool avg_initialized = 0; /**< already initialized by real values */
-
-typedef struct averaging_s {
- long int * ring_buffer;
- int ring_buffer_size;
- long int ring_buffer_sum;
- int ring_buffer_head;
-} averaging_t;
-
-
-static averaging_t pressure_averaging = { NULL, 0, 0L, 0 };
-static averaging_t temperature_averaging = { NULL, 0, 0L, 0 };
-
-
-/**
- * Create / allocate averaging buffer
- *
- * The buffer is initialized with zeros.
- *
- * @param avg pointer to ring buffer to be allocated
- * @param size requested buffer size
- *
- * @return Zero when successful
- */
-static int averaging_create(averaging_t * avg, int size)
-{
- int a;
-
- avg->ring_buffer = (long int *) malloc(size * sizeof(*avg));
- if (avg->ring_buffer == NULL)
- {
- ERROR ("barometer: averaging_create - ring buffer allocation of size %d failed",
- size);
- return -1;
- }
-
- for (a=0; a<size; ++a)
- {
- avg->ring_buffer[a] = 0L;
- }
-
- avg->ring_buffer_size = size;
- avg->ring_buffer_sum = 0L;
- avg->ring_buffer_head = 0;
-
- return 0;
-}
-
-
-/**
- * Delete / free existing averaging buffer
- *
- * @param avg pointer to the ring buffer to be deleted
- */
-static void averaging_delete(averaging_t * avg)
-{
- if (avg->ring_buffer != NULL)
- {
- free(avg->ring_buffer);
- avg->ring_buffer = NULL;
- }
- avg->ring_buffer_size = 0;
- avg->ring_buffer_sum = 0L;
- avg->ring_buffer_head = 0;
-}
-
-
-/*
- * Add new sample to the averaging buffer
- *
- * A new averaged value is returned. Note that till the buffer is full
- * returned value is inaccurate as it is an average of real values and initial
- * zeros.
- *
- * @param avg pointer to the ring buffer
- * @param sample new sample value
- *
- * @return Averaged sample value
- */
-static double averaging_add_sample(averaging_t * avg, long int sample)
-{
- double result;
-
- avg->ring_buffer_sum += sample - avg->ring_buffer[avg->ring_buffer_head];
- avg->ring_buffer[avg->ring_buffer_head] = sample;
- avg->ring_buffer_head = (avg->ring_buffer_head+1) % avg->ring_buffer_size;
- result = (double)(avg->ring_buffer_sum) / (double)(avg->ring_buffer_size);
-
- DEBUG ("barometer: averaging_add_sample - added %ld, result = %lf",
- sample,
- result);
-
- return result;
-}
-
-
-/* ------------------------ temperature refference ------------------------ */
-
-/**
- * Linked list type of temperature sensor references
- */
-typedef struct temperature_list_s {
- char * sensor_name; /**< sensor name/reference */
- size_t num_values; /**< number of values (usually one) */
- _Bool initialized; /**< sensor already provides data */
- struct temperature_list_s * next; /**< next in the list */
-} temperature_list_t;
-
-static temperature_list_t * temp_list = NULL;
-
-
-/*
- * Add new sensor to the temperature reference list
- *
- * @param list the list
- * @param sensor reference name (as provided by the config file)
- *
- * @return Zero when successful
- */
-static int temp_list_add(temperature_list_t * list, const char * sensor)
-{
- temperature_list_t * new_temp;
-
- new_temp = (temperature_list_t *) malloc(sizeof(*new_temp));
- if(new_temp == NULL)
- return -1;
-
- new_temp->sensor_name = strdup(sensor);
- new_temp->initialized = 0;
- new_temp->num_values = 0;
- if(new_temp->sensor_name == NULL)
- {
- free(new_temp);
- return -1;
- }
-
- new_temp->next = temp_list;
- temp_list = new_temp;
- return 0;
-}
-
-
-/*
- * Delete the whole temperature reference list
- *
- * @param list the list to be deleted
- */
-static void temp_list_delete(temperature_list_t ** list)
-{
- temperature_list_t * tmp;
-
- while (*list != NULL)
- {
- tmp = (*list);
- (*list) = (*list)->next;
- free(tmp->sensor_name);
- free(tmp);
- tmp = NULL;
- }
-}
-
-
-/*
- * Get reference temperature value
- *
- * First initially uc_get_rate_by_name is tried. At the startup due to nondeterministic
- * order the temperature may not be read yet (then it fails and first measurment gives
- * only absolute air pressure reading which is acceptable). Once it succedes (should be
- * second measurement at the latest) we use average of few last readings from
- * uc_get_history_by_name. It may take few readings to start filling so again we use
- * uc_get_rate_by_name as a fallback.
- * The idea is to use basic "noise" filtering (history averaging) across all the values
- * which given sensor provides (up to given depth). Then we get minimum among
- * the sensors.
- *
- * @param result where the result is stored. When not available NAN is stored.
- *
- * @return Zero when successful
- */
-static int get_reference_temperature(double * result)
-{
- temperature_list_t * list = temp_list;
-
- gauge_t * values = NULL; /**< rate values */
- size_t values_num = 0; /**< number of rate values */
- int i;
-
- gauge_t values_history[REF_TEMP_AVG_NUM];
-
- double avg_sum; /**< Value sum for computing average */
- int avg_num; /**< Number of values for computing average */
- double average; /**< Resulting value average */
-
- *result = NAN;
-
- while(list != NULL)
- {
- avg_sum = 0.0;
- avg_num = 0;
-
- /* First time need to read current rate to learn how many values are
- there (typically for temperature it would be just one).
- We do not expect dynamic changing of number of temperarure values
- in runtime yet (are there any such cases?). */
- if(!list->initialized)
- {
- if(uc_get_rate_by_name(list->sensor_name,
- &values,
- &values_num))
- {
- DEBUG ("barometer: get_reference_temperature - rate \"%s\" not found yet",
- list->sensor_name);
- list = list->next;
- continue;
- }
-
- DEBUG ("barometer: get_reference_temperature - initialize \"%s\", %zu vals",
- list->sensor_name,
- values_num);
-
- list->initialized = 1;
- list->num_values = values_num;
-
- for(i=0; i<values_num; ++i)
- {
- DEBUG ("barometer: get_reference_temperature - rate %d: %lf **",
- i,
- values[i]);
- if(!isnan(values[i]))
- {
- avg_sum += values[i];
- ++avg_num;
- }
- }
- free(values);
- values = NULL;
- }
-
- /* It is OK to get here the first time as well, in the worst case
- the history will full of NANs. */
- if(uc_get_history_by_name(list->sensor_name,
- values_history,
- REF_TEMP_AVG_NUM,
- list->num_values))
- {
- ERROR ("barometer: get_reference_temperature - history \"%s\" lost",
- list->sensor_name);
- list->initialized = 0;
- list->num_values = 0;
- list = list->next;
- continue;
- }
-
- for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
- {
- DEBUG ("barometer: get_reference_temperature - history %d: %lf",
- i,
- values_history[i]);
- if(!isnan(values_history[i]))
- {
- avg_sum += values_history[i];
- ++avg_num;
- }
- }
-
- if(avg_num == 0) /* still no history? fallback to current */
- {
- if(uc_get_rate_by_name(list->sensor_name,
- &values,
- &values_num))
- {
- ERROR ("barometer: get_reference_temperature - rate \"%s\" lost",
- list->sensor_name);
- list->initialized = 0;
- list->num_values = 0;
- list = list->next;
- continue;
- }
-
- for(i=0; i<values_num; ++i)
- {
- DEBUG ("barometer: get_reference_temperature - rate last %d: %lf **",
- i,
- values[i]);
- if(!isnan(values[i]))
- {
- avg_sum += values[i];
- ++avg_num;
- }
- }
- free(values);
- values = NULL;
- }
-
- if(avg_num == 0)
- {
- ERROR ("barometer: get_reference_temperature - could not read \"%s\"",
- list->sensor_name);
- list->initialized = 0;
- list->num_values = 0;
- }
- else
- {
- average = avg_sum / (double) avg_num;
- if(isnan(*result))
- *result=average;
- else if(*result>average)
- *result=average;
- }
- list = list->next;
- } /* while sensor list */
-
- if(*result == NAN)
- {
- ERROR("barometer: get_reference_temperature - no sensor available (yet?)");
- return -1;
- }
- DEBUG ("barometer: get_reference_temperature - temp is %lf", *result);
- return 0;
-}
-
-
-/* ------------------------ MPL115 access ------------------------ */
-
-/**
- * Detect presence of a MPL115 pressure sensor.
- *
- * Unfortunately there seems to be no ID register so we just try to read first
- * conversion coefficient from device at MPL115 address and hope it is really
- * MPL115. We should use this check as the last resort (which would be the typical
- * case anyway since MPL115 is the least accurate sensor).
- * As a sideeffect will leave set I2C slave address.
- *
- * @return 1 if MPL115, 0 otherwise
- */
-static int MPL115_detect(void)
-{
- __s32 res;
- char errbuf[1024];
-
- if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL115_I2C_ADDRESS) < 0)
- {
- ERROR("barometer: MPL115_detect problem setting i2c slave address to 0x%02X: %s",
- MPL115_I2C_ADDRESS,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 0 ;
- }
-
- res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL115_ADDR_COEFFS);
- if(res >= 0)
- {
- DEBUG ("barometer: MPL115_detect - positive detection");
- return 1;
- }
-
- DEBUG ("barometer: MPL115_detect - negative detection");
- return 0;
-}
-
-/**
- * Read the MPL115 sensor conversion coefficients.
- *
- * These are (device specific) constants so we can read them just once.
- *
- * @return Zero when successful
- */
-static int MPL115_read_coeffs(void)
-{
- uint8_t mpl115_coeffs[MPL115_NUM_COEFFS];
- int32_t res;
-
- int8_t sia0MSB, sia0LSB, sib1MSB, sib1LSB, sib2MSB, sib2LSB;
- int8_t sic12MSB, sic12LSB, sic11MSB, sic11LSB, sic22MSB, sic22LSB;
- int16_t sia0, sib1, sib2, sic12, sic11, sic22;
-
- char errbuf[1024];
-
- res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
- MPL115_ADDR_COEFFS,
- MPL115_NUM_COEFFS,
- mpl115_coeffs);
- if (res < 0)
- {
- ERROR ("barometer: MPL115_read_coeffs - problem reading data: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- /* Using perhaps less elegant/efficient code, but more readable. */
- /* a0: 16total 1sign 12int 4fract 0pad */
- sia0MSB = mpl115_coeffs[0];
- sia0LSB = mpl115_coeffs[1];
- sia0 = (int16_t) sia0MSB <<8; /* s16 type, Shift to MSB */
- sia0 += (int16_t) sia0LSB & 0x00FF; /* Add LSB to 16bit number */
- mpl115_coeffA0 = (double) (sia0);
- mpl115_coeffA0 /= 8.0; /* 3 fract bits */
-
- /* b1: 16total 1sign 2int 13fract 0pad */
- sib1MSB= mpl115_coeffs[2];
- sib1LSB= mpl115_coeffs[3];
- sib1 = sib1MSB <<8; /* Shift to MSB */
- sib1 += sib1LSB & 0x00FF; /* Add LSB to 16bit number */
- mpl115_coeffB1 = (double) (sib1);
- mpl115_coeffB1 /= 8192.0; /* 13 fract */
-
- /* b2: 16total 1sign 1int 14fract 0pad */
- sib2MSB= mpl115_coeffs[4];
- sib2LSB= mpl115_coeffs[5];
- sib2 = sib2MSB <<8; /* Shift to MSB */
- sib2 += sib2LSB & 0x00FF; /* Add LSB to 16bit number */
- mpl115_coeffB2 = (double) (sib2);
- mpl115_coeffB2 /= 16384.0; /* 14 fract */
-
- /* c12: 14total 1sign 0int 13fract 9pad */
- sic12MSB= mpl115_coeffs[6];
- sic12LSB= mpl115_coeffs[7];
- sic12 = sic12MSB <<8; /* Shift to MSB only by 8 for MSB */
- sic12 += sic12LSB & 0x00FF;
- mpl115_coeffC12 = (double) (sic12);
- mpl115_coeffC12 /= 4.0; /* 16-14=2 */
- mpl115_coeffC12 /= 4194304.0; /* 13+9=22 fract */
-
- /* c11: 11total 1sign 0int 11fract 11pad */
- sic11MSB= mpl115_coeffs[8];
- sic11LSB= mpl115_coeffs[9];
- sic11 = sic11MSB <<8; /* Shift to MSB only by 8 for MSB */
- sic11 += sic11LSB & 0x00FF;
- mpl115_coeffC11 = (double) (sic11);
- mpl115_coeffC11 /= 32.0; /* 16-11=5 */
- mpl115_coeffC11 /= 4194304.0; /* 11+11=22 fract */
-
- /* c12: 11total 1sign 0int 10fract 15pad */
- sic22MSB= mpl115_coeffs[10];
- sic22LSB= mpl115_coeffs[11];
- sic22 = sic22MSB <<8; /* Shift to MSB only by 8 for MSB */
- sic22 += sic22LSB & 0x00FF;
- mpl115_coeffC22 = (double) (sic22);
- mpl115_coeffC22 /= 32.0; //16-11=5
- mpl115_coeffC22 /= 33554432.0; /* 10+15=25 fract */
-
- DEBUG("barometer: MPL115_read_coeffs: a0=%lf, b1=%lf, b2=%lf, c12=%lf, c11=%lf, c22=%lf",
- mpl115_coeffA0,
- mpl115_coeffB1,
- mpl115_coeffB2,
- mpl115_coeffC12,
- mpl115_coeffC11,
- mpl115_coeffC22);
- return 0;
-}
-
-
-/**
- * Convert raw adc values to real data using the sensor coefficients.
- *
- * @param adc_pressure adc pressure value to be converted
- * @param adc_temp adc temperature value to be converted
- * @param pressure computed real pressure
- * @param temperature computed real temperature
- */
-static void MPL115_convert_adc_to_real(double adc_pressure,
- double adc_temp,
- double * pressure,
- double * temperature)
-{
- double Pcomp;
- Pcomp = mpl115_coeffA0 + \
- (mpl115_coeffB1 + mpl115_coeffC11*adc_pressure + mpl115_coeffC12*adc_temp) * adc_pressure + \
- (mpl115_coeffB2 + mpl115_coeffC22*adc_temp) * adc_temp;
-
- *pressure = ((1150.0-500.0) * Pcomp / 1023.0) + 500.0;
- *temperature = (472.0 - adc_temp) / 5.35 + 25.0;
- DEBUG ("barometer: MPL115_convert_adc_to_real - got %lf hPa, %lf C",
- *pressure,
- *temperature);
-}
-
-
-/**
- * Read sensor averegaed measurements
- *
- * @param pressure averaged measured pressure
- * @param temperature averaged measured temperature
- *
- * @return Zero when successful
- */
-static int MPL115_read_averaged(double * pressure, double * temperature)
-{
- uint8_t mpl115_conv[MPL115_NUM_CONV];
- int8_t res;
- int retries;
- int conv_pressure;
- int conv_temperature;
- double adc_pressure;
- double adc_temperature;
- char errbuf[1024];
-
- *pressure = 0.0;
- *temperature = 0.0;
-
- /* start conversion of both temp and presure */
- retries = MPL115_CONVERSION_RETRIES;
- while (retries>0)
- {
- /* write 1 to start conversion */
- res = i2c_smbus_write_byte_data (i2c_bus_fd,
- MPL115_CMD_CONVERT_BOTH,
- 0x01);
- if (res >= 0)
- break;
-
- --retries;
- if(retries>0)
- {
- ERROR ("barometer: MPL115_read_averaged - requesting conversion: %s, " \
- "will retry at most %d more times",
- sstrerror (errno, errbuf, sizeof (errbuf)),
- retries);
- }
- else
- {
- ERROR ("barometer: MPL115_read_averaged - requesting conversion: %s, "\
- "too many failed retries",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
- }
-
- usleep (10000); /* wait 10ms for the conversion */
-
- retries=MPL115_CONVERSION_RETRIES;
- while (retries>0)
- {
- res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
- MPL115_ADDR_CONV,
- MPL115_NUM_CONV,
- mpl115_conv);
- if (res >= 0)
- break;
-
- --retries;
- if (retries>0)
- {
- ERROR ("barometer: MPL115_read_averaged - reading conversion: %s, " \
- "will retry at most %d more times",
- sstrerror (errno, errbuf, sizeof (errbuf)),
- retries);
- }
- else
- {
- ERROR ("barometer: MPL115_read_averaged - reading conversion: %s, " \
- "too many failed retries",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
- }
-
- conv_pressure = ((mpl115_conv[0] << 8) | mpl115_conv[1]) >> 6;
- conv_temperature = ((mpl115_conv[2] << 8) | mpl115_conv[3]) >> 6;
- DEBUG ("barometer: MPL115_read_averaged, raw pressure ADC value = %d, " \
- "raw temperature ADC value = %d",
- conv_pressure,
- conv_temperature);
-
- adc_pressure = averaging_add_sample (&pressure_averaging, conv_pressure);
- adc_temperature = averaging_add_sample (&temperature_averaging, conv_temperature);
-
- MPL115_convert_adc_to_real(adc_pressure, adc_temperature, pressure, temperature);
-
- DEBUG ("barometer: MPL115_read_averaged - averaged ADC pressure = %lf / temperature = %lf, " \
- "real pressure = %lf hPa / temperature = %lf C",
- adc_pressure,
- adc_temperature,
- *pressure,
- *temperature);
-
- return 0;
-}
-
-/* ------------------------ MPL3115 access ------------------------ */
-
-/**
- * Detect presence of a MPL3115 pressure sensor by checking register "WHO AM I"
- *
- * As a sideeffect will leave set I2C slave address.
- *
- * @return 1 if MPL3115, 0 otherwise
- */
-static int MPL3115_detect(void)
-{
- __s32 res;
- char errbuf[1024];
-
- if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL3115_I2C_ADDRESS) < 0)
- {
- ERROR("barometer: MPL3115_detect problem setting i2c slave address to 0x%02X: %s",
- MPL3115_I2C_ADDRESS,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 0 ;
- }
-
- res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_WHO_AM_I);
- if(res == MPL3115_WHO_AM_I_RESP)
- {
- DEBUG ("barometer: MPL3115_detect - positive detection");
- return 1;
- }
-
- DEBUG ("barometer: MPL3115_detect - negative detection");
- return 0;
-}
-
-/**
- * Adjusts oversampling to values supported by MPL3115
- *
- * MPL3115 supports only power of 2 in the range 1 to 128.
- */
-static void MPL3115_adjust_oversampling(void)
-{
- int new_val = 0;
-
- if(config_oversample > 100)
- {
- new_val = 128;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_128;
- }
- else if(config_oversample > 48)
- {
- new_val = 64;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_64;
- }
- else if(config_oversample > 24)
- {
- new_val = 32;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_32;
- }
- else if(config_oversample > 12)
- {
- new_val = 16;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_16;
- }
- else if(config_oversample > 6)
- {
- new_val = 8;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_8;
- }
- else if(config_oversample > 3)
- {
- new_val = 4;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_4;
- }
- else if(config_oversample > 1)
- {
- new_val = 2;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_2;
- }
- else
- {
- new_val = 1;
- mpl3115_oversample = MPL3115_CTRL_REG1_OST_1;
- }
-
- DEBUG("barometer: MPL3115_adjust_oversampling - correcting oversampling from %d to %d",
- config_oversample,
- new_val);
- config_oversample = new_val;
-}
-
-/**
- * Read sensor averegaed measurements
- *
- * @param pressure averaged measured pressure
- * @param temperature averaged measured temperature
- *
- * @return Zero when successful
- */
-static int MPL3115_read(double * pressure, double * temperature)
-{
- __s32 res;
- __s32 ctrl ;
- __u8 data[MPL3115_NUM_CONV_VALS];
- long int tmp_value = 0;
- char errbuf[1024];
-
- /* Set Active - activate the device from standby */
- res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_read - cannot read CTRL_REG1: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
- ctrl = res;
- res = i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_CTRL_REG1,
- ctrl | MPL3115_CTRL_REG1_SBYB);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_read - problem activating: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- /* base sleep is 5ms x OST */
- usleep(5000 * config_oversample);
-
- /* check the flags/status if ready */
- res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_read - cannot read status register: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- while ((res & MPL3115_DR_STATUS_DR) != MPL3115_DR_STATUS_DR)
- {
- /* try some extra sleep... */
- usleep(10000);
-
- /* ... and repeat the check. The conversion has to finish sooner or later. */
- res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_read - cannot read status register: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
- }
-
- /* Now read all the data in one block. There is address autoincrement. */
- res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
- MPL3115_REG_OUT_P_MSB,
- MPL3115_NUM_CONV_VALS,
- data);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_read - cannot read data registers: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- tmp_value = (data[0] << 16) | (data[1] << 8) | data[2];
- *pressure = ((double) tmp_value) / 4.0 / 16.0 / 100.0;
- DEBUG ("barometer: MPL3115_read - absolute pressure = %lf hPa", *pressure);
-
- if(data[3] > 0x7F)
- {
- data[3] = ~data[3] + 1;
- *temperature = data[3];
- *temperature = - *temperature;
- }
- else
- {
- *temperature = data[3];
- }
-
- *temperature += (double)(data[4]) / 256.0;
- DEBUG ("barometer: MPL3115_read - temperature = %lf C", *temperature);
-
- return 0;
-}
-
-/**
- * Initialize MPL3115 for barometeric measurements
- *
- * @return 0 if successful
- */
-static int MPL3115_init_sensor(void)
-{
- __s32 res;
- __s8 offset;
- char errbuf[1024];
-
- /* Reset the sensor. It will reset immediately without ACKing */
- /* the transaction, so no error handling here. */
- i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_CTRL_REG1,
- MPL3115_CTRL_REG1_RST);
-
- /* wait some time for the reset to finish */
- usleep(100000);
-
- /* now it should be in standby already so we can go and configure it */
-
- /* Set temperature offset. */
- /* result = ADCtemp + offset [C] */
- offset = (__s8) (config_temp_offset * 16.0);
- res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_T, offset);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_init_sensor - problem setting temp offset: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- /* Set pressure offset. */
- /* result = ADCpress + offset [hPa] */
- offset = (__s8) (config_press_offset * 100.0 / 4.0);
- res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_P, offset);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_init_sensor - problem setting pressure offset: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- /* Enable Data Flags in PT_DATA_CFG - flags on both pressure and temp */
- res = i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_PT_DATA_CFG,
- MPL3115_PT_DATA_DREM \
- | MPL3115_PT_DATA_PDEF \
- | MPL3115_PT_DATA_TDEF);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_init_sensor - problem setting PT_DATA_CFG: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- /* Set to barometer with an OSR */
- res = i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_CTRL_REG1,
- mpl3115_oversample);
- if (res < 0)
- {
- ERROR ("barometer: MPL3115_init_sensor - problem configuring CTRL_REG1: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- return 0;
-}
-
-/* ------------------------ BMP085 access ------------------------ */
-
-/**
- * Detect presence of a BMP085 pressure sensor by checking its ID register
- *
- * As a sideeffect will leave set I2C slave address.
- *
- * @return 1 if BMP085, 0 otherwise
- */
-static int BMP085_detect(void)
-{
- __s32 res;
- char errbuf[1024];
-
- if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, BMP085_I2C_ADDRESS) < 0)
- {
- ERROR("barometer: BMP085_detect - problem setting i2c slave address to 0x%02X: %s",
- BMP085_I2C_ADDRESS,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 0 ;
- }
-
- res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_ID_REG);
- if(res == BMP085_CHIP_ID)
- {
- DEBUG ("barometer: BMP085_detect - positive detection");
-
- /* get version */
- res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_VERSION );
- if (res < 0)
- {
- ERROR("barometer: BMP085_detect - problem checking chip version: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 0 ;
- }
- DEBUG ("barometer: BMP085_detect - chip version ML:0x%02X AL:0x%02X",
- res & 0x0f,
- (res & 0xf0) >> 4);
- return 1;
- }
-
- DEBUG ("barometer: BMP085_detect - negative detection");
- return 0;
-}
-
-
-/**
- * Adjusts oversampling settings to values supported by BMP085
- *
- * BMP085 supports only 1,2,4 or 8 samples.
- */
-static void BMP085_adjust_oversampling(void)
-{
- int new_val = 0;
-
- if( config_oversample > 6 ) /* 8 */
- {
- new_val = 8;
- bmp085_oversampling = 3;
- bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_3;
- bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_3;
- }
- else if( config_oversample > 3 ) /* 4 */
- {
- new_val = 4;
- bmp085_oversampling = 2;
- bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_2;
- bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_2;
- }
- else if( config_oversample > 1 ) /* 2 */
- {
- new_val = 2;
- bmp085_oversampling = 1;
- bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_1;
- bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_1;
- }
- else /* 1 */
- {
- new_val = 1;
- bmp085_oversampling = 0;
- bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_0;
- bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_0;
- }
-
- DEBUG("barometer: BMP085_adjust_oversampling - correcting oversampling from %d to %d",
- config_oversample,
- new_val);
- config_oversample = new_val;
-}
-
-
-/**
- * Read the BMP085 sensor conversion coefficients.
- *
- * These are (device specific) constants so we can read them just once.
- *
- * @return Zero when successful
- */
-static int BMP085_read_coeffs(void)
-{
- __s32 res;
- __u8 coeffs[BMP085_NUM_COEFFS];
- char errbuf[1024];
-
- res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
- BMP085_ADDR_COEFFS,
- BMP085_NUM_COEFFS,
- coeffs);
- if (res < 0)
- {
- ERROR ("barometer: BMP085_read_coeffs - problem reading data: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- bmp085_AC1 = ((int16_t) coeffs[0] <<8) | (int16_t) coeffs[1];
- bmp085_AC2 = ((int16_t) coeffs[2] <<8) | (int16_t) coeffs[3];
- bmp085_AC3 = ((int16_t) coeffs[4] <<8) | (int16_t) coeffs[5];
- bmp085_AC4 = ((uint16_t) coeffs[6] <<8) | (uint16_t) coeffs[7];
- bmp085_AC5 = ((uint16_t) coeffs[8] <<8) | (uint16_t) coeffs[9];
- bmp085_AC6 = ((uint16_t) coeffs[10] <<8) | (uint16_t) coeffs[11];
- bmp085_B1 = ((int16_t) coeffs[12] <<8) | (int16_t) coeffs[13];
- bmp085_B2 = ((int16_t) coeffs[14] <<8) | (int16_t) coeffs[15];
- bmp085_MB = ((int16_t) coeffs[16] <<8) | (int16_t) coeffs[17];
- bmp085_MC = ((int16_t) coeffs[18] <<8) | (int16_t) coeffs[19];
- bmp085_MD = ((int16_t) coeffs[20] <<8) | (int16_t) coeffs[21];
-
- DEBUG("barometer: BMP085_read_coeffs - AC1=%d, AC2=%d, AC3=%d, AC4=%u,"\
- " AC5=%u, AC6=%u, B1=%d, B2=%d, MB=%d, MC=%d, MD=%d",
- bmp085_AC1,
- bmp085_AC2,
- bmp085_AC3,
- bmp085_AC4,
- bmp085_AC5,
- bmp085_AC6,
- bmp085_B1,
- bmp085_B2,
- bmp085_MB,
- bmp085_MC,
- bmp085_MD);
-
- return 0;
-}
-
-
-/**
- * Convert raw BMP085 adc values to real data using the sensor coefficients.
- *
- * @param adc_pressure adc pressure value to be converted
- * @param adc_temp adc temperature value to be converted
- * @param pressure computed real pressure
- * @param temperature computed real temperature
- */
-static void BMP085_convert_adc_to_real(long adc_pressure,
- long adc_temperature,
- double * pressure,
- double * temperature)
-
-{
- long X1, X2, X3;
- long B3, B5, B6;
- unsigned long B4, B7;
-
- long T;
- long P;
-
-
- /* calculate real temperature */
- X1 = ( (adc_temperature - bmp085_AC6) * bmp085_AC5) >> 15;
- X2 = (bmp085_MC << 11) / (X1 + bmp085_MD);
-
- /* B5, T */
- B5 = X1 + X2;
- T = (B5 + 8) >> 4;
- *temperature = (double)T * 0.1;
-
- /* calculate real pressure */
- /* in general X1, X2, X3 are recycled while values of B3, B4, B5, B6 are kept */
-
- /* B6, B3 */
- B6 = B5 - 4000;
- X1 = ((bmp085_B2 * ((B6 * B6)>>12)) >> 11 );
- X2 = (((long)bmp085_AC2 * B6) >> 11);
- X3 = X1 + X2;
- B3 = (((((long)bmp085_AC1 * 4) + X3) << bmp085_oversampling) + 2) >> 2;
-
- /* B4 */
- X1 = (((long)bmp085_AC3*B6) >> 13);
- X2 = (bmp085_B1*((B6*B6) >> 12) ) >> 16;
- X3 = ((X1 + X2) + 2 ) >> 2;
- B4 = ((long)bmp085_AC4* (unsigned long)(X3 + 32768)) >> 15;
-
- /* B7, P */
- B7 = (unsigned long)(adc_pressure - B3)*(50000>>bmp085_oversampling);
- if( B7 < 0x80000000 )
- {
- P = (B7 << 1) / B4;
- }
- else
- {
- P = (B7/B4) << 1;
- }
- X1 = (P >> 8) * (P >> 8);
- X1 = (X1 * 3038) >> 16;
- X2 = ((-7357) * P) >> 16;
- P = P + ( ( X1 + X2 + 3791 ) >> 4);
-
- *pressure = P / 100.0; // in [hPa]
- DEBUG ("barometer: BMP085_convert_adc_to_real - got %lf hPa, %lf C",
- *pressure,
- *temperature);
-}
-
-
-/**
- * Read compensated sensor measurements
- *
- * @param pressure averaged measured pressure
- * @param temperature averaged measured temperature
- *
- * @return Zero when successful
- */
-static int BMP085_read(double * pressure, double * temperature)
-{
- __s32 res;
- __u8 measBuff[3];
-
- long adc_pressure;
- long adc_temperature;
-
- char errbuf[1024];
-
- /* start conversion of temperature */
- res = i2c_smbus_write_byte_data( i2c_bus_fd,
- BMP085_ADDR_CTRL_REG,
- BMP085_CMD_CONVERT_TEMP );
- if (res < 0)
- {
- ERROR ("barometer: BMP085_read - problem requesting temperature conversion: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- usleep(BMP085_TIME_CNV_TEMP); /* wait for the conversion */
-
- res = i2c_smbus_read_i2c_block_data( i2c_bus_fd,
- BMP085_ADDR_CONV,
- 2,
- measBuff);
- if (res < 0)
- {
- ERROR ("barometer: BMP085_read - problem reading temperature data: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- adc_temperature = ( (unsigned short)measBuff[0] << 8 ) + measBuff[1];
-
-
- /* get presure */
- res = i2c_smbus_write_byte_data( i2c_bus_fd,
- BMP085_ADDR_CTRL_REG,
- bmp085_cmdCnvPress );
- if (res < 0)
- {
- ERROR ("barometer: BMP085_read - problem requesting pressure conversion: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- usleep(bmp085_timeCnvPress); /* wait for the conversion */
-
- res = i2c_smbus_read_i2c_block_data( i2c_bus_fd,
- BMP085_ADDR_CONV,
- 3,
- measBuff );
- if (res < 0)
- {
- ERROR ("barometer: BMP085_read - problem reading pressure data: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return 1;
- }
-
- adc_pressure = (long)((((ulong)measBuff[0]<<16) | ((ulong)measBuff[1]<<8) | (ulong)measBuff[2] ) >> (8 - bmp085_oversampling));
-
-
- DEBUG ("barometer: BMP085_read - raw pressure ADC value = %ld, " \
- "raw temperature ADC value = %ld",
- adc_pressure,
- adc_temperature);
-
- BMP085_convert_adc_to_real(adc_pressure, adc_temperature, pressure, temperature);
-
- return 0;
-}
-
-
-
-/* ------------------------ Sensor detection ------------------------ */
-/**
- * Detect presence of a supported sensor.
- *
- * As a sideeffect will leave set I2C slave address.
- * The detection is done in the order BMP085, MPL3115, MPL115 and stops after
- * first sensor beeing found.
- *
- * @return detected sensor type
- */
-enum Sensor_type Detect_sensor_type(void)
-{
- if(BMP085_detect())
- return Sensor_BMP085;
-
- else if(MPL3115_detect())
- return Sensor_MPL3115;
-
- else if(MPL115_detect())
- return Sensor_MPL115;
-
- return Sensor_none;
-}
-
-/* ------------------------ Common functionality ------------------------ */
-
-/**
- * Convert absolute pressure (in hPa) to mean sea level pressure
- *
- * Implemented methods are:
- * - MSLP_NONE - no converions, returns absolute pressure
- *
- * - MSLP_INTERNATIONAL - see http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation
- * Requires #config_altitude
- *
- * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See
- * http://de.wikipedia.org/wiki/Barometrische_H%C3%B6henformel#Theorie
- * Requires both #config_altitude and temperature reference(s).
- *
- * @param abs_pressure absloute pressure to be converted
- *
- * @return mean sea level pressure if successful, NAN otherwise
- */
-static double abs_to_mean_sea_level_pressure(double abs_pressure)
-{
- double mean = -1.0;
- double temp = 0.0;
- int result = 0;
-
- if (config_normalize >= MSLP_DEU_WETT)
- {
- result = get_reference_temperature(&temp);
- if(result)
- {
- return NAN;
- }
- }
-
- switch(config_normalize)
- {
- case MSLP_NONE:
- mean = abs_pressure;
- break;
-
- case MSLP_INTERNATIONAL:
- mean = abs_pressure / \
- pow(1.0 - 0.0065*config_altitude/288.15, 9.80665*0.0289644/(8.31447*0.0065));
- break;
-
- case MSLP_DEU_WETT:
- {
- double E; /* humidity */
- double x;
- if(temp<9.1)
- E = 5.6402 * (-0.0916 + exp(0.06*temp) );
- else
- E = 18.2194 * (1.0463 - exp(-0.0666*temp) );
- x = 9.80665 / (287.05 * (temp+273.15 + 0.12*E + 0.0065*config_altitude/2)) * config_altitude;
- mean = abs_pressure * exp(x);
- }
- break;
-
- default:
- ERROR ("barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d",
- config_normalize);
- mean = abs_pressure;
- break;
- }
-
- DEBUG ("barometer: abs_to_mean_sea_level_pressure: absPressure = %lf hPa, method = %d, meanPressure = %lf hPa",
- abs_pressure,
- config_normalize,
- mean);
-
- return mean;
-}
-
-/* ------------------------ main plugin callbacks ------------------------ */
-
-/**
- * Main plugin configuration callback (using simple config)
- *
- * @param key configuration key we should process
- * @param value configuration value we should process
- *
- * @return Zero when successful.
- */
-static int collectd_barometer_config (const char *key, const char *value)
-{
- DEBUG("barometer: collectd_barometer_config");
-
- if (strcasecmp (key, "Device") == 0)
- {
- sfree (config_device);
- config_device = strdup (value);
- }
- else if (strcasecmp (key, "Oversampling") == 0)
- {
- int oversampling_tmp = atoi (value);
- if (oversampling_tmp < 1 || oversampling_tmp > 1024)
- {
- WARNING ("barometer: collectd_barometer_config: invalid oversampling: %d." \
- " Allowed values are 1 to 1024 (for MPL115) or 1 to 128 (for MPL3115) or 1 to 8 (for BMP085).",
- oversampling_tmp);
- return 1;
- }
- config_oversample = oversampling_tmp;
- }
- else if (strcasecmp (key, "Altitude") == 0)
- {
- config_altitude = atof (value);
- }
- else if (strcasecmp (key, "Normalization") == 0)
- {
- int normalize_tmp = atoi (value);
- if (normalize_tmp < 0 || normalize_tmp > 2)
- {
- WARNING ("barometer: collectd_barometer_config: invalid normalization: %d",
- normalize_tmp);
- return 1;
- }
- config_normalize = normalize_tmp;
- }
- else if (strcasecmp (key, "TemperatureSensor") == 0)
- {
- if(temp_list_add(temp_list, value))
- {
- return -1;
- }
- }
- else if (strcasecmp (key, "PressureOffset") == 0)
- {
- config_press_offset = atof(value);
- }
- else if (strcasecmp (key, "TemperatureOffset") == 0)
- {
- config_temp_offset = atof(value);
- }
- else
- {
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * Shutdown callback.
- *
- * Close I2C and delete all the buffers.
- *
- * @return Zero when successful (at the moment the only possible outcome)
- */
-static int collectd_barometer_shutdown(void)
-{
- DEBUG ("barometer: collectd_barometer_shutdown");
-
- if(sensor_type == Sensor_MPL115)
- {
- averaging_delete (&pressure_averaging);
- averaging_delete (&temperature_averaging);
-
- temp_list_delete(&temp_list);
- }
-
- if (i2c_bus_fd > 0)
- {
- close (i2c_bus_fd);
- i2c_bus_fd = -1;
- sfree (config_device);
- }
-
- return 0;
-}
-
-
-/**
- * Plugin read callback for MPL115.
- *
- * Dispatching will create values:
- * - <hostname>/barometer-mpl115/pressure-normalized
- * - <hostname>/barometer-mpl115/pressure-absolute
- * - <hostname>/barometer-mpl115/temperature
- *
- * @return Zero when successful.
- */
-static int MPL115_collectd_barometer_read (void)
-{
- int result = 0;
-
- double pressure = 0.0;
- double temperature = 0.0;
- double norm_pressure = 0.0;
-
- value_list_t vl = VALUE_LIST_INIT;
- value_t values[1];
-
- DEBUG("barometer: MPL115_collectd_barometer_read");
-
- if (!configured)
- {
- return -1;
- }
-
- /* Rather than delaying init, we will intitialize during first read. This
- way at least we have a better chance to have the reference temperature
- already available. */
- if(!avg_initialized)
- {
- int i;
- for(i=0; i<config_oversample-1; ++i)
- {
- result = MPL115_read_averaged(&pressure, &temperature);
- if(result)
- {
- ERROR ("barometer: MPL115_collectd_barometer_read - mpl115 read, ignored during init");
- }
- DEBUG("barometer: MPL115_collectd_barometer_read - init %d / %d", i+1, config_oversample-1);
- usleep(20000);
- }
- avg_initialized = 1;
- }
-
- result = MPL115_read_averaged(&pressure, &temperature);
- if(result)
- return result;
-
- norm_pressure = abs_to_mean_sea_level_pressure(pressure);
-
- sstrncpy (vl.host, hostname_g, sizeof (vl.host));
- sstrncpy (vl.plugin, "barometer", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, "mpl115", sizeof (vl.plugin_instance));
-
- vl.values_len = 1;
- vl.values = values;
-
- /* dispatch normalized air pressure */
- sstrncpy (vl.type, "pressure", sizeof (vl.type));
- sstrncpy (vl.type_instance, "normalized", sizeof (vl.type_instance));
- values[0].gauge = norm_pressure;
- plugin_dispatch_values (&vl);
-
- /* dispatch absolute air pressure */
- sstrncpy (vl.type, "pressure", sizeof (vl.type));
- sstrncpy (vl.type_instance, "absolute", sizeof (vl.type_instance));
- values[0].gauge = pressure;
- plugin_dispatch_values (&vl);
-
- /* dispatch sensor temperature */
- sstrncpy (vl.type, "temperature", sizeof (vl.type));
- sstrncpy (vl.type_instance, "", sizeof (vl.type_instance));
- values[0].gauge = temperature;
- plugin_dispatch_values (&vl);
-
- return 0;
-}
-
-
-/**
- * Plugin read callback for MPL3115.
- *
- * Dispatching will create values:
- * - <hostname>/barometer-mpl3115/pressure-normalized
- * - <hostname>/barometer-mpl3115/pressure-absolute
- * - <hostname>/barometer-mpl3115/temperature
- *
- * @return Zero when successful.
- */
-static int MPL3115_collectd_barometer_read (void)
-{
- int result = 0;
-
- double pressure = 0.0;
- double temperature = 0.0;
- double norm_pressure = 0.0;
-
- value_list_t vl = VALUE_LIST_INIT;
- value_t values[1];
-
- DEBUG("barometer: MPL3115_collectd_barometer_read");
-
- if (!configured)
- {
- return -1;
- }
-
- result = MPL3115_read(&pressure, &temperature);
- if(result)
- return result;
-
- norm_pressure = abs_to_mean_sea_level_pressure(pressure);
-
- sstrncpy (vl.host, hostname_g, sizeof (vl.host));
- sstrncpy (vl.plugin, "barometer", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, "mpl3115", sizeof (vl.plugin_instance));
-
- vl.values_len = 1;
- vl.values = values;
-
- /* dispatch normalized air pressure */
- sstrncpy (vl.type, "pressure", sizeof (vl.type));
- sstrncpy (vl.type_instance, "normalized", sizeof (vl.type_instance));
- values[0].gauge = norm_pressure;
- plugin_dispatch_values (&vl);
-
- /* dispatch absolute air pressure */
- sstrncpy (vl.type, "pressure", sizeof (vl.type));
- sstrncpy (vl.type_instance, "absolute", sizeof (vl.type_instance));
- values[0].gauge = pressure;
- plugin_dispatch_values (&vl);
-
- /* dispatch sensor temperature */
- sstrncpy (vl.type, "temperature", sizeof (vl.type));
- sstrncpy (vl.type_instance, "", sizeof (vl.type_instance));
- values[0].gauge = temperature;
- plugin_dispatch_values (&vl);
-
- return 0;
-}
-
-
-/**
- * Plugin read callback for BMP085.
- *
- * Dispatching will create values:
- * - <hostname>/barometer-bmp085/pressure-normalized
- * - <hostname>/barometer-bmp085/pressure-absolute
- * - <hostname>/barometer-bmp085/temperature
- *
- * @return Zero when successful.
- */
-static int BMP085_collectd_barometer_read (void)
-{
- int result = 0;
-
- double pressure = 0.0;
- double temperature = 0.0;
- double norm_pressure = 0.0;
-
- value_list_t vl = VALUE_LIST_INIT;
- value_t values[1];
-
- DEBUG("barometer: BMP085_collectd_barometer_read");
-
- if (!configured)
- {
- return -1;
- }
-
- result = BMP085_read(&pressure, &temperature);
- if(result)
- return result;
-
- norm_pressure = abs_to_mean_sea_level_pressure(pressure);
-
- sstrncpy (vl.host, hostname_g, sizeof (vl.host));
- sstrncpy (vl.plugin, "barometer", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, "bmp085", sizeof (vl.plugin_instance));
-
- vl.values_len = 1;
- vl.values = values;
-
- /* dispatch normalized air pressure */
- sstrncpy (vl.type, "pressure", sizeof (vl.type));
- sstrncpy (vl.type_instance, "normalized", sizeof (vl.type_instance));
- values[0].gauge = norm_pressure;
- plugin_dispatch_values (&vl);
-
- /* dispatch absolute air pressure */
- sstrncpy (vl.type, "pressure", sizeof (vl.type));
- sstrncpy (vl.type_instance, "absolute", sizeof (vl.type_instance));
- values[0].gauge = pressure;
- plugin_dispatch_values (&vl);
-
- /* dispatch sensor temperature */
- sstrncpy (vl.type, "temperature", sizeof (vl.type));
- sstrncpy (vl.type_instance, "", sizeof (vl.type_instance));
- values[0].gauge = temperature;
- plugin_dispatch_values (&vl);
-
- return 0;
-}
-
-
-/**
- * Initialization callback
- *
- * Check config, initialize I2C bus access, conversion coefficients and averaging
- * ring buffers
- *
- * @return Zero when successful.
- */
-static int collectd_barometer_init (void)
-{
- char errbuf[1024];
-
- DEBUG ("barometer: collectd_barometer_init");
-
- if (config_device == NULL)
- {
- ERROR("barometer: collectd_barometer_init I2C bus device not configured");
- return -1;
- }
-
- if (config_normalize >= MSLP_INTERNATIONAL && isnan(config_altitude))
- {
- ERROR("barometer: collectd_barometer_init no altitude configured " \
- "for mean sea level pressure normalization.");
- return -1;
- }
-
- if (config_normalize == MSLP_DEU_WETT
- &&
- temp_list == NULL)
- {
- ERROR("barometer: collectd_barometer_init no temperature reference "\
- "configured for mean sea level pressure normalization.");
- return -1;
- }
-
-
- i2c_bus_fd = open(config_device, O_RDWR);
- if (i2c_bus_fd < 0)
- {
- ERROR ("barometer: collectd_barometer_init problem opening I2C bus device \"%s\": %s (is loaded mod i2c-dev?)",
- config_device,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return -1;
- }
-
- /* detect sensor type - this will also set slave address */
- sensor_type = Detect_sensor_type();
-
- /* init correct sensor type */
- switch(sensor_type)
- {
-/* MPL3115 */
- case Sensor_MPL3115:
- {
- MPL3115_adjust_oversampling();
-
- if(MPL3115_init_sensor())
- return -1;
-
- plugin_register_read ("barometer", MPL3115_collectd_barometer_read);
- }
- break;
-
-/* MPL115 */
- case Sensor_MPL115:
- {
- if (averaging_create (&pressure_averaging, config_oversample))
- {
- ERROR("barometer: collectd_barometer_init pressure averaging init failed");
- return -1;
- }
-
- if (averaging_create (&temperature_averaging, config_oversample))
- {
- ERROR("barometer: collectd_barometer_init temperature averaging init failed");
- return -1;
- }
-
- if (MPL115_read_coeffs() < 0)
- return -1;
-
- plugin_register_read ("barometer", MPL115_collectd_barometer_read);
- }
- break;
-
-/* BMP085 */
- case Sensor_BMP085:
- {
- BMP085_adjust_oversampling();
-
- if (BMP085_read_coeffs() < 0)
- return -1;
-
- plugin_register_read ("barometer", BMP085_collectd_barometer_read);
- }
- break;
-
-/* anything else -> error */
- default:
- ERROR("barometer: collectd_barometer_init - no supported sensor found");
- return -1;
- }
-
-
- configured = 1;
- return 0;
-}
-
-/* ------------------------ plugin register / entry point ------------------------ */
-
-/**
- * Plugin "entry" - register all callback.
- *
- */
-void module_register (void)
-{
- plugin_register_config ("barometer",
- collectd_barometer_config,
- config_keys,
- config_keys_num);
- plugin_register_init ("barometer", collectd_barometer_init);
- plugin_register_shutdown ("barometer", collectd_barometer_shutdown);
-}