Sfoglia il codice sorgente

updated Arduino Code

FloKra 1 anno fa
parent
commit
da759a4d29

+ 87 - 87
HomeServerIOExt_Arduino/Adafruit_Sensor.cpp

@@ -1,87 +1,87 @@
-#include "Adafruit_Sensor.h"
-
-/**************************************************************************/
-/*!
-    @brief  Prints sensor information to serial console
-*/
-/**************************************************************************/
-void Adafruit_Sensor::printSensorDetails(void) {
-  sensor_t sensor;
-  getSensor(&sensor);
-  Serial.println(F("------------------------------------"));
-  Serial.print(F("Sensor:       "));
-  Serial.println(sensor.name);
-  Serial.print(F("Type:         "));
-  switch ((sensors_type_t)sensor.type) {
-  case SENSOR_TYPE_ACCELEROMETER:
-    Serial.print(F("Acceleration (m/s2)"));
-    break;
-  case SENSOR_TYPE_MAGNETIC_FIELD:
-    Serial.print(F("Magnetic (uT)"));
-    break;
-  case SENSOR_TYPE_ORIENTATION:
-    Serial.print(F("Orientation (degrees)"));
-    break;
-  case SENSOR_TYPE_GYROSCOPE:
-    Serial.print(F("Gyroscopic (rad/s)"));
-    break;
-  case SENSOR_TYPE_LIGHT:
-    Serial.print(F("Light (lux)"));
-    break;
-  case SENSOR_TYPE_PRESSURE:
-    Serial.print(F("Pressure (hPa)"));
-    break;
-  case SENSOR_TYPE_PROXIMITY:
-    Serial.print(F("Distance (cm)"));
-    break;
-  case SENSOR_TYPE_GRAVITY:
-    Serial.print(F("Gravity (m/s2)"));
-    break;
-  case SENSOR_TYPE_LINEAR_ACCELERATION:
-    Serial.print(F("Linear Acceleration (m/s2)"));
-    break;
-  case SENSOR_TYPE_ROTATION_VECTOR:
-    Serial.print(F("Rotation vector"));
-    break;
-  case SENSOR_TYPE_RELATIVE_HUMIDITY:
-    Serial.print(F("Relative Humidity (%)"));
-    break;
-  case SENSOR_TYPE_AMBIENT_TEMPERATURE:
-    Serial.print(F("Ambient Temp (C)"));
-    break;
-  case SENSOR_TYPE_OBJECT_TEMPERATURE:
-    Serial.print(F("Object Temp (C)"));
-    break;
-  case SENSOR_TYPE_VOLTAGE:
-    Serial.print(F("Voltage (V)"));
-    break;
-  case SENSOR_TYPE_CURRENT:
-    Serial.print(F("Current (mA)"));
-    break;
-  case SENSOR_TYPE_COLOR:
-    Serial.print(F("Color (RGBA)"));
-    break;
-  case SENSOR_TYPE_TVOC:
-    Serial.print(F("Total Volatile Organic Compounds (ppb)"));
-    break;
-  case SENSOR_TYPE_VOC_INDEX:
-    Serial.print(F("Volatile Organic Compounds (Index)"));
-    break;
-  case SENSOR_TYPE_NOX_INDEX:
-    Serial.print(F("Nitrogen Oxides (Index)"));
-    break;
-  }
-
-  Serial.println();
-  Serial.print(F("Driver Ver:   "));
-  Serial.println(sensor.version);
-  Serial.print(F("Unique ID:    "));
-  Serial.println(sensor.sensor_id);
-  Serial.print(F("Min Value:    "));
-  Serial.println(sensor.min_value);
-  Serial.print(F("Max Value:    "));
-  Serial.println(sensor.max_value);
-  Serial.print(F("Resolution:   "));
-  Serial.println(sensor.resolution);
-  Serial.println(F("------------------------------------\n"));
-}
+#include "Adafruit_Sensor.h"
+
+/**************************************************************************/
+/*!
+    @brief  Prints sensor information to serial console
+*/
+/**************************************************************************/
+void Adafruit_Sensor::printSensorDetails(void) {
+  sensor_t sensor;
+  getSensor(&sensor);
+  Serial.println(F("------------------------------------"));
+  Serial.print(F("Sensor:       "));
+  Serial.println(sensor.name);
+  Serial.print(F("Type:         "));
+  switch ((sensors_type_t)sensor.type) {
+  case SENSOR_TYPE_ACCELEROMETER:
+    Serial.print(F("Acceleration (m/s2)"));
+    break;
+  case SENSOR_TYPE_MAGNETIC_FIELD:
+    Serial.print(F("Magnetic (uT)"));
+    break;
+  case SENSOR_TYPE_ORIENTATION:
+    Serial.print(F("Orientation (degrees)"));
+    break;
+  case SENSOR_TYPE_GYROSCOPE:
+    Serial.print(F("Gyroscopic (rad/s)"));
+    break;
+  case SENSOR_TYPE_LIGHT:
+    Serial.print(F("Light (lux)"));
+    break;
+  case SENSOR_TYPE_PRESSURE:
+    Serial.print(F("Pressure (hPa)"));
+    break;
+  case SENSOR_TYPE_PROXIMITY:
+    Serial.print(F("Distance (cm)"));
+    break;
+  case SENSOR_TYPE_GRAVITY:
+    Serial.print(F("Gravity (m/s2)"));
+    break;
+  case SENSOR_TYPE_LINEAR_ACCELERATION:
+    Serial.print(F("Linear Acceleration (m/s2)"));
+    break;
+  case SENSOR_TYPE_ROTATION_VECTOR:
+    Serial.print(F("Rotation vector"));
+    break;
+  case SENSOR_TYPE_RELATIVE_HUMIDITY:
+    Serial.print(F("Relative Humidity (%)"));
+    break;
+  case SENSOR_TYPE_AMBIENT_TEMPERATURE:
+    Serial.print(F("Ambient Temp (C)"));
+    break;
+  case SENSOR_TYPE_OBJECT_TEMPERATURE:
+    Serial.print(F("Object Temp (C)"));
+    break;
+  case SENSOR_TYPE_VOLTAGE:
+    Serial.print(F("Voltage (V)"));
+    break;
+  case SENSOR_TYPE_CURRENT:
+    Serial.print(F("Current (mA)"));
+    break;
+  case SENSOR_TYPE_COLOR:
+    Serial.print(F("Color (RGBA)"));
+    break;
+  case SENSOR_TYPE_TVOC:
+    Serial.print(F("Total Volatile Organic Compounds (ppb)"));
+    break;
+  case SENSOR_TYPE_VOC_INDEX:
+    Serial.print(F("Volatile Organic Compounds (Index)"));
+    break;
+  case SENSOR_TYPE_NOX_INDEX:
+    Serial.print(F("Nitrogen Oxides (Index)"));
+    break;
+  }
+
+  Serial.println();
+  Serial.print(F("Driver Ver:   "));
+  Serial.println(sensor.version);
+  Serial.print(F("Unique ID:    "));
+  Serial.println(sensor.sensor_id);
+  Serial.print(F("Min Value:    "));
+  Serial.println(sensor.min_value);
+  Serial.print(F("Max Value:    "));
+  Serial.println(sensor.max_value);
+  Serial.print(F("Resolution:   "));
+  Serial.println(sensor.resolution);
+  Serial.println(F("------------------------------------\n"));
+}

+ 196 - 196
HomeServerIOExt_Arduino/Adafruit_Sensor.h

