diff --git a/fhem/FHEM/52_I2C_ADS1x1x.pm b/fhem/FHEM/52_I2C_ADS1x1x.pm
index 1f004e084..9e792022e 100755
--- a/fhem/FHEM/52_I2C_ADS1x1x.pm
+++ b/fhem/FHEM/52_I2C_ADS1x1x.pm
@@ -13,6 +13,7 @@ use strict;
use warnings;
use SetExtensions;
use Scalar::Util qw(looks_like_number);
+use List::Util qw(sum);
my %I2C_ADS1x1x_Config =
(
@@ -105,6 +106,7 @@ sub I2C_ADS1x1x_Initialize($) {
"a3_mode:RTD,NTC,RAW,RES,off ".
"a0_res a1_res a2_res a3_res ".
"a0_r0 a1_r0 a2_r0 a3_r0 ".
+ "a0_avg a1_avg a2_avg a3_avg ".
"a0_bval a1_bval a2_bval a3_bval ".
"a0_gain:6V,4V,2V,1V,0.5V,0.25V ".
"a1_gain:6V,4V,2V,1V,0.5V,0.25V ".
@@ -417,10 +419,23 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
( $refvoltage/$mask) * # normiere anhand der Auflösung 2^15 im positiven Bereich
( 1.0 - (2.0 * (($value & ($mask+1)) >> ($bits-1)))); # bei gesetzten Bit 2^15 Faktor -1, ansonsten +1 ($mask+1 = 0x8000/0x800)
+ my $sensor= $clientmsg->{sensor};
+
+ #Build average with floating windows to smoothe shaky sensors
+ my @avg=();
+ my $avgs=$hash->{helper}{"a".$sensor};
+ if (defined $avgs) {
+ @avg=@$avgs;
+ }
+ my $avgmax=AttrVal($name,"a".$sensor."_avg",1);
+ push @avg,$voltage;
+ while (@avg>$avgmax) { shift @avg; }
+ $hash->{helper}{"a".$sensor}=[@avg];
+ $voltage=sum(@avg)/@avg;
+
#rounded voltage only for reading, continue calculation will full precision
my $voltager = sprintf( '%.' . AttrVal($clientHash->{NAME}, 'decimals', 3) . 'f', $voltage );
Log3 $hash,5 , "$name:voltage=$voltage, ref=".$I2C_ADS1x1x_Config{'Gain'}{$gain}{refVoltage};
- my $sensor= $clientmsg->{sensor};
readingsBulkUpdate($hash, "a".$sensor."_voltage", $voltager) if (ReadingsVal($name,"a".$sensor."_voltage",0) != $voltager);
my $divider=AttrVal($name,"a".$sensor."_res",1000);
my $highvoltage=AttrVal($name,"sys_voltage",3.3);
@@ -458,11 +473,10 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
=item summary_DE liest/konvertiert Daten eines via angeschlossenen ADS1x1x A/D Wandlers
=begin html
-
I2C_ADS1x1x
(en | de)
-
+
Provides an interface to an ADS1x1x A/D converter via I2C.
The I2C messages are send through an I2C interface module like RPII2C, FRM
or NetzerI2C so this device must be defined first.
@@ -487,7 +501,7 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
Attribute IODev must be set. This is typically the name of a defined RPII2C device
-
+
Define
define <name> I2C_ADS1x1x <I2C Address>
@@ -495,11 +509,11 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
-
+
Set
- update
-
+
set <name> update
Trigger a reading. Resets the timers so the first reading will start within 1s -
continuing with the other channels based on the polling_interleave attribute.
@@ -507,12 +521,12 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
-
+
Attributes
- device
-
+
Defines the Texas Instruments ADS1x1x device that is actually being used.
- ADS1013 - 12Bit, 1 channel
@@ -529,37 +543,37 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
- poll_interval
-
+
Set the polling interval in minutes to query a new reading from enabled channels
By setting this number to 0, the device can be set to manual mode (new readings only by "set update").
Default: 5, valid values: decimal number
- poll_interleave
-
+
Interleave between reading 2 channels in seconds (only valid for multi channel devices).
Can be used to distribute the load more evenly.
Default: 0.008, valid values: decimal number
- sys_voltage
-
+
System voltage running the chip and typically connected to the pull-up resistor (e.g. 3.3V with a Raspberry Pi)
Default: 3.3, valid values: float number
- decimals
-
+
Number of decimals (after the decimal point) for voltage and resistance to make results more readable.
Calculations are still based on full precision. Temperatures are fixed to one decimal.
Default: 3, valid values: 0,1,2,3,4,5
- a[0-3]_gain
-
-
-
-
+
+
+
+
Gain amplifier value (sensibility and range of measurement) used per channel a0-a3.
Standard is 4V which can measure a range between 0 and 4 Volts.
If measuring smaller voltage, the amplification can be increased to get more accurate readings.
@@ -568,10 +582,10 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
- a[0-3]_mode
-
-
-
-
+
+
+
+
Determines how the results are interpreted.
- off: The channel is not measured
@@ -586,35 +600,43 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
- a[0-3]_res
-
-
-
-
+
+
+
+
Value of pull-up resistor for resistance and temperature measurement. Connected between A0 and VCC (defined in "sys_voltage")
Default: 1000, valid values: float numbers
- a[0-3]_r0
-
-
-
-
+
+
+
+
Reference resistance for temperature measurements at 0°C (for RTD) and 25°C (for NTC) in Ohm.
Default: 1000.0 in RTD and 50000.0 in NTC mode, valid values: float numbers
- a[0-3]_bval
-
-
-
-
+
+
+
+
B-Value for NTC Thermistors (define the increase from the base value).
Default: 3950.0, valid values: float numbers
-
+ - a[0-3]_avg
+
+
+
+
+ Sometimes measurements can fluctuate. To get smoother values, this attribute will enable creating an average of n numbers, which should result in more stable results.
+ Default: 1, valid values: integers
+
+
- data_rate (1/16x,1/8x,1/4x,1/2x,1x,2x,4x,8x )
-
+
Conversion speed - default is 1x. The 12-bit chips use 1600 SPS as default rate, while the 16-bit chips are slower with 128 SPS.
Below table translates the settings based on the actual device used.
@@ -677,7 +699,6 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
- operation_mode
-
Not implemented, since Continuous Mode make no sense when using multiple input registers and is meant to read values in very high speed (e.g. one value every 8 ms) which IMHO makes no sense with FHEM.
- SingleShot: Do one reading and then power down
@@ -702,7 +723,7 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
- - latching_comparator (on|off)
+ - latching_comparator (on|off)
@@ -718,25 +739,24 @@ sub I2C_ADS1x1x_I2CRec($@) { # ueber CallFn vom physical aufgerufen
=begin html_DE
-
I2C_ADS1x1x
(en | de)
-
+
Bitte englische Dokumentation verwenden.
-
+
Define
define <name> I2C_ADS1x1x <I2C Address>
Der Wert <I2C Address>
ist ohne das Richtungsbit
-
+
Set
-
+
Attribute