@@ -1,196 +1,196 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software< /span>
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and
- * extended sensor support to include color, voltage and current */
-
-#ifndef _ADAFRUIT_SENSOR_H
-#define _ADAFRUIT_SENSOR_H
-
-#ifndef ARDUINO
-#include <stdint.h>
-#elif ARDUINO >= 100
-#include "Arduino.h"
-#include "Print.h"
-#else
-#include "WProgram.h"
-#endif
-
-/* Constants */
-#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
-#define SENSORS_GRAVITY_MOON (1.6F)      /**< The moon's gravity in m/s^2 */
-#define SENSORS_GRAVITY_SUN (275.0F)     /**< The sun's gravity in m/s^2 */
-#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
-#define SENSORS_MAGFIELD_EARTH_MAX                                             \
-  (60.0F) /**< Maximum magnetic field on Earth's surface */
-#define SENSORS_MAGFIELD_EARTH_MIN                                             \
-  (30.0F) /**< Minimum magnetic field on Earth's surface */
-#define SENSORS_PRESSURE_SEALEVELHPA                                           \
-  (1013.25F) /**< Average sea level pressure is 1013.25 hPa */
-#define SENSORS_DPS_TO_RADS                                                    \
-  (0.017453293F) /**< Degrees/s to rad/s multiplier                            \
-                  */
-#define SENSORS_RADS_TO_DPS                                                    \
-  (57.29577793F) /**< Rad/s to degrees/s  multiplier */
-#define SENSORS_GAUSS_TO_MICROTESLA                                            \
-  (100) /**< Gauss to micro-Tesla multiplier */
-
-/** Sensor types */
-typedef enum {
-  SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
-  SENSOR_TYPE_MAGNETIC_FIELD = (2),
-  SENSOR_TYPE_ORIENTATION = (3),
-  SENSOR_TYPE_GYROSCOPE = (4),
-  SENSOR_TYPE_LIGHT = (5),
-  SENSOR_TYPE_PRESSURE = (6),
-  SENSOR_TYPE_PROXIMITY = (8),
-  SENSOR_TYPE_GRAVITY = (9),
-  SENSOR_TYPE_LINEAR_ACCELERATION =
-      (10), /**< Acceleration not including gravity */
-  SENSOR_TYPE_ROTATION_VECTOR = (11),
-  SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
-  SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
-  SENSOR_TYPE_OBJECT_TEMPERATURE = (14),
-  SENSOR_TYPE_VOLTAGE = (15),
-  SENSOR_TYPE_CURRENT = (16),
-  SENSOR_TYPE_COLOR = (17),
-  SENSOR_TYPE_TVOC = (18),
-  SENSOR_TYPE_VOC_INDEX = (19),
-  SENSOR_TYPE_NOX_INDEX = (20)
-} sensors_type_t;
-
-/** struct sensors_vec_s is used to return a vector in a common format. */
-typedef struct {
-  union {
-    float v[3]; ///< 3D vector elements
-    struct {
-      float x; ///< X component of vector
-      float y; ///< Y component of vector
-      float z; ///< Z component of vector
-    };         ///< Struct for holding XYZ component
-    /* Orientation sensors */
-    struct {
-      float roll; /**< Rotation around the longitudinal axis (the plane body, 'X
-                     axis'). Roll is positive and increasing when moving
-                     downward. -90 degrees <= roll <= 90 degrees */
-      float pitch;   /**< Rotation around the lateral axis (the wing span, 'Y
-                        axis'). Pitch is positive and increasing when moving
-                        upwards. -180 degrees <= pitch <= 180 degrees) */
-      float heading; /**< Angle between the longitudinal axis (the plane body)
-                        and magnetic north, measured clockwise when viewing from
-                        the top of the device. 0-359 degrees */
-    };               ///< Struct for holding roll/pitch/heading
-  };                 ///< Union that can hold 3D vector array, XYZ components or
-                     ///< roll/pitch/heading
-  int8_t status;     ///< Status byte
-  uint8_t reserved[3]; ///< Reserved
-} sensors_vec_t;
-
-/** struct sensors_color_s is used to return color data in a common format. */
-typedef struct {
-  union {
-    float c[3]; ///< Raw 3-element data
-    /* RGB color space */
-    struct {
-      float r;   /**< Red component */
-      float g;   /**< Green component */
-      float b;   /**< Blue component */
-    };           ///< RGB data in floating point notation
-  };             ///< Union of various ways to describe RGB colorspace
-  uint32_t rgba; /**< 24-bit RGBA value */
-} sensors_color_t;
-
-/* Sensor event (36 bytes) */
-/** struct sensor_event_s is used to provide a single sensor event in a common
- * format. */
-typedef struct {
-  int32_t version;   /**< must be sizeof(struct sensors_event_t) */
-  int32_t sensor_id; /**< unique sensor identifier */
-  int32_t type;      /**< sensor type */
-  int32_t reserved0; /**< reserved */
-  int32_t timestamp; /**< time is in milliseconds */
-  union {
-    float data[4];              ///< Raw data
-    sensors_vec_t acceleration; /**< acceleration values are in meter per second
-                                   per second (m/s^2) */
-    sensors_vec_t
-        magnetic; /**< magnetic vector values are in micro-Tesla (uT) */
-    sensors_vec_t orientation; /**< orientation values are in degrees */
-    sensors_vec_t gyro;        /**< gyroscope values are in rad/s */
-    float temperature; /**< temperature is in degrees centigrade (Celsius) */
-    float distance;    /**< distance in centimeters */
-    float light;       /**< light in SI lux units */
-    float pressure;    /**< pressure in hectopascal (hPa) */
-    float relative_humidity; /**< relative humidity in percent */
-    float current;           /**< current in milliamps (mA) */
-    float voltage;           /**< voltage in volts (V) */
-    float tvoc;              /**< Total Volatile Organic Compounds, in ppb */
-    float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is
-                          normal (unitless) */
-    float nox_index; /**< NOx (Nitrogen Oxides) index where 100 is normal
-                          (unitless) */
-    sensors_color_t color; /**< color in RGB component values */
-  };                       ///< Union for the wide ranges of data we can carry
-} sensors_event_t;
-
-/* Sensor details (40 bytes) */
-/** struct sensor_s is used to describe basic information about a specific
- * sensor. */
-typedef struct {
-  char name[12];     /**< sensor name */
-  int32_t version;   /**< version of the hardware + driver */
-  int32_t sensor_id; /**< unique sensor identifier */
-  int32_t type;      /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
-  float max_value;   /**< maximum value of this sensor's value in SI units */
-  float min_value;   /**< minimum value of this sensor's value in SI units */
-  float resolution; /**< smallest difference between two values reported by this
-                       sensor */
-  int32_t min_delay; /**< min delay in microseconds between events. zero = not a
-                        constant rate */
-} sensor_t;
-
-/** @brief Common sensor interface to unify various sensors.
- * Intentionally modeled after sensors.h in the Android API:
- * https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h
- */
-class Adafruit_Sensor {
-public:
-  // Constructor(s)
-  Adafruit_Sensor() {}
-  virtual ~Adafruit_Sensor() {}
-
-  // These must be defined by the subclass
-
-  /*! @brief Whether we should automatically change the range (if possible) for
-     higher precision
-      @param enabled True if we will try to autorange */
-  virtual void enableAutoRange(bool enabled) {
-    (void)enabled; /* suppress unused warning */
-  };
-
-  /*! @brief Get the latest sensor event
-      @returns True if able to fetch an event */
-  virtual bool getEvent(sensors_event_t *) = 0;
-  /*! @brief Get info about the sensor itself */
-  virtual void getSensor(sensor_t *) = 0;
-
-  void printSensorDetails(void);
-
-private:
-  bool _autoRange;
-};
-
-#endif
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software< /span>
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and
+ * extended sensor support to include color, voltage and current */
+
+#ifndef _ADAFRUIT_SENSOR_H
+#define _ADAFRUIT_SENSOR_H
+
+#ifndef ARDUINO
+#include <stdint.h>
+#elif ARDUINO >= 100
+#include "Arduino.h"
+#include "Print.h"
+#else
+#include "WProgram.h"
+#endif
+
+/* Constants */
+#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
+#define SENSORS_GRAVITY_MOON (1.6F)      /**< The moon's gravity in m/s^2 */
+#define SENSORS_GRAVITY_SUN (275.0F)     /**< The sun's gravity in m/s^2 */
+#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
+#define SENSORS_MAGFIELD_EARTH_MAX                                             \
+  (60.0F) /**< Maximum magnetic field on Earth's surface */
+#define SENSORS_MAGFIELD_EARTH_MIN                                             \
+  (30.0F) /**< Minimum magnetic field on Earth's surface */
+#define SENSORS_PRESSURE_SEALEVELHPA                                           \
+  (1013.25F) /**< Average sea level pressure is 1013.25 hPa */
+#define SENSORS_DPS_TO_RADS                                                    \
+  (0.017453293F) /**< Degrees/s to rad/s multiplier                            \
+                  */
+#define SENSORS_RADS_TO_DPS                                                    \
+  (57.29577793F) /**< Rad/s to degrees/s  multiplier */
+#define SENSORS_GAUSS_TO_MICROTESLA                                            \
+  (100) /**< Gauss to micro-Tesla multiplier */
+
+/** Sensor types */
+typedef enum {
+  SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
+  SENSOR_TYPE_MAGNETIC_FIELD = (2),
+  SENSOR_TYPE_ORIENTATION = (3),
+  SENSOR_TYPE_GYROSCOPE = (4),
+  SENSOR_TYPE_LIGHT = (5),
+  SENSOR_TYPE_PRESSURE = (6),
+  SENSOR_TYPE_PROXIMITY = (8),
+  SENSOR_TYPE_GRAVITY = (9),
+  SENSOR_TYPE_LINEAR_ACCELERATION =
+      (10), /**< Acceleration not including gravity */
+  SENSOR_TYPE_ROTATION_VECTOR = (11),
+  SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
+  SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
+  SENSOR_TYPE_OBJECT_TEMPERATURE = (14),
+  SENSOR_TYPE_VOLTAGE = (15),
+  SENSOR_TYPE_CURRENT = (16),
+  SENSOR_TYPE_COLOR = (17),
+  SENSOR_TYPE_TVOC = (18),
+  SENSOR_TYPE_VOC_INDEX = (19),
+  SENSOR_TYPE_NOX_INDEX = (20)
+} sensors_type_t;
+
+/** struct sensors_vec_s is used to return a vector in a common format. */
+typedef struct {
+  union {
+    float v[3]; ///< 3D vector elements
+    struct {
+      float x; ///< X component of vector
+      float y; ///< Y component of vector
+      float z; ///< Z component of vector
+    };         ///< Struct for holding XYZ component
+    /* Orientation sensors */
+    struct {
+      float roll; /**< Rotation around the longitudinal axis (the plane body, 'X
+                     axis'). Roll is positive and increasing when moving
+                     downward. -90 degrees <= roll <= 90 degrees */
+      float pitch;   /**< Rotation around the lateral axis (the wing span, 'Y
+                        axis'). Pitch is positive and increasing when moving
+                        upwards. -180 degrees <= pitch <= 180 degrees) */
+      float heading; /**< Angle between the longitudinal axis (the plane body)
+                        and magnetic north, measured clockwise when viewing from
+                        the top of the device. 0-359 degrees */
+    };               ///< Struct for holding roll/pitch/heading
+  };                 ///< Union that can hold 3D vector array, XYZ components or
+                     ///< roll/pitch/heading
+  int8_t status;     ///< Status byte
+  uint8_t reserved[3]; ///< Reserved
+} sensors_vec_t;
+
+/** struct sensors_color_s is used to return color data in a common format. */
+typedef struct {
+  union {
+    float c[3]; ///< Raw 3-element data
+    /* RGB color space */
+    struct {
+      float r;   /**< Red component */
+      float g;   /**< Green component */
+      float b;   /**< Blue component */
+    };           ///< RGB data in floating point notation
+  };             ///< Union of various ways to describe RGB colorspace
+  uint32_t rgba; /**< 24-bit RGBA value */
+} sensors_color_t;
+
+/* Sensor event (36 bytes) */
+/** struct sensor_event_s is used to provide a single sensor event in a common
+ * format. */
+typedef struct {
+  int32_t version;   /**< must be sizeof(struct sensors_event_t) */
+  int32_t sensor_id; /**< unique sensor identifier */
+  int32_t type;      /**< sensor type */
+  int32_t reserved0; /**< reserved */
+  int32_t timestamp; /**< time is in milliseconds */
+  union {
+    float data[4];              ///< Raw data
+    sensors_vec_t acceleration; /**< acceleration values are in meter per second
+                                   per second (m/s^2) */
+    sensors_vec_t
+        magnetic; /**< magnetic vector values are in micro-Tesla (uT) */
+    sensors_vec_t orientation; /**< orientation values are in degrees */
+    sensors_vec_t gyro;        /**< gyroscope values are in rad/s */
+    float temperature; /**< temperature is in degrees centigrade (Celsius) */
+    float distance;    /**< distance in centimeters */
+    float light;       /**< light in SI lux units */
+    float pressure;    /**< pressure in hectopascal (hPa) */
+    float relative_humidity; /**< relative humidity in percent */
+    float current;           /**< current in milliamps (mA) */
+    float voltage;           /**< voltage in volts (V) */
+    float tvoc;              /**< Total Volatile Organic Compounds, in ppb */
+    float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is
+                          normal (unitless) */
+    float nox_index; /**< NOx (Nitrogen Oxides) index where 100 is normal
+                          (unitless) */
+    sensors_color_t color; /**< color in RGB component values */
+  };                       ///< Union for the wide ranges of data we can carry
+} sensors_event_t;
+
+/* Sensor details (40 bytes) */
+/** struct sensor_s is used to describe basic information about a specific
+ * sensor. */
+typedef struct {
+  char name[12];     /**< sensor name */
+  int32_t version;   /**< version of the hardware + driver */
+  int32_t sensor_id; /**< unique sensor identifier */
+  int32_t type;      /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
+  float max_value;   /**< maximum value of this sensor's value in SI units */
+  float min_value;   /**< minimum value of this sensor's value in SI units */
+  float resolution; /**< smallest difference between two values reported by this
+                       sensor */
+  int32_t min_delay; /**< min delay in microseconds between events. zero = not a
+                        constant rate */
+} sensor_t;
+
+/** @brief Common sensor interface to unify various sensors.
+ * Intentionally modeled after sensors.h in the Android API:
+ * https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h
+ */
+class Adafruit_Sensor {
+public:
+  // Constructor(s)
+  Adafruit_Sensor() {}
+  virtual ~Adafruit_Sensor() {}
+
+  // These must be defined by the subclass
+
+  /*! @brief Whether we should automatically change the range (if possible) for
+     higher precision
+      @param enabled True if we will try to autorange */
+  virtual void enableAutoRange(bool enabled) {
+    (void)enabled; /* suppress unused warning */
+  };
+
+  /*! @brief Get the latest sensor event
+      @returns True if able to fetch an event */
+  virtual bool getEvent(sensors_event_t *) = 0;
+  /*! @brief Get info about the sensor itself */
+  virtual void getSensor(sensor_t *) = 0;
+
+  void printSensorDetails(void);
+
+private:
+  bool _autoRange;
+};
+
+#endif

+ 390 - 390
HomeServerIOExt_Arduino/DHT.cpp

@@ -1,390 +1,390 @@
-/*!
- *  @file DHT.cpp
- *
- *  @mainpage DHT series of low cost temperature/humidity sensors.
- *
- *  @section intro_sec Introduction
- *
- *  This is a library for DHT series of low cost temperature/humidity sensors.
- *
- *  You must have Adafruit Unified Sensor Library library installed to use this
- * class.
- *
- *  Adafruit invests time and resources providing this open source code,
- *  please support Adafruit andopen-source hardware by purchasing products
- *  from Adafruit!
- *
- *  @section author Author
- *
- *  Written by Adafruit Industries.
- *
- *  @section license License
- *
- *  MIT license, all text above must be included in any redistribution
- */
-
-#include "DHT.h"
-
-#define MIN_INTERVAL 2000 /**< min interval value */
-#define TIMEOUT                                                                \
-  UINT32_MAX /**< Used programmatically for timeout.                           \
-                   Not a timeout duration. Type: uint32_t. */
-
-/*!
- *  @brief  Instantiates a new DHT class
- *  @param  pin
- *          pin number that sensor is connected
- *  @param  type
- *          type of sensor
- *  @param  count
- *          number of sensors
- */
-DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
-  (void)count; // Workaround to avoid compiler warning.
-  _pin = pin;
-  _type = type;
-#ifdef __AVR
-  _bit = digitalPinToBitMask(pin);
-  _port = digitalPinToPort(pin);
-#endif
-  _maxcycles =
-      microsecondsToClockCycles(1000); // 1 millisecond timeout for
-                                       // reading pulses from DHT sensor.
-  // Note that count is now ignored as the DHT reading algorithm adjusts itself
-  // based on the speed of the processor.
-}
-
-/*!
- *  @brief  Setup sensor pins and set pull timings
- *  @param  usec
- *          Optionally pass pull-up time (in microseconds) before DHT reading
- *starts. Default is 55 (see function declaration in DHT.h).
- */
-void DHT::begin(uint8_t usec) {
-  // set up the pins!
-  pinMode(_pin, INPUT_PULLUP);
-  // Using this value makes sure that millis() - lastreadtime will be
-  // >= MIN_INTERVAL right away. Note that this assignment wraps around,
-  // but so will the subtraction.
-  _lastreadtime = millis() - MIN_INTERVAL;
-  DEBUG_PRINT("DHT max clock cycles: ");
-  DEBUG_PRINTLN(_maxcycles, DEC);
-  pullTime = usec;
-}
-
-/*!
- *  @brief  Read temperature
- *  @param  S
- *          Scale. Boolean value:
- *					- true = Fahrenheit
- *					- false = Celcius
- *  @param  force
- *          true if in force mode
- *	@return Temperature value in selected scale
- */
-float DHT::readTemperature(bool S, bool force) {
-  float f = NAN;
-
-  if (read(force)) {
-    switch (_type) {
-    case DHT11:
-      f = data[2];
-      if (data[3] & 0x80) {
-        f = -1 - f;
-      }
-      f += (data[3] & 0x0f) * 0.1;
-      if (S) {
-        f = convertCtoF(f);
-      }
-      break;
-    case DHT12:
-      f = data[2];
-      f += (data[3] & 0x0f) * 0.1;
-      if (data[2] & 0x80) {
-        f *= -1;
-      }
-      if (S) {
-        f = convertCtoF(f);
-      }
-      break;
-    case DHT22:
-    case DHT21:
-      f = ((word)(data[2] & 0x7F)) << 8 | data[3];
-      f *= 0.1;
-      if (data[2] & 0x80) {
-        f *= -1;
-      }
-      if (S) {
-        f = convertCtoF(f);
-      }
-      break;
-    }
-  }
-  return f;
-}
-
-/*!
- *  @brief  Converts Celcius to Fahrenheit
- *  @param  c
- *					value in Celcius
- *	@return float value in Fahrenheit
- */
-float DHT::convertCtoF(float c) { return c * 1.8 + 32; }
-
-/*!
- *  @brief  Converts Fahrenheit to Celcius
- *  @param  f
- *					value in Fahrenheit
- *	@return float value in Celcius
- */
-float DHT::convertFtoC(float f) { return (f - 32) * 0.55555; }
-
-/*!
- *  @brief  Read Humidity
- *  @param  force
- *					force read mode
- *	@return float value - humidity in percent
- */
-float DHT::readHumidity(bool force) {
-  float f = NAN;
-  if (read(force)) {
-    switch (_type) {
-    case DHT11:
-    case DHT12:
-      f = data[0] + data[1] * 0.1;
-      break;
-    case DHT22:
-    case DHT21:
-      f = ((word)data[0]) << 8 | data[1];
-      f *= 0.1;
-      break;
-    }
-  }
-  return f;
-}
-
-/*!
- *  @brief  Compute Heat Index
- *          Simplified version that reads temp and humidity from sensor
- *  @param  isFahrenheit
- * 					true if fahrenheit, false if celcius
- *(default true)
- *	@return float heat index
- */
-float DHT::computeHeatIndex(bool isFahrenheit) {
-  float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(),
-                              isFahrenheit);
-  return hi;
-}
-
-/*!
- *  @brief  Compute Heat Index
- *  				Using both Rothfusz and Steadman's equations
- *					(http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml)
- *  @param  temperature
- *          temperature in selected scale
- *  @param  percentHumidity
- *          humidity in percent
- *  @param  isFahrenheit
- * 					true if fahrenheit, false if celcius
- *	@return float heat index
- */
-float DHT::computeHeatIndex(float temperature, float percentHumidity,
-                            bool isFahrenheit) {
-  float hi;
-
-  if (!isFahrenheit)
-    temperature = convertCtoF(temperature);
-
-  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) +
-              (percentHumidity * 0.094));
-
-  if (hi > 79) {
-    hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity +
-         -0.22475541 * temperature * percentHumidity +
-         -0.00683783 * pow(temperature, 2) +
-         -0.05481717 * pow(percentHumidity, 2) +
-         0.00122874 * pow(temperature, 2) * percentHumidity +
-         0.00085282 * temperature * pow(percentHumidity, 2) +
-         -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);
-
-    if ((percentHumidity < 13) && (temperature >= 80.0) &&
-        (temperature <= 112.0))
-      hi -= ((13.0 - percentHumidity) * 0.25) *
-            sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
-
-    else if ((percentHumidity > 85.0) && (temperature >= 80.0) &&
-             (temperature <= 87.0))
-      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
-  }
-
-  return isFahrenheit ? hi : convertFtoC(hi);
-}
-
-/*!
- *  @brief  Read value from sensor or return last one from less than two
- *seconds.
- *  @param  force
- *          true if using force mode
- *	@return float value
- */
-bool DHT::read(bool force) {
-  // Check if sensor was read less than two seconds ago and return early
-  // to use last reading.
-  uint32_t currenttime = millis();
-  if (!force && ((currenttime - _lastreadtime) < MIN_INTERVAL)) {
-    return _lastresult; // return last correct measurement
-  }
-  _lastreadtime = currenttime;
-
-  // Reset 40 bits of received data to zero.
-  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
-
-#if defined(ESP8266)
-  yield(); // Handle WiFi / reset software watchdog
-#endif
-
-  // Send start signal.  See DHT datasheet for full signal diagram:
-  //   http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
-
-  // Go into high impedence state to let pull-up raise data line level and
-  // start the reading process.
-  pinMode(_pin, INPUT_PULLUP);
-  delay(1);
-
-  // First set data line low for a period according to sensor type
-  pinMode(_pin, OUTPUT);
-  digitalWrite(_pin, LOW);
-  switch (_type) {
-  case DHT22:
-  case DHT21:
-    delayMicroseconds(1100); // data sheet says "at least 1ms"
-    break;
-  case DHT11:
-  default:
-    delay(20); // data sheet says at least 18ms, 20ms just to be safe
-    break;
-  }
-
-  uint32_t cycles[80];
-  {
-    // End the start signal by setting data line high for 40 microseconds.
-    pinMode(_pin, INPUT_PULLUP);
-
-    // Delay a moment to let sensor pull data line low.
-    delayMicroseconds(pullTime);
-
-    // Now start reading the data line to get the value from the DHT sensor.
-
-    // Turn off interrupts temporarily because the next sections
-    // are timing critical and we don't want any interruptions.
-    InterruptLock lock;
-
-    // First expect a low signal for ~80 microseconds followed by a high signal
-    // for ~80 microseconds again.
-    if (expectPulse(LOW) == TIMEOUT) {
-      DEBUG_PRINTLN(F("DHT timeout waiting for start signal low pulse."));
-      _lastresult = false;
-      return _lastresult;
-    }
-    if (expectPulse(HIGH) == TIMEOUT) {
-      DEBUG_PRINTLN(F("DHT timeout waiting for start signal high pulse."));
-      _lastresult = false;
-      return _lastresult;
-    }
-
-    // Now read the 40 bits sent by the sensor.  Each bit is sent as a 50
-    // microsecond low pulse followed by a variable length high pulse.  If the
-    // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
-    // then it's a 1.  We measure the cycle count of the initial 50us low pulse
-    // and use that to compare to the cycle count of the high pulse to determine
-    // if the bit is a 0 (high state cycle count < low state cycle count), or a
-    // 1 (high state cycle count > low state cycle count). Note that for speed
-    // all the pulses are read into a array and then examined in a later step.
-    for (int i = 0; i < 80; i += 2) {
-      cycles[i] = expectPulse(LOW);
-      cycles[i + 1] = expectPulse(HIGH);
-    }
-  } // Timing critical code is now complete.
-
-  // Inspect pulses and determine which ones are 0 (high state cycle count < low
-  // state cycle count), or 1 (high state cycle count > low state cycle count).
-  for (int i = 0; i < 40; ++i) {
-    uint32_t lowCycles = cycles[2 * i];
-    uint32_t highCycles = cycles[2 * i + 1];
-    if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) {
-      DEBUG_PRINTLN(F("DHT timeout waiting for pulse."));
-      _lastresult = false;
-      return _lastresult;
-    }
-    data[i / 8] <<= 1;
-    // Now compare the low and high cycle times to see if the bit is a 0 or 1.
-    if (highCycles > lowCycles) {
-      // High cycles are greater than 50us low cycle count, must be a 1.
-      data[i / 8] |= 1;
-    }
-    // Else high cycles are less than (or equal to, a weird case) the 50us low
-    // cycle count so this must be a zero.  Nothing needs to be changed in the
-    // stored data.
-  }
-
-  DEBUG_PRINTLN(F("Received from DHT:"));
-  DEBUG_PRINT(data[0], HEX);
-  DEBUG_PRINT(F(", "));
-  DEBUG_PRINT(data[1], HEX);
-  DEBUG_PRINT(F(", "));
-  DEBUG_PRINT(data[2], HEX);
-  DEBUG_PRINT(F(", "));
-  DEBUG_PRINT(data[3], HEX);
-  DEBUG_PRINT(F(", "));
-  DEBUG_PRINT(data[4], HEX);
-  DEBUG_PRINT(F(" =? "));
-  DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX);
-
-  // Check we read 40 bits and that the checksum matches.
-  if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
-    _lastresult = true;
-    return _lastresult;
-  } else {
-    DEBUG_PRINTLN(F("DHT checksum failure!"));
-    _lastresult = false;
-    return _lastresult;
-  }
-}
-
-// Expect the signal line to be at the specified level for a period of time and
-// return a count of loop cycles spent at that level (this cycle count can be
-// used to compare the relative time of two pulses).  If more than a millisecond
-// ellapses without the level changing then the call fails with a 0 response.
-// This is adapted from Arduino's pulseInLong function (which is only available
-// in the very latest IDE versions):
-//   https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
-uint32_t DHT::expectPulse(bool level) {
-// F_CPU is not be known at compile time on platforms such as STM32F103.
-// The preprocessor seems to evaluate it to zero in that case.
-#if (F_CPU > 16000000L) || (F_CPU == 0L)
-  uint32_t count = 0;
-#else
-  uint16_t count = 0; // To work fast enough on slower AVR boards
-#endif
-// On AVR platforms use direct GPIO port access as it's much faster and better
-// for catching pulses that are 10's of microseconds in length:
-#ifdef __AVR
-  uint8_t portState = level ? _bit : 0;
-  while ((*portInputRegister(_port) & _bit) == portState) {
-    if (count++ >= _maxcycles) {
-      return TIMEOUT; // Exceeded timeout, fail.
-    }
-  }
-// Otherwise fall back to using digitalRead (this seems to be necessary on
-// ESP8266 right now, perhaps bugs in direct port access functions?).
-#else
-  while (digitalRead(_pin) == level) {
-    if (count++ >= _maxcycles) {
-      return TIMEOUT; // Exceeded timeout, fail.
-    }
-  }
-#endif
-
-  return count;
-}
+/*!
+ *  @file DHT.cpp
+ *
+ *  @mainpage DHT series of low cost temperature/humidity sensors.
+ *
+ *  @section intro_sec Introduction
+ *
+ *  This is a library for DHT series of low cost temperature/humidity sensors.
+ *
+ *  You must have Adafruit Unified Sensor Library library installed to use this
+ * class.
+ *
+ *  Adafruit invests time and resources providing this open source code,
+ *  please support Adafruit andopen-source hardware by purchasing products
+ *  from Adafruit!
+ *
+ *  @section author Author
+ *
+ *  Written by Adafruit Industries.
+ *
+ *  @section license License
+ *
+ *  MIT license, all text above must be included in any redistribution
+ */
+
+#include "DHT.h"
+
+#define MIN_INTERVAL 2000 /**< min interval value */
+#define TIMEOUT                                                                \
+  UINT32_MAX /**< Used programmatically for timeout.                           \
+                   Not a timeout duration. Type: uint32_t. */
+
+/*!
+ *  @brief  Instantiates a new DHT class
+ *  @param  pin
+ *          pin number that sensor is connected
+ *  @param  type
+ *          type of sensor
+ *  @param  count
+ *          number of sensors
+ */
+DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
+  (void)count; // Workaround to avoid compiler warning.
+  _pin = pin;
+  _type = type;
+#ifdef __AVR
+  _bit = digitalPinToBitMask(pin);
+  _port = digitalPinToPort(pin);
+#endif
+  _maxcycles =
+      microsecondsToClockCycles(1000); // 1 millisecond timeout for
+                                       // reading pulses from DHT sensor.
+  // Note that count is now ignored as the DHT reading algorithm adjusts itself
+  // based on the speed of the processor.
+}
+
+/*!
+ *  @brief  Setup sensor pins and set pull timings
+ *  @param  usec
+ *          Optionally pass pull-up time (in microseconds) before DHT reading
+ *starts. Default is 55 (see function declaration in DHT.h).
+ */
+void DHT::begin(uint8_t usec) {
+  // set up the pins!
+  pinMode(_pin, INPUT_PULLUP);
+  // Using this value makes sure that millis() - lastreadtime will be
+  // >= MIN_INTERVAL right away. Note that this assignment wraps around,
+  // but so will the subtraction.
+  _lastreadtime = millis() - MIN_INTERVAL;
+  DEBUG_PRINT("DHT max clock cycles: ");
+  DEBUG_PRINTLN(_maxcycles, DEC);
+  pullTime = usec;
+}
+
+/*!
+ *  @brief  Read temperature
+ *  @param  S
+ *          Scale. Boolean value:
+ *					- true = Fahrenheit
+ *					- false = Celcius
+ *  @param  force
+ *          true if in force mode
+ *	@return Temperature value in selected scale
+ */
+float DHT::readTemperature(bool S, bool force) {
+  float f = NAN;
+
+  if (read(force)) {
+    switch (_type) {
+    case DHT11:
+      f = data[2];
+      if (data[3] & 0x80) {
+        f = -1 - f;
+      }
+      f += (data[3] & 0x0f) * 0.1;
+      if (S) {
+        f = convertCtoF(f);
+      }
+      break;
+    case DHT12:
+      f = data[2];
+      f += (data[3] & 0x0f) * 0.1;
+      if (data[2] & 0x80) {
+        f *= -1;
+      }
+      if (S) {
+        f = convertCtoF(f);
+      }
+      break;
+    case DHT22:
+    case DHT21:
+      f = ((word)(data[2] & 0x7F)) << 8 | data[3];
+      f *= 0.1;
+      if (data[2] & 0x80) {
+        f *= -1;
+      }
+      if (S) {
+        f = convertCtoF(f);
+      }
+      break;
+    }
+  }
+  return f;
+}
+
+/*!
+ *  @brief  Converts Celcius to Fahrenheit
+ *  @param  c
+ *					value in Celcius
+ *	@return float value in Fahrenheit
+ */
+float DHT::convertCtoF(float c) { return c * 1.8 + 32; }
+
+/*!
+ *  @brief  Converts Fahrenheit to Celcius
+ *  @param  f
+ *					value in Fahrenheit
+ *	@return float value in Celcius
+ */
+float DHT::convertFtoC(float f) { return (f - 32) * 0.55555; }
+
+/*!
+ *  @brief  Read Humidity
+ *  @param  force
+ *					force read mode
+ *	@return float value - humidity in percent
+ */
+float DHT::readHumidity(bool force) {
+  float f = NAN;
+  if (read(force)) {
+    switch (_type) {
+    case DHT11:
+    case DHT12:
+      f = data[0] + data[1] * 0.1;
+      break;
+    case DHT22:
+    case DHT21:
+      f = ((word)data[0]) << 8 | data[1];
+      f *= 0.1;
+      break;
+    }
+  }
+  return f;
+}
+
+/*!
+ *  @brief  Compute Heat Index
+ *          Simplified version that reads temp and humidity from sensor
+ *  @param  isFahrenheit
+ * 					true if fahrenheit, false if celcius
+ *(default true)
+ *	@return float heat index
+ */
+float DHT::computeHeatIndex(bool isFahrenheit) {
+  float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(),
+                              isFahrenheit);
+  return hi;
+}
+
+/*!
+ *  @brief  Compute Heat Index
+ *  				Using both Rothfusz and Steadman's equations
+ *					(http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml)
+ *  @param  temperature
+ *          temperature in selected scale
+ *  @param  percentHumidity
+ *          humidity in percent
+ *  @param  isFahrenheit
+ * 					true if fahrenheit, false if celcius
+ *	@return float heat index
+ */
+float DHT::computeHeatIndex(float temperature, float percentHumidity,
+                            bool isFahrenheit) {
+  float hi;
+
+  if (!isFahrenheit)
+    temperature = convertCtoF(temperature);
+
+  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) +
+              (percentHumidity * 0.094));
+
+  if (hi > 79) {
+    hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity +
+         -0.22475541 * temperature * percentHumidity +
+         -0.00683783 * pow(temperature, 2) +
+         -0.05481717 * pow(percentHumidity, 2) +
+         0.00122874 * pow(temperature, 2) * percentHumidity +
+         0.00085282 * temperature * pow(percentHumidity, 2) +
+         -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);
+
+    if ((percentHumidity < 13) && (temperature >= 80.0) &&
+        (temperature <= 112.0))
+      hi -= ((13.0 - percentHumidity) * 0.25) *
+            sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
+
+    else if ((percentHumidity > 85.0) && (temperature >= 80.0) &&
+             (temperature <= 87.0))
+      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
+  }
+
+  return isFahrenheit ? hi : convertFtoC(hi);
+}
+
+/*!
+ *  @brief  Read value from sensor or return last one from less than two
+ *seconds.
+ *  @param  force
+ *          true if using force mode
+ *	@return float value
+ */
+bool DHT::read(bool force) {
+  // Check if sensor was read less than two seconds ago and return early
+  // to use last reading.
+  uint32_t currenttime = millis();
+  if (!force && ((currenttime - _lastreadtime) < MIN_INTERVAL)) {
+    return _lastresult; // return last correct measurement
+  }
+  _lastreadtime = currenttime;
+
+  // Reset 40 bits of received data to zero.
+  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
+
+#if defined(ESP8266)
+  yield(); // Handle WiFi / reset software watchdog
+#endif
+
+  // Send start signal.  See DHT datasheet for full signal diagram:
+  //   http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
+
+  // Go into high impedence state to let pull-up raise data line level and
+  // start the reading process.
+  pinMode(_pin, INPUT_PULLUP);
+  delay(1);
+
+  // First set data line low for a period according to sensor type
+  pinMode(_pin, OUTPUT);
+  digitalWrite(_pin, LOW);
+  switch (_type) {
+  case DHT22:
+  case DHT21:
+    delayMicroseconds(1100); // data sheet says "at least 1ms"
+    break;
+  case DHT11:
+  default:
+    delay(20); // data sheet says at least 18ms, 20ms just to be safe
+    break;
+  }
+
+  uint32_t cycles[80];
+  {
+    // End the start signal by setting data line high for 40 microseconds.
+    pinMode(_pin, INPUT_PULLUP);
+
+    // Delay a moment to let sensor pull data line low.
+    delayMicroseconds(pullTime);
+
+    // Now start reading the data line to get the value from the DHT sensor.
+
+    // Turn off interrupts temporarily because the next sections
+    // are timing critical and we don't want any interruptions.
+    InterruptLock lock;
+
+    // First expect a low signal for ~80 microseconds followed by a high signal
+    // for ~80 microseconds again.
+    if (expectPulse(LOW) == TIMEOUT) {
+      DEBUG_PRINTLN(F("DHT timeout waiting for start signal low pulse."));
+      _lastresult = false;
+      return _lastresult;
+    }
+    if (expectPulse(HIGH) == TIMEOUT) {
+      DEBUG_PRINTLN(F("DHT timeout waiting for start signal high pulse."));
+      _lastresult = false;
+      return _lastresult;
+    }
+
+    // Now read the 40 bits sent by the sensor.  Each bit is sent as a 50
+    // microsecond low pulse followed by a variable length high pulse.  If the
+    // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
+    // then it's a 1.  We measure the cycle count of the initial 50us low pulse
+    // and use that to compare to the cycle count of the high pulse to determine
+    // if the bit is a 0 (high state cycle count < low state cycle count), or a
+    // 1 (high state cycle count > low state cycle count). Note that for speed
+    // all the pulses are read into a array and then examined in a later step.
+    for (int i = 0; i < 80; i += 2) {
+      cycles[i] = expectPulse(LOW);
+      cycles[i + 1] = expectPulse(HIGH);
+    }
+  } // Timing critical code is now complete.
+
+  // Inspect pulses and determine which ones are 0 (high state cycle count < low
+  // state cycle count), or 1 (high state cycle count > low state cycle count).
+  for (int i = 0; i < 40; ++i) {
+    uint32_t lowCycles = cycles[2 * i];
+    uint32_t highCycles = cycles[2 * i + 1];
+    if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) {
+      DEBUG_PRINTLN(F("DHT timeout waiting for pulse."));
+      _lastresult = false;
+      return _lastresult;
+    }
+    data[i / 8] <<= 1;
+    // Now compare the low and high cycle times to see if the bit is a 0 or 1.
+    if (highCycles > lowCycles) {
+      // High cycles are greater than 50us low cycle count, must be a 1.
+      data[i / 8] |= 1;
+    }
+    // Else high cycles are less than (or equal to, a weird case) the 50us low
+    // cycle count so this must be a zero.  Nothing needs to be changed in the
+    // stored data.
+  }
+
+  DEBUG_PRINTLN(F("Received from DHT:"));
+  DEBUG_PRINT(data[0], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[1], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[2], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[3], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[4], HEX);
+  DEBUG_PRINT(F(" =? "));
+  DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX);
+
+  // Check we read 40 bits and that the checksum matches.
+  if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
+    _lastresult = true;
+    return _lastresult;
+  } else {
+    DEBUG_PRINTLN(F("DHT checksum failure!"));
+    _lastresult = false;
+    return _lastresult;
+  }
+}
+
+// Expect the signal line to be at the specified level for a period of time and
+// return a count of loop cycles spent at that level (this cycle count can be
+// used to compare the relative time of two pulses).  If more than a millisecond
+// ellapses without the level changing then the call fails with a 0 response.
+// This is adapted from Arduino's pulseInLong function (which is only available
+// in the very latest IDE versions):
+//   https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
+uint32_t DHT::expectPulse(bool level) {
+// F_CPU is not be known at compile time on platforms such as STM32F103.
+// The preprocessor seems to evaluate it to zero in that case.
+#if (F_CPU > 16000000L) || (F_CPU == 0L)
+  uint32_t count = 0;
+#else
+  uint16_t count = 0; // To work fast enough on slower AVR boards
+#endif
+// On AVR platforms use direct GPIO port access as it's much faster and better
+// for catching pulses that are 10's of microseconds in length:
+#ifdef __AVR
+  uint8_t portState = level ? _bit : 0;
+  while ((*portInputRegister(_port) & _bit) == portState) {
+    if (count++ >= _maxcycles) {
+      return TIMEOUT; // Exceeded timeout, fail.
+    }
+  }
+// Otherwise fall back to using digitalRead (this seems to be necessary on
+// ESP8266 right now, perhaps bugs in direct port access functions?).
+#else
+  while (digitalRead(_pin) == level) {
+    if (count++ >= _maxcycles) {
+      return TIMEOUT; // Exceeded timeout, fail.
+    }
+  }
+#endif
+
+  return count;
+}

+ 109 - 109
HomeServerIOExt_Arduino/DHT.h

@@ -1,109 +1,109 @@
-/*!
- *  @file DHT.h
- *
- *  This is a library for DHT series of low cost temperature/humidity sensors.
- *
- *  You must have Adafruit Unified Sensor Library library installed to use this
- * class.
- *
- *  Adafruit invests time and resources providing this open source code,
- *  please support Adafruit andopen-source hardware by purchasing products
- *  from Adafruit!
- *
- *  Written by Adafruit Industries.
- *
- *  MIT license, all text above must be included in any redistribution
- */
-
-#ifndef DHT_H
-#define DHT_H
-
-#include "Arduino.h"
-
-/* Uncomment to enable printing out nice debug messages. */
-//#define DHT_DEBUG
-
-#define DEBUG_PRINTER                                                          \
-  Serial /**< Define where debug output will be printed.                       \
-          */
-
-/* Setup debug printing macros. */
-#ifdef DHT_DEBUG
-#define DEBUG_PRINT(...)                                                       \
-  { DEBUG_PRINTER.print(__VA_ARGS__); }
-#define DEBUG_PRINTLN(...)                                                     \
-  { DEBUG_PRINTER.println(__VA_ARGS__); }
-#else
-#define DEBUG_PRINT(...)                                                       \
-  {} /**< Debug Print Placeholder if Debug is disabled */
-#define DEBUG_PRINTLN(...)                                                     \
-  {} /**< Debug Print Line Placeholder if Debug is disabled */
-#endif
-
-/* Define types of sensors. */
-static const uint8_t DHT11{11};  /**< DHT TYPE 11 */
-static const uint8_t DHT12{12};  /**< DHY TYPE 12 */
-static const uint8_t DHT21{21};  /**< DHT TYPE 21 */
-static const uint8_t DHT22{22};  /**< DHT TYPE 22 */
-static const uint8_t AM2301{21}; /**< AM2301 */
-
-#if defined(TARGET_NAME) && (TARGET_NAME == ARDUINO_NANO33BLE)
-#ifndef microsecondsToClockCycles
-/*!
- * As of 7 Sep 2020 the Arduino Nano 33 BLE boards do not have
- * microsecondsToClockCycles defined.
- */
-#define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L))
-#endif
-#endif
-
-/*!
- *  @brief  Class that stores state and functions for DHT
- */
-class DHT {
-public:
-  DHT(uint8_t pin, uint8_t type, uint8_t count = 6);
-  void begin(uint8_t usec = 55);
-  float readTemperature(bool S = false, bool force = false);
-  float convertCtoF(float);
-  float convertFtoC(float);
-  float computeHeatIndex(bool isFahrenheit = true);
-  float computeHeatIndex(float temperature, float percentHumidity,
-                         bool isFahrenheit = true);
-  float readHumidity(bool force = false);
-  bool read(bool force = false);
-
-private:
-  uint8_t data[5];
-  uint8_t _pin, _type;
-#ifdef __AVR
-  // Use direct GPIO access on an 8-bit AVR so keep track of the port and
-  // bitmask for the digital pin connected to the DHT.  Other platforms will use
-  // digitalRead.
-  uint8_t _bit, _port;
-#endif
-  uint32_t _lastreadtime, _maxcycles;
-  bool _lastresult;
-  uint8_t pullTime; // Time (in usec) to pull up data line before reading
-
-  uint32_t expectPulse(bool level);
-};
-
-/*!
- *  @brief  Class that defines Interrupt Lock Avaiability
- */
-class InterruptLock {
-public:
-  InterruptLock() {
-#if !defined(ARDUINO_ARCH_NRF52)
-    noInterrupts();
-#endif
-  }
-  ~InterruptLock() {
-#if !defined(ARDUINO_ARCH_NRF52)
-    interrupts();
-#endif
-  }
-};
-
-#endif
+/*!
+ *  @file DHT.h
+ *
+ *  This is a library for DHT series of low cost temperature/humidity sensors.
+ *
+ *  You must have Adafruit Unified Sensor Library library installed to use this
+ * class.
+ *
+ *  Adafruit invests time and resources providing this open source code,
+ *  please support Adafruit andopen-source hardware by purchasing products
+ *  from Adafruit!
+ *
+ *  Written by Adafruit Industries.
+ *
+ *  MIT license, all text above must be included in any redistribution
+ */
+
+#ifndef DHT_H
+#define DHT_H
+
+#include "Arduino.h"
+
+/* Uncomment to enable printing out nice debug messages. */
+//#define DHT_DEBUG
+
+#define DEBUG_PRINTER                                                          \
+  Serial /**< Define where debug output will be printed.                       \
+          */
+
+/* Setup debug printing macros. */
+#ifdef DHT_DEBUG
+#define DEBUG_PRINT(...)                                                       \
+  { DEBUG_PRINTER.print(__VA_ARGS__); }
+#define DEBUG_PRINTLN(...)                                                     \
+  { DEBUG_PRINTER.println(__VA_ARGS__); }
+#else
+#define DEBUG_PRINT(...)                                                       \
+  {} /**< Debug Print Placeholder if Debug is disabled */
+#define DEBUG_PRINTLN(...)                                                     \
+  {} /**< Debug Print Line Placeholder if Debug is disabled */
+#endif
+
+/* Define types of sensors. */
+static const uint8_t DHT11{11};  /**< DHT TYPE 11 */
+static const uint8_t DHT12{12};  /**< DHY TYPE 12 */
+static const uint8_t DHT21{21};  /**< DHT TYPE 21 */
+static const uint8_t DHT22{22};  /**< DHT TYPE 22 */
+static const uint8_t AM2301{21}; /**< AM2301 */
+
+#if defined(TARGET_NAME) && (TARGET_NAME == ARDUINO_NANO33BLE)
+#ifndef microsecondsToClockCycles
+/*!
+ * As of 7 Sep 2020 the Arduino Nano 33 BLE boards do not have
+ * microsecondsToClockCycles defined.
+ */
+#define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L))
+#endif
+#endif
+
+/*!
+ *  @brief  Class that stores state and functions for DHT
+ */
+class DHT {
+public:
+  DHT(uint8_t pin, uint8_t type, uint8_t count = 6);
+  void begin(uint8_t usec = 55);
+  float readTemperature(bool S = false, bool force = false);
+  float convertCtoF(float);
+  float convertFtoC(float);
+  float computeHeatIndex(bool isFahrenheit = true);
+  float computeHeatIndex(float temperature, float percentHumidity,
+                         bool isFahrenheit = true);
+  float readHumidity(bool force = false);
+  bool read(bool force = false);
+
+private:
+  uint8_t data[5];
+  uint8_t _pin, _type;
+#ifdef __AVR
+  // Use direct GPIO access on an 8-bit AVR so keep track of the port and
+  // bitmask for the digital pin connected to the DHT.  Other platforms will use
+  // digitalRead.
+  uint8_t _bit, _port;
+#endif
+  uint32_t _lastreadtime, _maxcycles;
+  bool _lastresult;
+  uint8_t pullTime; // Time (in usec) to pull up data line before reading
+
+  uint32_t expectPulse(bool level);
+};
+
+/*!
+ *  @brief  Class that defines Interrupt Lock Avaiability
+ */
+class InterruptLock {
+public:
+  InterruptLock() {
+#if !defined(ARDUINO_ARCH_NRF52)
+    noInterrupts();
+#endif
+  }
+  ~InterruptLock() {
+#if !defined(ARDUINO_ARCH_NRF52)
+    interrupts();
+#endif
+  }
+};
+
+#endif

+ 2 - 2
HomeServerIOExt_Arduino/HomeServerIOExt_Arduino.ino

@@ -2,7 +2,7 @@
 #define INTERVAL 60000
 
 // define how many input pins should be used
-#define IN_PINS 3
+#define IN_PINS 4
 // which pin number to start at (default = 2)
 #define START_AT_PIN 2
 // 
@@ -44,7 +44,7 @@ bool state_pin_pending[IN_PINS];
 unsigned long lastPinChange[IN_PINS];
 
 void setup() {
-  Serial.begin(57600);
+  Serial.begin(115200);
   Serial.print(F("HomeServerIOExt v"));
   Serial.println("0.1");
 

+ 182 - 184
HomeServerIOExt_Arduino/HomeServerIOExt_Arduino.ino.eightanaloginputs.hex

@@ -15,14 +15,14 @@
 :1000E00002020303030303030102040810204080FB
 :1000F0000102040810200102040810204205112406
 :100100001FBECFEFD8E0DEBFCDBF11E0A0E0B1E071
-:10011000E4EDF4E102C005900D92A832B107D9F7E1
-:1001200021E0A8E2B1E001C01D92A73FB207E1F7CC
-:1001300010E0CFE7D0E004C02197FE010E94620AE0
-:10014000CE37D107C9F70E948F050C94680A0C942A
+:10011000E2EBF4E102C005900D92A832B107D9F7E5
+:1001200021E0A8E2B1E001C01D92AD3FB207E1F7C6
+:1001300010E0CFE7D0E004C02197FE010E94510AF1
+:10014000CE37D107C9F70E948F050C94570A0C943B
 :100150000000CF92DF92EF92FF92CF93DF93B091A6
-:10016000EB01A0E08111AB2F8091EC0190E0880FB2
-:10017000991FAC0146535F4FC090F101D090F2013E
-:10018000E090F301F090F40130E020E0FA01C59135
+:10016000F101A0E08111AB2F8091F20190E0880FA6
+:10017000991FAC0146535F4FC090F701D090F80132
+:10018000E090F901F090FA0130E020E0FA01C59129
 :10019000D491E881B90190E080E0EB23EA130AC032
 :1001A0002F5F3F4F6C157D058E059F0578F36FEF30
 :1001B0007FEFCB01DF91CF91FF90EF90DF90CF9059
@@ -39,7 +39,7 @@
 :100260000895FC01918D828D981731F0828DE80FF1
 :10027000F11D858D90E008958FEF9FEF0895FC01AB
 :10028000918D228D892F90E0805C9F4F821B910978
-:100290008F739927089587E491E00E943F0121E040
+:100290008F73992708958DE491E00E943F0121E03A
 :1002A000892B09F420E0822F089580E090E0892BCB
 :1002B00029F00E944B0181110C9400000895FC016B
 :1002C000A48DA80FB92FB11DA35ABF4F2C91848DB7
@@ -57,7 +57,7 @@
 :10038000EC0FFD2FF11DE35AFF4FF0829FB7F89459
 :100390000B8FEA89FB8980818062CFCF0F931F93F7
 :1003A000CF93DF938C01D0E0C0E0F801EC0FFD1F8C
-:1003B0006491662341F087E491E00E948101892BDA
+:1003B0006491662341F08DE491E00E948101892BD4
 :1003C00011F02196F2CFCE01DF91CF911F910F91C5
 :1003D0000895CF93DF93EC01888D8823B9F0AA8923
 :1003E000BB89E889F9898C9185FD03C0808186FDF0
@@ -94,26 +94,26 @@
 :1005D0002A0180912B0190912C012FBF08958F92B9
 :1005E0009F92AF92BF92CF92DF92EF92FF920F93C2
 :1005F0001F93CF93DF93CDB7DEB7C054D1400FB672
-:10060000F894DEBF0FBECDBF0E94E3020091ED0162
-:100610001091EE012091EF013091F0016B017C010E
+:10060000F894DEBF0FBECDBF0E94E3020091F3015C
+:100610001091F4012091F5013091F6016B017C01FC
 :10062000C01AD10AE20AF30A97018601003D174079
-:1006300021053105B0F48091F501C05CDE4F0FB6A5
+:1006300021053105B0F48091FB01C05CDE4F0FB69F
 :10064000F894DEBF0FBECDBFDF91CF911F910F9108
 :10065000FF90EF90DF90CF90BF90AF909F908F90E2
-:1006600008956093ED017093EE018093EF019093F4
-:10067000F0011092E8011092E7011092E601109249
-:10068000E5011092E40162E08091E9010E945B02C1
+:1006600008956093F3017093F4018093F5019093E2
+:10067000F6011092EE011092ED011092EC01109231
+:10068000EB011092EA0162E08091EF010E945B02AF
 :1006900061E070E080E090E00E94B10261E0809152
-:1006A000E9010E945B022091E90130E0F901EA547E
+:1006A000EF010E945B022091EF0130E0F901EA5472
 :1006B000FF4F8491F901E851FF4F0491F901EC5289
 :1006C000FF4F1491112391F081110E940902E12F33
 :1006D000F0E0EE0FFF1FE455FF4FA591B4918FB7E7
-:1006E000F894EC9100950E230C938FBF8091EA0152
+:1006E000F894EC9100950E230C938FBF8091F0014C
 :1006F0008551823020F58BE291E10197F1F762E0BC
-:100700008091E9010E945B028091F60190E08230C5
+:100700008091EF010E945B028091FC0190E08230B9
 :10071000910538F0880F991F880F991F0597019749
 :10072000F1F7F89480E00E94A9006F3F7F4F8F4F50
-:100730009F4F61F41092F501789480E07ECF64E1E0
+:100730009F4F61F41092FB01789480E07ECF64E1DA
 :1007400070E080E090E00E94B102D9CF81E00E9489
 :10075000A9006F3F7F4F8F4F9F4F61F3CE010196EE
 :100760007C015E019FEBA91A9EEFB90A870180E028
@@ -122,19 +122,19 @@
 :100790001F4FA016B10659F7789430E020E0F7011A
 :1007A00080809180A280B380448155816681778169
 :1007B000FFEF8F169F06AF06BF0631F04F3F8FEF5A
-:1007C00058076807780719F41092F501B6CFF901B8
-:1007D00083E0F595E7958A95E1F7EC51FE4F80812E
+:1007C00058076807780719F41092FB01B6CFF901B2
+:1007D00083E0F595E7958A95E1F7E651FE4F808134
 :1007E000880F84169506A606B70618F180832F5F3A
 :1007F0003F4F98E0E90EF11C2832310581F6409117
-:10080000E8012091E4018091E501280F3327331F8F
-:100810008091E601280F311D8091E701820F932F0F
-:10082000911D99274817190679F681E08093F50103
+:10080000EE012091EA018091EB01280F3327331F7D
+:100810008091EC01280F311D8091ED01820F932F03
+:10082000911D99274817190679F681E08093FB01FD
 :1008300004CF8160DBCFFC0101900020E9F7319704
-:10084000AF01481B590BBC0187E491E00C94E10017
+:10084000AF01481B590BBC018DE491E00C94E10011
 :100850008F929F92AF92BF920F931F93CF93DF938C
 :10086000CDB7DEB7A1970FB6F894DEBF0FBECDBFF0
 :1008700019A2423008F44AE08E010F5D1F4F842E0A
-:10088000912CB12CA12CA50194010E94400AE62FC5
+:10088000912CB12CA12CA50194010E942F0AE62FD6
 :10089000B901CA01EA30F4F4E05DD801EE938D01AC
 :1008A000232B242B252B79F790E080E0109719F06B
 :1008B000CD010E941B04A1960FB6F894DEBF0FBEB7
@@ -148,14 +148,14 @@
 :1009300080E090E0CF910C94B10289E191E0F4CF96
 :100940001F920F920FB60F9211242F933F934F9344
 :100950005F936F937F938F939F93AF93BF93EF9327
-:10096000FF9387E491E00E945F01FF91EF91BF91B7
+:10096000FF938DE491E00E945F01FF91EF91BF91B1
 :10097000AF919F918F917F916F915F914F913F9137
 :100980002F910F900FBE0F901F9018951F920F92EE
 :100990000FB60F9211242F938F939F93EF93FF9392
-:1009A000E0915701F09158018081E0915D01F09153
-:1009B0005E0182FD1BC09081809160018F5F8F730B
-:1009C00020916101821741F0E0916001F0E0E95B64
-:1009D000FE4F958F80936001FF91EF919F918F91D2
+:1009A000E0915D01F0915E018081E0916301F09141
+:1009B000640182FD1BC09081809166018F5F8F73FF
+:1009C00020916701821741F0E0916601F0E0E35B5E
+:1009D000FE4F958F80936601FF91EF919F918F91CC
 :1009E0002F910F900FBE0F901F9018958081F4CF1C
 :1009F0001F920F920FB60F9211242F933F938F9354
 :100A00009F93AF93BF938091290190912A01A09168
@@ -166,12 +166,12 @@
 :100A5000B11D80932D0190932E01A0932F01B0938F
 :100A60003001BF91AF919F918F913F912F910F9046
 :100A70000FBE0F901F90189526E8230F0296A11D18
-:100A8000B11DD2CFE7E4F1E01382128288EE93E049
+:100A8000B11DD2CFEDE4F1E01382128288EE93E043
 :100A9000A0E0B0E084839583A683B78384E091E0EF
 :100AA0009183808385EC90E09587848784EC90E047
 :100AB0009787868780EC90E0918B808B81EC90E02B
 :100AC000938B828B82EC90E0958B848B86EC90E00C
-:100AD000978B868B118E128E138E148EA4EEB1E03E
+:100AD000978B868B118E128E138E148EAAEEB1E038
 :100AE00081E115968C93159786E116968C9316974F
 :100AF000E9EFF0E0E4911796EC931797E5EEF0E05C
 :100B0000E4911896EC93189740E85EE360E070E09B
@@ -184,155 +184,153 @@
 :100B7000B00081608093B00080917A00846080939F
 :100B80007A0080917A00826080937A0080917A0066
 :100B9000816080937A0080917A00806880937A00E7
-:100BA0001092C100E0915701F091580182E08083DA
-:100BB000E0915701F09158011082E0915301F091BA
-:100BC00054011082E0915501F091560180E180833B
-:100BD00010925F01E0915B01F0915C0186E08083FF
-:100BE000E0915901F0915A01808180618083E09108
-:100BF0005901F0915A01808188608083E091590108
-:100C0000F0915A01808180688083E0915901F091D0
-:100C10005A0180818F7D808384E790E00E94CE011D
-:100C20008BE191E00E946C0462E082E00E945B0232
-:100C300062E083E00E945B0262E084E00E945B026B
-:100C400082E00E94320221E0892B09F420E0209307
-:100C5000310183E00E94320221E0892B09F420E077
-:100C60002093320184E00E94320221E0892B09F4B2
-:100C700020E02093330162E08091E9010E945B0251
-:100C80000E94E302605D7740810991096093ED0164
-:100C90007093EE018093EF019093F00187E38093CE
-:100CA000F601C0E0D0E030E4A32E31E0B32E41E302
-:100CB000C42E41E0D42E54E3E52E51E0F52E12E08F
-:100CC000812F0E94320201E0892B09F400E0F50136
-:100CD00081915F01081751F00E94E302F7016083E0
-:100CE000718382839383F50131970083F6018081BC
-:100CF0000817E1F00E94E302F70140805180628012
-:100D0000738064197509860997096B3F7105810520
-:100D1000910560F0F60100830E94E302F701608311
-:100D2000718382839383812F0E947A041F5FFFEF78
-:100D3000CF1ADF0A24E0E20EF11C153009F60E94FA
-:100D4000E30200914301109144012091450130914B
-:100D50004601601B710B820B930B61367A4E810545
-:100D6000910508F4C6C00E94E302609343017093AA
-:100D70004401809345019093460182E00E947A04E9
-:100D800083E00E947A0484E00E947A040E94EF02C9
-:100D9000882349F08091EA018B3028F08D3050F0A3
-:100DA00085518230C8F1812C912C20ECA22E2FE7A6
-:100DB000B22E1EC06091E50170E090E080E00E94DC
-:100DC00019092DEC3CEC4CEC5DE30E94CE096B0163
-:100DD0007C016091E40170E090E080E00E941909DC
-:100DE0009B01AC01C701B6010E9470084B015C0178
-:100DF0000E94EF02882309F474C08091EA018C30CC
-:100E000009F482C0D8F48B3091F1C12CD12C80EC44
-:100E1000E82E8FE7F82E55C06091E4017091E5014E
-:100E200076276727762790E080E00E9417092DEC4F
-:100E30003CEC4CEC5DE30E94CE09D8CF855182306A
-:100E400020F71091E601612F70E0762F6627662764
-:100E50007F778091E701682B90E080E00E9417097E
-:100E60002DEC3CEC4CEC5DE30E94CE0969C0609136
-:100E7000E60170E090E080E00E9417096B017C01C0
-:100E80001091E70117FF0AC0AC019B0160E070E020
-:100E900080E89FEB0E946F086B017C011F70612F3F
-:100EA00070E090E080E00E9419092DEC3CEC4CECE5
-:100EB0005DE30E94CE09A70196010E9470086B01B4
-:100EC0007C01A5019401C501B4010E943B0A811176
-:100ED00008C0A7019601C701B6010E943B0A8823FA
-:100EE000C1F184E990E00E94CE0182E191E00E948C
-:100EF0001B04209709F4D7CE0E944B01882309F4E4
-:100F0000D2CE0E940000CFCE1091E601612F70E09A
-:100F100090E080E00E9417096B017C016091E7017D
-:100F20006F7070E090E080E00E9419092DEC3CECBD
-:100F30004CEC5DE30E94CE09A70196010E94700867
-:100F40006B017C0117FFBDCFF7FAF094F7F8F0942E
-:100F5000B8CF8EE890E00E94CE0126013701E894D8
-:100F600077F82FEF3FEF4FE75FE7C301B2010E9431
-:100F70003B0A81113DC02FEF3FEF4FE75FE7C30111
-:100F8000B2010E94DC0818169CF58FE191E00E94E6
-:100F90001B0488E890E00E94CE01C501B4010E94C4
-:100FA000E1086B01770FEE08FF084AE0C701B601C0
-:100FB000F7FE0DC06DE287E491E00E948101662793
-:100FC0007727CB016C197D098E099F094AE00E94A1
-:100FD000280486E890E00E94CE0182E191E00E9420
-:100FE0001B0465E070E080E090E00E94B10281CFD8
-:100FF0002FEF3FEF4FE75FE4C701B6010E94C90939
-:1010000018161CF483E291E0C2CF2FEF3FEF4FE7B9
-:101010005FECC701B6010E94DC0887FDF3CF20E03A
-:1010200030E0A901C701B6010E94DC0887FF09C0B2
-:101030006DE287E491E00E948101F7FAF094F7F8FD
-:10104000F0942AE037ED43EA5BE3C701B6010E9462
-:1010500070082B013C010E94E8086B017C010E9492
-:1010600017099B01AC01C301B2010E946F082B015B
-:101070003C014AE0C701B6010E9428046EE287E401
-:1010800091E00E94810120E030E040E251E4C301A0
-:10109000B2010E94CE092B013C010E94E8086B01BD
-:1010A000F12CE12C4AE0C701B6010E942804C701D7
-:1010B000B6010E9417099B01AC01C301B2010E9455
-:1010C0006F0820E030E040E251E40E94CE090E9427
-:1010D000E80890E080E04AE00E9428045ACF505887
-:1010E000BB27AA270E9487080C948F090E948109B8
-:1010F00038F00E94880920F039F49F3F19F426F453
-:101100000C947E090EF4E095E7FB0C947809E92F26
-:101110000E94A00958F3BA1762077307840795075E
-:1011200020F079F4A6F50C94C2090EF4E0950B2E8C
-:10113000BA2FA02D0B01B90190010C01CA01A00129
-:101140001124FF27591B99F0593F50F4503E68F184
-:101150001A16F040A22F232F342F4427585FF3CFC5
-:10116000469537952795A795F0405395C9F77EF496
-:101170001F16BA0B620B730B840BBAF09150A1F0DF
-:10118000FF0FBB1F661F771F881FC2F70EC0BA0F65
-:10119000621F731F841F48F4879577956795B795ED
-:1011A000F7959E3F08F0B0CF9395880F08F09927E8
-:1011B000EE0F9795879508950E94540908F481E0F1
-:1011C00008950E94E8086894B1110C94C309089529
-:1011D0000E94A80988F09F5798F0B92F9927B75116
-:1011E000B0F0E1F0660F771F881F991F1AF0BA95CB
-:1011F000C9F714C0B13091F00E94C209B1E008955E
-:101200000C94C209672F782F8827B85F39F0B93F4F
-:10121000CCF3869577956795B395D9F73EF490957D
-:101220008095709561957F4F8F4F9F4F0895E894FB
-:1012300009C097FB3EF490958095709561957F4F1E
-:101240008F4F9F4F9923A9F0F92F96E9BB279395CC
-:10125000F695879577956795B795F111F8CFFAF4DC
-:10126000BB0F11F460FF1BC06F5F7F4F8F4F9F4F0D
-:1012700016C0882311F096E911C0772321F09EE86B
-:10128000872F762F05C0662371F096E8862F70E0D1
-:1012900060E02AF09A95660F771F881FDAF7880FAB
-:1012A0009695879597F90895990F0008550FAA0B01
-:1012B000E0E8FEEF16161706E807F907C0F0121669
-:1012C0001306E407F50798F0621B730B840B950B6C
-:1012D00039F40A2661F0232B242B252B21F40895C1
-:1012E0000A2609F4A140A6958FEF811D811D08955E
-:1012F00097F99F6780E870E060E008959FEF80ECC9
-:10130000089500240A94161617061806090608956B
-:1013100000240A9412161306140605060895092ED1
-:101320000394000C11F4882352F0BB0F40F4BF2B40
-:1013300011F460FF04C06F5F7F4F8F4F9F4F089580
-:1013400057FD9058440F551F59F05F3F71F0479576
-:10135000880F97FB991F61F09F3F79F0879508955B
-:10136000121613061406551FF2CF4695F1DF08C07A
-:10137000161617061806991FF1CF86957105610597
-:1013800008940895E894BB2766277727CB0197F93F
-:1013900008950E94540908F48FEF08950E94E1090E
-:1013A0000C948F090E94810938F00E94880920F06E
-:1013B000952311F00C9478090C947E0911240C9457
-:1013C000C3090E94A00970F3959FC1F3950F50E0E7
-:1013D000551F629FF001729FBB27F00DB11D639FE7
-:1013E000AA27F00DB11DAA1F649F6627B00DA11D8D
-:1013F000661F829F2227B00DA11D621F739FB00D33
-:10140000A11D621F839FA00D611D221F749F3327A2
-:10141000A00D611D231F849F600D211D822F762F3B
-:101420006A2F11249F5750409AF0F1F088234AF018
-:10143000EE0FFF1FBB1F661F771F881F9150504084
-:10144000A9F79E3F510580F00C9478090C94C309CC
-:101450005F3FE4F3983ED4F3869577956795B7950B
-:10146000F795E7959F5FC1F7FE2B880F911D969525
-:10147000879597F908950E945409880B990B089550
-:10148000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F88
-:10149000EE1FFF1FA217B307E407F50720F0A21BFA
-:1014A000B30BE40BF50B661F771F881F991F1A9467
-:1014B00069F760957095809590959B01AC01BD0191
-:1014C000CF010895EE0FFF1F0590F491E02D0994D0
-:0414D000F894FFCFBE
-:1014D400000000008101E1000E01E9013F011D014E
-:1014E40031010D0A003D0048004C00302E310069E6
-:0814F4006E66006F76660000D1
+:100BA0001092C100E0915D01F0915E0182E08083CE
+:100BB000E0915901F0915A011082E0915B01F091AE
+:100BC0005C0180E1808310926501E0916101F09108
+:100BD000620186E08083E0915F01F0916001808195
+:100BE00080618083E0915F01F09160018081886085
+:100BF0008083E0915F01F091600180818068808353
+:100C0000E0915F01F091600180818F7D808384E7B6
+:100C100090E00E94CE018BE191E00E946C04C2E062
+:100C200062E08C2F0E945B02CF5FC630C9F701E300
+:100C300011E0C2E08C2F0E94320221E0892B09F4DE
+:100C400020E0F80121938F01CF5FC63099F762E071
+:100C50008091EF010E945B020E94E302605D774099
+:100C6000810991096093F3017093F4018093F50178
+:100C70009093F60187E38093FC01C0E0D0E035E477
+:100C8000A32E31E0B32E45E3E42E41E0F42E51E3F0
+:100C9000C52E51E0D52E12E0812F0E94320201E0D4
+:100CA000892B09F400E0F50181915F01081751F0EB
+:100CB0000E94E302F7016083718382839383F501CD
+:100CC00031970083F60180810817E1F00E94E3026A
+:100CD000F70140805180628073806419750986092C
+:100CE00097096B3F71058105910560F0F60100835E
+:100CF0000E94E302F7016083718382839383812FD3
+:100D00000E947A041F5FFFEFCF1ADF0A24E0E20E91
+:100D1000F11C163009F60E94E3020091490110917E
+:100D20004A0120914B0130914C01601B710B820BE9
+:100D3000930B61367A4E8105910508F4C9C00E9473
+:100D4000E3026093490170934A0180934B019093B1
+:100D50004C0182E00E947A0483E00E947A0484E0DD
+:100D60000E947A0485E00E947A040E94EF028823A0
+:100D700049F08091F0018B3028F08D3050F0855192
+:100D80008230C8F1812C912C20ECA22E2FE7B22EBC
+:100D90001EC06091EB0170E090E080E00E940809C5
+:100DA0002DEC3CEC4CEC5DE30E94BD096B017C0139
+:100DB0006091EA0170E090E080E00E9408099B01E8
+:100DC000AC01C701B6010E945F084B015C010E94A3
+:100DD000EF02882309F474C08091F0018C3009F48B
+:100DE00082C0D8F48B3091F1C12CD12C80ECE82E4C
+:100DF0008FE7F82E55C06091EA017091EB017627DC
+:100E00006727762790E080E00E9406092DEC3CECF5
+:100E10004CEC5DE30E94BD09D8CF8551823020F7AC
+:100E20001091EC01612F70E0762F662766277F779F
+:100E30008091ED01682B90E080E00E9406092DEC86
+:100E40003CEC4CEC5DE30E94BD0969C06091EC0193
+:100E500070E090E080E00E9406096B017C01109137
+:100E6000ED0117FF0AC0AC019B0160E070E080E873
+:100E70009FEB0E945E086B017C011F70612F70E088
+:100E800090E080E00E9408092DEC3CEC4CEC5DE326
+:100E90000E94BD09A70196010E945F086B017C01B9
+:100EA000A5019401C501B4010E942A0A811108C05C
+:100EB000A7019601C701B6010E942A0A8823C1F141
+:100EC00084E990E00E94CE0182E191E00E941B043F
+:100ED000209709F4D4CE0E944B01882309F4CFCE89
+:100EE0000E940000CCCE1091EC01612F70E090E0E8
+:100EF00080E00E9406096B017C016091ED016F703A
+:100F000070E090E080E00E9408092DEC3CEC4CEC95
+:100F10005DE30E94BD09A70196010E945F086B0175
+:100F20007C0117FFBDCFF7FAF094F7F8F094B8CF33
+:100F30008EE890E00E94CE0126013701E89477F810
+:100F40002FEF3FEF4FE75FE7C301B2010E942A0A8C
+:100F500081113DC02FEF3FEF4FE75FE7C301B201C3
+:100F60000E94CB0818169CF58FE191E00E941B04AB
+:100F700088E890E00E94CE01C501B4010E94D0082B
+:100F80006B01770FEE08FF084AE0C701B601F7FED4
+:100F90000DC06DE28DE491E00E9481016627772704
+:100FA000CB016C197D098E099F094AE00E94280433
+:100FB00086E890E00E94CE0182E191E00E941B044D
+:100FC00065E070E080E090E00E94B10281CF2FEFF9
+:100FD0003FEF4FE75FE4C701B6010E94B80918165A
+:100FE0001CF483E291E0C2CF2FEF3FEF4FE75FECBD
+:100FF000C701B6010E94CB0887FDF3CF20E030E0A7
+:10100000A901C701B6010E94CB0887FF09C06DE2A4
+:101010008DE491E00E948101F7FAF094F7F8F094E2
+:101020002AE037ED43EA5BE3C701B6010E945F089F
+:101030002B013C010E94D7086B017C010E9406092C
+:101040009B01AC01C301B2010E945E082B013C016F
+:101050004AE0C701B6010E9428046EE28DE491E0E7
+:101060000E94810120E030E040E251E4C301B2017E
+:101070000E94BD092B013C010E94D7086B01F12C95
+:10108000E12C4AE0C701B6010E942804C701B6015D
+:101090000E9406099B01AC01C301B2010E945E08D7
+:1010A00020E030E040E251E40E94BD090E94D708F0
+:1010B00090E080E04AE00E9428045ACF5058BB27B5
+:1010C000AA270E9476080C947E090E94700938F0C5
+:1010D0000E94770920F039F49F3F19F426F40C940C
+:1010E0006D090EF4E095E7FB0C946709E92F0E9467
+:1010F0008F0958F3BA17620773078407950720F022
+:1011000079F4A6F50C94B1090EF4E0950B2EBA2FE4
+:10111000A02D0B01B90190010C01CA01A0011124FD
+:10112000FF27591B99F0593F50F4503E68F11A16A9
+:10113000F040A22F232F342F4427585FF3CF46953A
+:1011400037952795A795F0405395C9F77EF41F165C
+:10115000BA0B620B730B840BBAF09150A1F0FF0F26
+:10116000BB1F661F771F881FC2F70EC0BA0F621F12
+:10117000731F841F48F4879577956795B795F79502
+:101180009E3F08F0B0CF9395880F08F09927EE0F97
+:101190009795879508950E94430908F481E0089582
+:1011A0000E94D7086894B1110C94B20908950E9466
+:1011B000970988F09F5798F0B92F9927B751B0F049
+:1011C000E1F0660F771F881F991F1AF0BA95C9F7CB
+:1011D00014C0B13091F00E94B109B1E008950C94AF
+:1011E000B109672F782F8827B85F39F0B93FCCF362
+:1011F000869577956795B395D9F73EF49095809548
+:10120000709561957F4F8F4F9F4F0895E89409C067
+:1012100097FB3EF490958095709561957F4F8F4F29
+:101220009F4F9923A9F0F92F96E9BB279395F6953F
+:10123000879577956795B795F111F8CFFAF4BB0FBD
+:1012400011F460FF1BC06F5F7F4F8F4F9F4F16C021
+:10125000882311F096E911C0772321F09EE8872FAB
+:10126000762F05C0662371F096E8862F70E060E067
+:101270002AF09A95660F771F881FDAF7880F9695E0
+:10128000879597F90895990F0008550FAA0BE0E884
+:10129000FEEF16161706E807F907C0F01216130638
+:1012A000E407F50798F0621B730B840B950B39F478
+:1012B0000A2661F0232B242B252B21F408950A26DE
+:1012C00009F4A140A6958FEF811D811D089597F91E
+:1012D0009F6780E870E060E008959FEF80EC0895DC
+:1012E00000240A9416161706180609060895002405
+:1012F0000A9412161306140605060895092E03947F
+:10130000000C11F4882352F0BB0F40F4BF2B11F4F2
+:1013100060FF04C06F5F7F4F8F4F9F4F089557FD51
+:101320009058440F551F59F05F3F71F04795880F53
+:1013300097FB991F61F09F3F79F0879508951216EA
+:1013400013061406551FF2CF4695F1DF08C0161696
+:1013500017061806991FF1CF869571056105089447
+:101360000895E894BB2766277727CB0197F908955E
+:101370000E94430908F48FEF08950E94D0090C944D
+:101380007E090E94700938F00E94770920F09523A9
+:1013900011F00C9467090C946D0911240C94B20996
+:1013A0000E948F0970F3959FC1F3950F50E0551F70
+:1013B000629FF001729FBB27F00DB11D639FAA27AA
+:1013C000F00DB11DAA1F649F6627B00DA11D661FF9
+:1013D000829F2227B00DA11D621F739FB00DA11D1A
+:1013E000621F839FA00D611D221F749F3327A00DD4
+:1013F000611D231F849F600D211D822F762F6A2F70
+:1014000011249F5750409AF0F1F088234AF0EE0FD4
+:10141000FF1FBB1F661F771F881F91505040A9F701
+:101420009E3F510580F00C9467090C94B2095F3F10
+:10143000E4F3983ED4F3869577956795B795F7953D
+:10144000E7959F5FC1F7FE2B880F911D96958795B5
+:1014500097F908950E944309880B990B0895A1E21A
+:101460001A2EAA1BBB1BFD010DC0AA1FBB1FEE1F1E
+:10147000FF1FA217B307E407F50720F0A21BB30B69
+:10148000E40BF50B661F771F881F991F1A9469F7E5
+:1014900060957095809590959B01AC01BD01CF0141
+:1014A0000895EE0FFF1F0590F491E02D0994F89434
+:0214B000FFCF6C
+:1014B200000000008101E1000E01E9013F011D0170
+:1014C20031010D0A003D0048004C00302E31006908
+:0814D2006E66006F76660000F3
 :00000001FF

+ 181 - 183
HomeServerIOExt_Arduino/HomeServerIOExt_Arduino.ino.with_bootloader.eightanaloginputs.hex

@@ -16,14 +16,14 @@
 :1000E00002020303030303030102040810204080FB
 :1000F0000102040810200102040810204205112406
 :100100001FBECFEFD8E0DEBFCDBF11E0A0E0B1E071
-:10011000E4EDF4E102C005900D92A832B107D9F7E1
-:1001200021E0A8E2B1E001C01D92A73FB207E1F7CC
-:1001300010E0CFE7D0E004C02197FE010E94620AE0
-:10014000CE37D107C9F70E948F050C94680A0C942A
+:10011000E2EBF4E102C005900D92A832B107D9F7E5
+:1001200021E0A8E2B1E001C01D92AD3FB207E1F7C6
+:1001300010E0CFE7D0E004C02197FE010E94510AF1
+:10014000CE37D107C9F70E948F050C94570A0C943B
 :100150000000CF92DF92EF92FF92CF93DF93B091A6
-:10016000EB01A0E08111AB2F8091EC0190E0880FB2
-:10017000991FAC0146535F4FC090F101D090F2013E
-:10018000E090F301F090F40130E020E0FA01C59135
+:10016000F101A0E08111AB2F8091F20190E0880FA6
+:10017000991FAC0146535F4FC090F701D090F80132
+:10018000E090F901F090FA0130E020E0FA01C59129
 :10019000D491E881B90190E080E0EB23EA130AC032
 :1001A0002F5F3F4F6C157D058E059F0578F36FEF30
 :1001B0007FEFCB01DF91CF91FF90EF90DF90CF9059
@@ -40,7 +40,7 @@
 :100260000895FC01918D828D981731F0828DE80FF1
 :10027000F11D858D90E008958FEF9FEF0895FC01AB
 :10028000918D228D892F90E0805C9F4F821B910978
-:100290008F739927089587E491E00E943F0121E040
+:100290008F73992708958DE491E00E943F0121E03A
 :1002A000892B09F420E0822F089580E090E0892BCB
 :1002B00029F00E944B0181110C9400000895FC016B
 :1002C000A48DA80FB92FB11DA35ABF4F2C91848DB7
@@ -58,7 +58,7 @@
 :10038000EC0FFD2FF11DE35AFF4FF0829FB7F89459
 :100390000B8FEA89FB8980818062CFCF0F931F93F7
 :1003A000CF93DF938C01D0E0C0E0F801EC0FFD1F8C
-:1003B0006491662341F087E491E00E948101892BDA
+:1003B0006491662341F08DE491E00E948101892BD4
 :1003C00011F02196F2CFCE01DF91CF911F910F91C5
 :1003D0000895CF93DF93EC01888D8823B9F0AA8923
 :1003E000BB89E889F9898C9185FD03C0808186FDF0
@@ -95,26 +95,26 @@
 :1005D0002A0180912B0190912C012FBF08958F92B9
 :1005E0009F92AF92BF92CF92DF92EF92FF920F93C2
 :1005F0001F93CF93DF93CDB7DEB7C054D1400FB672
-:10060000F894DEBF0FBECDBF0E94E3020091ED0162
-:100610001091EE012091EF013091F0016B017C010E
+:10060000F894DEBF0FBECDBF0E94E3020091F3015C
+:100610001091F4012091F5013091F6016B017C01FC
 :10062000C01AD10AE20AF30A97018601003D174079
-:1006300021053105B0F48091F501C05CDE4F0FB6A5
+:1006300021053105B0F48091FB01C05CDE4F0FB69F
 :10064000F894DEBF0FBECDBFDF91CF911F910F9108
 :10065000FF90EF90DF90CF90BF90AF909F908F90E2
-:1006600008956093ED017093EE018093EF019093F4
-:10067000F0011092E8011092E7011092E601109249
-:10068000E5011092E40162E08091E9010E945B02C1
+:1006600008956093F3017093F4018093F5019093E2
+:10067000F6011092EE011092ED011092EC01109231
+:10068000EB011092EA0162E08091EF010E945B02AF
 :1006900061E070E080E090E00E94B10261E0809152
-:1006A000E9010E945B022091E90130E0F901EA547E
+:1006A000EF010E945B022091EF0130E0F901EA5472
 :1006B000FF4F8491F901E851FF4F0491F901EC5289
 :1006C000FF4F1491112391F081110E940902E12F33
 :1006D000F0E0EE0FFF1FE455FF4FA591B4918FB7E7
-:1006E000F894EC9100950E230C938FBF8091EA0152
+:1006E000F894EC9100950E230C938FBF8091F0014C
 :1006F0008551823020F58BE291E10197F1F762E0BC
-:100700008091E9010E945B028091F60190E08230C5
+:100700008091EF010E945B028091FC0190E08230B9
 :10071000910538F0880F991F880F991F0597019749
 :10072000F1F7F89480E00E94A9006F3F7F4F8F4F50
-:100730009F4F61F41092F501789480E07ECF64E1E0
+:100730009F4F61F41092FB01789480E07ECF64E1DA
 :1007400070E080E090E00E94B102D9CF81E00E9489
 :10075000A9006F3F7F4F8F4F9F4F61F3CE010196EE
 :100760007C015E019FEBA91A9EEFB90A870180E028
@@ -123,19 +123,19 @@
 :100790001F4FA016B10659F7789430E020E0F7011A
 :1007A00080809180A280B380448155816681778169
 :1007B000FFEF8F169F06AF06BF0631F04F3F8FEF5A
-:1007C00058076807780719F41092F501B6CFF901B8
-:1007D00083E0F595E7958A95E1F7EC51FE4F80812E
+:1007C00058076807780719F41092FB01B6CFF901B2
+:1007D00083E0F595E7958A95E1F7E651FE4F808134
 :1007E000880F84169506A606B70618F180832F5F3A
 :1007F0003F4F98E0E90EF11C2832310581F6409117
-:10080000E8012091E4018091E501280F3327331F8F
-:100810008091E601280F311D8091E701820F932F0F
-:10082000911D99274817190679F681E08093F50103
+:10080000EE012091EA018091EB01280F3327331F7D
+:100810008091EC01280F311D8091ED01820F932F03
+:10082000911D99274817190679F681E08093FB01FD
 :1008300004CF8160DBCFFC0101900020E9F7319704
-:10084000AF01481B590BBC0187E491E00C94E10017
+:10084000AF01481B590BBC018DE491E00C94E10011
 :100850008F929F92AF92BF920F931F93CF93DF938C
 :10086000CDB7DEB7A1970FB6F894DEBF0FBECDBFF0
 :1008700019A2423008F44AE08E010F5D1F4F842E0A
-:10088000912CB12CA12CA50194010E94400AE62FC5
+:10088000912CB12CA12CA50194010E942F0AE62FD6
 :10089000B901CA01EA30F4F4E05DD801EE938D01AC
 :1008A000232B242B252B79F790E080E0109719F06B
 :1008B000CD010E941B04A1960FB6F894DEBF0FBEB7
@@ -149,14 +149,14 @@
 :1009300080E090E0CF910C94B10289E191E0F4CF96
 :100940001F920F920FB60F9211242F933F934F9344
 :100950005F936F937F938F939F93AF93BF93EF9327
-:10096000FF9387E491E00E945F01FF91EF91BF91B7
+:10096000FF938DE491E00E945F01FF91EF91BF91B1
 :10097000AF919F918F917F916F915F914F913F9137
 :100980002F910F900FBE0F901F9018951F920F92EE
 :100990000FB60F9211242F938F939F93EF93FF9392
-:1009A000E0915701F09158018081E0915D01F09153
-:1009B0005E0182FD1BC09081809160018F5F8F730B
-:1009C00020916101821741F0E0916001F0E0E95B64
-:1009D000FE4F958F80936001FF91EF919F918F91D2
+:1009A000E0915D01F0915E018081E0916301F09141
+:1009B000640182FD1BC09081809166018F5F8F73FF
+:1009C00020916701821741F0E0916601F0E0E35B5E
+:1009D000FE4F958F80936601FF91EF919F918F91CC
 :1009E0002F910F900FBE0F901F9018958081F4CF1C
 :1009F0001F920F920FB60F9211242F933F938F9354
 :100A00009F93AF93BF938091290190912A01A09168
@@ -167,12 +167,12 @@
 :100A5000B11D80932D0190932E01A0932F01B0938F
 :100A60003001BF91AF919F918F913F912F910F9046
 :100A70000FBE0F901F90189526E8230F0296A11D18
-:100A8000B11DD2CFE7E4F1E01382128288EE93E049
+:100A8000B11DD2CFEDE4F1E01382128288EE93E043
 :100A9000A0E0B0E084839583A683B78384E091E0EF
 :100AA0009183808385EC90E09587848784EC90E047
 :100AB0009787868780EC90E0918B808B81EC90E02B
 :100AC000938B828B82EC90E0958B848B86EC90E00C
-:100AD000978B868B118E128E138E148EA4EEB1E03E
+:100AD000978B868B118E128E138E148EAAEEB1E038
 :100AE00081E115968C93159786E116968C9316974F
 :100AF000E9EFF0E0E4911796EC931797E5EEF0E05C
 :100B0000E4911896EC93189740E85EE360E070E09B
@@ -185,156 +185,154 @@
 :100B7000B00081608093B00080917A00846080939F
 :100B80007A0080917A00826080937A0080917A0066
 :100B9000816080937A0080917A00806880937A00E7
-:100BA0001092C100E0915701F091580182E08083DA
-:100BB000E0915701F09158011082E0915301F091BA
-:100BC00054011082E0915501F091560180E180833B
-:100BD00010925F01E0915B01F0915C0186E08083FF
-:100BE000E0915901F0915A01808180618083E09108
-:100BF0005901F0915A01808188608083E091590108
-:100C0000F0915A01808180688083E0915901F091D0
-:100C10005A0180818F7D808384E790E00E94CE011D
-:100C20008BE191E00E946C0462E082E00E945B0232
-:100C300062E083E00E945B0262E084E00E945B026B
-:100C400082E00E94320221E0892B09F420E0209307
-:100C5000310183E00E94320221E0892B09F420E077
-:100C60002093320184E00E94320221E0892B09F4B2
-:100C700020E02093330162E08091E9010E945B0251
-:100C80000E94E302605D7740810991096093ED0164
-:100C90007093EE018093EF019093F00187E38093CE
-:100CA000F601C0E0D0E030E4A32E31E0B32E41E302
-:100CB000C42E41E0D42E54E3E52E51E0F52E12E08F
-:100CC000812F0E94320201E0892B09F400E0F50136
-:100CD00081915F01081751F00E94E302F7016083E0
-:100CE000718382839383F50131970083F6018081BC
-:100CF0000817E1F00E94E302F70140805180628012
-:100D0000738064197509860997096B3F7105810520
-:100D1000910560F0F60100830E94E302F701608311
-:100D2000718382839383812F0E947A041F5FFFEF78
-:100D3000CF1ADF0A24E0E20EF11C153009F60E94FA
-:100D4000E30200914301109144012091450130914B
-:100D50004601601B710B820B930B61367A4E810545
-:100D6000910508F4C6C00E94E302609343017093AA
-:100D70004401809345019093460182E00E947A04E9
-:100D800083E00E947A0484E00E947A040E94EF02C9
-:100D9000882349F08091EA018B3028F08D3050F0A3
-:100DA00085518230C8F1812C912C20ECA22E2FE7A6
-:100DB000B22E1EC06091E50170E090E080E00E94DC
-:100DC00019092DEC3CEC4CEC5DE30E94CE096B0163
-:100DD0007C016091E40170E090E080E00E941909DC
-:100DE0009B01AC01C701B6010E9470084B015C0178
-:100DF0000E94EF02882309F474C08091EA018C30CC
-:100E000009F482C0D8F48B3091F1C12CD12C80EC44
-:100E1000E82E8FE7F82E55C06091E4017091E5014E
-:100E200076276727762790E080E00E9417092DEC4F
-:100E30003CEC4CEC5DE30E94CE09D8CF855182306A
-:100E400020F71091E601612F70E0762F6627662764
-:100E50007F778091E701682B90E080E00E9417097E
-:100E60002DEC3CEC4CEC5DE30E94CE0969C0609136
-:100E7000E60170E090E080E00E9417096B017C01C0
-:100E80001091E70117FF0AC0AC019B0160E070E020
-:100E900080E89FEB0E946F086B017C011F70612F3F
-:100EA00070E090E080E00E9419092DEC3CEC4CECE5
-:100EB0005DE30E94CE09A70196010E9470086B01B4
-:100EC0007C01A5019401C501B4010E943B0A811176
-:100ED00008C0A7019601C701B6010E943B0A8823FA
-:100EE000C1F184E990E00E94CE0182E191E00E948C
-:100EF0001B04209709F4D7CE0E944B01882309F4E4
-:100F0000D2CE0E940000CFCE1091E601612F70E09A
-:100F100090E080E00E9417096B017C016091E7017D
-:100F20006F7070E090E080E00E9419092DEC3CECBD
-:100F30004CEC5DE30E94CE09A70196010E94700867
-:100F40006B017C0117FFBDCFF7FAF094F7F8F0942E
-:100F5000B8CF8EE890E00E94CE0126013701E894D8
-:100F600077F82FEF3FEF4FE75FE7C301B2010E9431
-:100F70003B0A81113DC02FEF3FEF4FE75FE7C30111
-:100F8000B2010E94DC0818169CF58FE191E00E94E6
-:100F90001B0488E890E00E94CE01C501B4010E94C4
-:100FA000E1086B01770FEE08FF084AE0C701B601C0
-:100FB000F7FE0DC06DE287E491E00E948101662793
-:100FC0007727CB016C197D098E099F094AE00E94A1
-:100FD000280486E890E00E94CE0182E191E00E9420
-:100FE0001B0465E070E080E090E00E94B10281CFD8
-:100FF0002FEF3FEF4FE75FE4C701B6010E94C90939
-:1010000018161CF483E291E0C2CF2FEF3FEF4FE7B9
-:101010005FECC701B6010E94DC0887FDF3CF20E03A
-:1010200030E0A901C701B6010E94DC0887FF09C0B2
-:101030006DE287E491E00E948101F7FAF094F7F8FD
-:10104000F0942AE037ED43EA5BE3C701B6010E9462
-:1010500070082B013C010E94E8086B017C010E9492
-:1010600017099B01AC01C301B2010E946F082B015B
-:101070003C014AE0C701B6010E9428046EE287E401
-:1010800091E00E94810120E030E040E251E4C301A0
-:10109000B2010E94CE092B013C010E94E8086B01BD
-:1010A000F12CE12C4AE0C701B6010E942804C701D7
-:1010B000B6010E9417099B01AC01C301B2010E9455
-:1010C0006F0820E030E040E251E40E94CE090E9427
-:1010D000E80890E080E04AE00E9428045ACF505887
-:1010E000BB27AA270E9487080C948F090E948109B8
-:1010F00038F00E94880920F039F49F3F19F426F453
-:101100000C947E090EF4E095E7FB0C947809E92F26
-:101110000E94A00958F3BA1762077307840795075E
-:1011200020F079F4A6F50C94C2090EF4E0950B2E8C
-:10113000BA2FA02D0B01B90190010C01CA01A00129
-:101140001124FF27591B99F0593F50F4503E68F184
-:101150001A16F040A22F232F342F4427585FF3CFC5
-:10116000469537952795A795F0405395C9F77EF496
-:101170001F16BA0B620B730B840BBAF09150A1F0DF
-:10118000FF0FBB1F661F771F881FC2F70EC0BA0F65
-:10119000621F731F841F48F4879577956795B795ED
-:1011A000F7959E3F08F0B0CF9395880F08F09927E8
-:1011B000EE0F9795879508950E94540908F481E0F1
-:1011C00008950E94E8086894B1110C94C309089529
-:1011D0000E94A80988F09F5798F0B92F9927B75116
-:1011E000B0F0E1F0660F771F881F991F1AF0BA95CB
-:1011F000C9F714C0B13091F00E94C209B1E008955E
-:101200000C94C209672F782F8827B85F39F0B93F4F
-:10121000CCF3869577956795B395D9F73EF490957D
-:101220008095709561957F4F8F4F9F4F0895E894FB
-:1012300009C097FB3EF490958095709561957F4F1E
-:101240008F4F9F4F9923A9F0F92F96E9BB279395CC
-:10125000F695879577956795B795F111F8CFFAF4DC
-:10126000BB0F11F460FF1BC06F5F7F4F8F4F9F4F0D
-:1012700016C0882311F096E911C0772321F09EE86B
-:10128000872F762F05C0662371F096E8862F70E0D1
-:1012900060E02AF09A95660F771F881FDAF7880FAB
-:1012A0009695879597F90895990F0008550FAA0B01
-:1012B000E0E8FEEF16161706E807F907C0F0121669
-:1012C0001306E407F50798F0621B730B840B950B6C
-:1012D00039F40A2661F0232B242B252B21F40895C1
-:1012E0000A2609F4A140A6958FEF811D811D08955E
-:1012F00097F99F6780E870E060E008959FEF80ECC9
-:10130000089500240A94161617061806090608956B
-:1013100000240A9412161306140605060895092ED1
-:101320000394000C11F4882352F0BB0F40F4BF2B40
-:1013300011F460FF04C06F5F7F4F8F4F9F4F089580
-:1013400057FD9058440F551F59F05F3F71F0479576
-:10135000880F97FB991F61F09F3F79F0879508955B
-:10136000121613061406551FF2CF4695F1DF08C07A
-:10137000161617061806991FF1CF86957105610597
-:1013800008940895E894BB2766277727CB0197F93F
-:1013900008950E94540908F48FEF08950E94E1090E
-:1013A0000C948F090E94810938F00E94880920F06E
-:1013B000952311F00C9478090C947E0911240C9457
-:1013C000C3090E94A00970F3959FC1F3950F50E0E7
-:1013D000551F629FF001729FBB27F00DB11D639FE7
-:1013E000AA27F00DB11DAA1F649F6627B00DA11D8D
-:1013F000661F829F2227B00DA11D621F739FB00D33
-:10140000A11D621F839FA00D611D221F749F3327A2
-:10141000A00D611D231F849F600D211D822F762F3B
-:101420006A2F11249F5750409AF0F1F088234AF018
-:10143000EE0FFF1FBB1F661F771F881F9150504084
-:10144000A9F79E3F510580F00C9478090C94C309CC
-:101450005F3FE4F3983ED4F3869577956795B7950B
-:10146000F795E7959F5FC1F7FE2B880F911D969525
-:10147000879597F908950E945409880B990B089550
-:10148000A1E21A2EAA1BBB1BFD010DC0AA1FBB1F88
-:10149000EE1FFF1FA217B307E407F50720F0A21BFA
-:1014A000B30BE40BF50B661F771F881F991F1A9467
-:1014B00069F760957095809590959B01AC01BD0191
-:1014C000CF010895EE0FFF1F0590F491E02D0994D0
-:1014D000F894FFCF000000008101E1000E01E90156
-:1014E0003F011D0131010D0A003D0048004C003054
-:0C14F0002E3100696E66006F7666000009
+:100BA0001092C100E0915D01F0915E0182E08083CE
+:100BB000E0915901F0915A011082E0915B01F091AE
+:100BC0005C0180E1808310926501E0916101F09108
+:100BD000620186E08083E0915F01F0916001808195
+:100BE00080618083E0915F01F09160018081886085
+:100BF0008083E0915F01F091600180818068808353
+:100C0000E0915F01F091600180818F7D808384E7B6
+:100C100090E00E94CE018BE191E00E946C04C2E062
+:100C200062E08C2F0E945B02CF5FC630C9F701E300
+:100C300011E0C2E08C2F0E94320221E0892B09F4DE
+:100C400020E0F80121938F01CF5FC63099F762E071
+:100C50008091EF010E945B020E94E302605D774099
+:100C6000810991096093F3017093F4018093F50178
+:100C70009093F60187E38093FC01C0E0D0E035E477
+:100C8000A32E31E0B32E45E3E42E41E0F42E51E3F0
+:100C9000C52E51E0D52E12E0812F0E94320201E0D4
+:100CA000892B09F400E0F50181915F01081751F0EB
+:100CB0000E94E302F7016083718382839383F501CD
+:100CC00031970083F60180810817E1F00E94E3026A
+:100CD000F70140805180628073806419750986092C
+:100CE00097096B3F71058105910560F0F60100835E
+:100CF0000E94E302F7016083718382839383812FD3
+:100D00000E947A041F5FFFEFCF1ADF0A24E0E20E91
+:100D1000F11C163009F60E94E3020091490110917E
+:100D20004A0120914B0130914C01601B710B820BE9
+:100D3000930B61367A4E8105910508F4C9C00E9473
+:100D4000E3026093490170934A0180934B019093B1
+:100D50004C0182E00E947A0483E00E947A0484E0DD
+:100D60000E947A0485E00E947A040E94EF028823A0
+:100D700049F08091F0018B3028F08D3050F0855192
+:100D80008230C8F1812C912C20ECA22E2FE7B22EBC
+:100D90001EC06091EB0170E090E080E00E940809C5
+:100DA0002DEC3CEC4CEC5DE30E94BD096B017C0139
+:100DB0006091EA0170E090E080E00E9408099B01E8
+:100DC000AC01C701B6010E945F084B015C010E94A3
+:100DD000EF02882309F474C08091F0018C3009F48B
+:100DE00082C0D8F48B3091F1C12CD12C80ECE82E4C
+:100DF0008FE7F82E55C06091EA017091EB017627DC
+:100E00006727762790E080E00E9406092DEC3CECF5
+:100E10004CEC5DE30E94BD09D8CF8551823020F7AC
+:100E20001091EC01612F70E0762F662766277F779F
+:100E30008091ED01682B90E080E00E9406092DEC86
+:100E40003CEC4CEC5DE30E94BD0969C06091EC0193
+:100E500070E090E080E00E9406096B017C01109137
+:100E6000ED0117FF0AC0AC019B0160E070E080E873
+:100E70009FEB0E945E086B017C011F70612F70E088
+:100E800090E080E00E9408092DEC3CEC4CEC5DE326
+:100E90000E94BD09A70196010E945F086B017C01B9
+:100EA000A5019401C501B4010E942A0A811108C05C
+:100EB000A7019601C701B6010E942A0A8823C1F141
+:100EC00084E990E00E94CE0182E191E00E941B043F
+:100ED000209709F4D4CE0E944B01882309F4CFCE89
+:100EE0000E940000CCCE1091EC01612F70E090E0E8
+:100EF00080E00E9406096B017C016091ED016F703A
+:100F000070E090E080E00E9408092DEC3CEC4CEC95
+:100F10005DE30E94BD09A70196010E945F086B0175
+:100F20007C0117FFBDCFF7FAF094F7F8F094B8CF33
+:100F30008EE890E00E94CE0126013701E89477F810
+:100F40002FEF3FEF4FE75FE7C301B2010E942A0A8C
+:100F500081113DC02FEF3FEF4FE75FE7C301B201C3
+:100F60000E94CB0818169CF58FE191E00E941B04AB
+:100F700088E890E00E94CE01C501B4010E94D0082B
+:100F80006B01770FEE08FF084AE0C701B601F7FED4
+:100F90000DC06DE28DE491E00E9481016627772704
+:100FA000CB016C197D098E099F094AE00E94280433
+:100FB00086E890E00E94CE0182E191E00E941B044D
+:100FC00065E070E080E090E00E94B10281CF2FEFF9
+:100FD0003FEF4FE75FE4C701B6010E94B80918165A
+:100FE0001CF483E291E0C2CF2FEF3FEF4FE75FECBD
+:100FF000C701B6010E94CB0887FDF3CF20E030E0A7
+:10100000A901C701B6010E94CB0887FF09C06DE2A4
+:101010008DE491E00E948101F7FAF094F7F8F094E2
+:101020002AE037ED43EA5BE3C701B6010E945F089F
+:101030002B013C010E94D7086B017C010E9406092C
+:101040009B01AC01C301B2010E945E082B013C016F
+:101050004AE0C701B6010E9428046EE28DE491E0E7
+:101060000E94810120E030E040E251E4C301B2017E
+:101070000E94BD092B013C010E94D7086B01F12C95
+:10108000E12C4AE0C701B6010E942804C701B6015D
+:101090000E9406099B01AC01C301B2010E945E08D7
+:1010A00020E030E040E251E40E94BD090E94D708F0
+:1010B00090E080E04AE00E9428045ACF5058BB27B5
+:1010C000AA270E9476080C947E090E94700938F0C5
+:1010D0000E94770920F039F49F3F19F426F40C940C
+:1010E0006D090EF4E095E7FB0C946709E92F0E9467
+:1010F0008F0958F3BA17620773078407950720F022
+:1011000079F4A6F50C94B1090EF4E0950B2EBA2FE4
+:10111000A02D0B01B90190010C01CA01A0011124FD
+:10112000FF27591B99F0593F50F4503E68F11A16A9
+:10113000F040A22F232F342F4427585FF3CF46953A
+:1011400037952795A795F0405395C9F77EF41F165C
+:10115000BA0B620B730B840BBAF09150A1F0FF0F26
+:10116000BB1F661F771F881FC2F70EC0BA0F621F12
+:10117000731F841F48F4879577956795B795F79502
+:101180009E3F08F0B0CF9395880F08F09927EE0F97
+:101190009795879508950E94430908F481E0089582
+:1011A0000E94D7086894B1110C94B20908950E9466
+:1011B000970988F09F5798F0B92F9927B751B0F049
+:1011C000E1F0660F771F881F991F1AF0BA95C9F7CB
+:1011D00014C0B13091F00E94B109B1E008950C94AF
+:1011E000B109672F782F8827B85F39F0B93FCCF362
+:1011F000869577956795B395D9F73EF49095809548
+:10120000709561957F4F8F4F9F4F0895E89409C067
+:1012100097FB3EF490958095709561957F4F8F4F29
+:101220009F4F9923A9F0F92F96E9BB279395F6953F
+:10123000879577956795B795F111F8CFFAF4BB0FBD
+:1012400011F460FF1BC06F5F7F4F8F4F9F4F16C021
+:10125000882311F096E911C0772321F09EE8872FAB
+:10126000762F05C0662371F096E8862F70E060E067
+:101270002AF09A95660F771F881FDAF7880F9695E0
+:10128000879597F90895990F0008550FAA0BE0E884
+:10129000FEEF16161706E807F907C0F01216130638
+:1012A000E407F50798F0621B730B840B950B39F478
+:1012B0000A2661F0232B242B252B21F408950A26DE
+:1012C00009F4A140A6958FEF811D811D089597F91E
+:1012D0009F6780E870E060E008959FEF80EC0895DC
+:1012E00000240A9416161706180609060895002405
+:1012F0000A9412161306140605060895092E03947F
+:10130000000C11F4882352F0BB0F40F4BF2B11F4F2
+:1013100060FF04C06F5F7F4F8F4F9F4F089557FD51
+:101320009058440F551F59F05F3F71F04795880F53
+:1013300097FB991F61F09F3F79F0879508951216EA
+:1013400013061406551FF2CF4695F1DF08C0161696
+:1013500017061806991FF1CF869571056105089447
+:101360000895E894BB2766277727CB0197F908955E
+:101370000E94430908F48FEF08950E94D0090C944D
+:101380007E090E94700938F00E94770920F09523A9
+:1013900011F00C9467090C946D0911240C94B20996
+:1013A0000E948F0970F3959FC1F3950F50E0551F70
+:1013B000629FF001729FBB27F00DB11D639FAA27AA
+:1013C000F00DB11DAA1F649F6627B00DA11D661FF9
+:1013D000829F2227B00DA11D621F739FB00DA11D1A
+:1013E000621F839FA00D611D221F749F3327A00DD4
+:1013F000611D231F849F600D211D822F762F6A2F70
+:1014000011249F5750409AF0F1F088234AF0EE0FD4
+:10141000FF1FBB1F661F771F881F91505040A9F701
+:101420009E3F510580F00C9467090C94B2095F3F10
+:10143000E4F3983ED4F3869577956795B795F7953D
+:10144000E7959F5FC1F7FE2B880F911D96958795B5
+:1014500097F908950E944309880B990B0895A1E21A
+:101460001A2EAA1BBB1BFD010DC0AA1FBB1FEE1F1E
+:10147000FF1FA217B307E407F50720F0A21BB30B69
+:10148000E40BF50B661F771F881F991F1A9469F7E5
+:1014900060957095809590959B01AC01BD01CF0141
+:1014A0000895EE0FFF1F0590F491E02D0994F89434
+:1014B000FFCF000000008101E1000E01E9013F01C2
+:1014C0001D0131010D0A003D0048004C00302E3155
+:0A14D00000696E66006F766600008A
 :107E0000112484B714BE81FFF0D085E080938100F7
 :107E100082E08093C00088E18093C10086E0809377
 :107E2000C20080E18093C4008EE0C9D0259A86E02C