Conductivity via Analog Electrical Resistance topic
Classes for measuring conductivity using a simple analog voltage divider.
Introduction
This is for a very basic conductivity circuit built with a single resistor and an old power cord. DC power is briefly supplied across the power cord causing the water to act as one of the resistors on a voltage divider. Knowing the voltage of the other resistor in the divider, we can calculate to resistance from the water (and then its electrical conductivity) based on the drop in volage across the divider.
For this to work, the power across the circuit MUST be turned off between readings. If the power to the circuit is left on the water will become polarized and the values will not be valid. The water temperature (if used) must be suplied separately for a calculation.
The Circuit
One pole of the power cord wire is connected to the ground of the main logger board. The other pole is connected to the sensor power supply via a resistor of known resistance (R1) and then to an analog pin to measure the voltage.
So the circuit is:
The above diagram and the calculations assume the reistance of the analog pins themselves on the Arduino is negligible.
Calculating the Conductivity
First, we need to convert the bit reading of the ADC into volts based on the range of the ADC (1 bit more than the resolution):
Assuming the voltage of the ADC reference is the same as that used to power the EC resistor circuit we can replace the reference voltage with the sensor power voltage:
Now we can calculate the resistance of the water, knowing the resistance of the resistor we put in the circuit and the voltage drop:
Combining the above equations and doing some rearranging, we get:
The conductivity is then the inverse of the resistance - multiplied by a measured cell constant and a 10^6 conversion to µS/cm.
The real cell constant will vary based on the size of the "cell" - that is, the size of the plug on the power cord. You can calculate the cell constant for each power cord sensor you use following the calibration program.
For one AC Power Cord 12t with male IEC 320-C8 connector the cell constant was 2.88.
References
- For the sensor setup and calculations: https:/
/ hackaday.io/ project/ 7008-fly-wars-a-hackers-solution-to-world-hunger/ log/ 24646-three-dollar-ec-ppm-meter-arduino - For temperature compensation: https:/
/ link.springer.com/ article/ 10.1023/ B:EMAS.0000031719.83065.68
Build flags
-D ANALOG_EC_ADC_RESOLUTION=##
- used to set the resolution of the processor ADC
-D ANALOG_EC_ADC_REFERENCE_MODE=xxx
- used to set the processor ADC value reference mode
Sensor Constructor
Construct a new AnalogElecConductivity object. The processor ADC port pin to read the voltage from the EC probe. Not all processor pins can be used as analog pins. Those usable as analog pins generally are numbered with an "A" in front of the number
AnalogElecConductivity::
Parameters
powerPin
The port pin providing power to the EC probe. Needs to be switched, and assumed to be same V as the dataPin's ADC.
dataPin
Rseries_ohms
The resistance of the resistor series (R) in the line; optional with default value of 499.
sensorEC_Konst
The cell constant for the sensing circuit; optional with default value of 2.88 - which is what has been measured for a typical standard sized lamp-type plug.
measurementsToAverage
The number of measurements to average; optional with default value of 1.
Example Code
The analog electrical conductivity sensor is used in the menu a la carte example.
Classes
- class AnalogElecConductivity
- Class for the analog [Electrical Conductivity monitor](Conductivity via Analog Electrical Resistance)
- class AnalogElecConductivity_EC
- The Variable sub-class used for electrical conductivity measured using an analog pin connected to electrodes submerged in the medium.
Sensor Variable Counts
The number of variables that can be returned by the analog conductivity sensor
- #define ANALOGELECCONDUCTIVITY_NUM_VARIABLES = 1
- Sensor::
_numReturnedValues; we only get one value from the analog conductivity sensor. - #define ANALOGELECCONDUCTIVITY_INC_CALC_VARIABLES = 0
- Sensor::
_incCalcValues; we don't calculate any additional values though we recommend users include a temperature sensor and calculate specific conductance in their own program.
Configuration Defines
Defines to help configure the range and resolution of the home-made conductivity sensor depending on the processor and ADC in use.
- #define ANALOG_EC_ADC_RESOLUTION = 10
- Default resolution (in bits) of the voltage measurement.
- #define ANALOG_EC_ADC_MAX = ((1 <<
- The maximum possible value of the ADC - one less than the resolution shifted up one bit.
- #define ANALOG_EC_ADC_RANGE = (1 <<
- The maximum possible range of the ADC - the resolution shifted up one bit.
- #define ANALOG_EC_ADC_REFERENCE_MODE = DEFAULT
- The voltage reference mode for the processor's ADC.
- #define ANALOG_EC_ADC_REFERENCE_MODE = AR_DEFAULT
- The voltage reference mode for the processor's ADC.
- #define RSERIES_OHMS_DEF = 499
- The default resistance (in ohms) of the measuring resistor. This should not be less than 300 ohms when measuring EC in water.
- #define SENSOREC_KONST_DEF = 1.0
- Cell Constant For EC Measurements.
Sensor Timing
The timing for analog conductivity via resistance.
- #define ANALOGELECCONDUCTIVITY_WARM_UP_TIME_MS = 2
- Sensor::
_warmUpTime_ms; giving 2ms for warm-up. - #define ANALOGELECCONDUCTIVITY_STABILIZATION_TIME_MS = 1
- Sensor::
_stabilizationTime_ms; we give just a tiny delay for stabilization. - #define ANALOGELECCONDUCTIVITY_MEASUREMENT_TIME_MS = 0
- Sensor::
_measurementTime_ms; we assume the analog voltage is measured instantly.
Electrical Conductance
The electrical conductance variable from a home-made analog sensor.
Construct a new AnalogElecConductivity_
AnalogElecConductivity_
Parameters
parentSense
The parent AnalogElecConductivity providing the result values.
uuid
A universally unique identifier (UUID or GUID) for the variable; optional with the default value of an empty string.
varCode
A short code to help identify the variable in files; optional with a default value of "anlgEc".
- #define ANALOGELECCONDUCTIVITY_EC_RESOLUTION = 1
- Decimals places in string representation; EC should have 1.
- #define ANALOGELECCONDUCTIVITY_EC_VAR_NUM = 0
- Sensor variable number; EC is stored in sensorValues[0].
- #define ANALOGELECCONDUCTIVITY_EC_VAR_NAME = "electricalConductivity"
- Variable name in ODM2 controlled vocabulary; "electricalConductivity".
- #define ANALOGELECCONDUCTIVITY_EC_UNIT_NAME = "microsiemenPerCentimeter"
- Variable unit name in ODM2 controlled vocabulary; "microsiemenPerCentimeter" (µS/cm)
- #define ANALOGELECCONDUCTIVITY_EC_DEFAULT_CODE = "anlgEc"
- Default variable short code; "anlgEc".
Define documentation
#define ANALOGELECCONDUCTIVITY_NUM_VARIABLES = 1
Sensor::
#define ANALOGELECCONDUCTIVITY_INC_CALC_VARIABLES = 0
Sensor::
#define ANALOG_EC_ADC_RESOLUTION = 10
Default resolution (in bits) of the voltage measurement.
The default for all boards is 10, use a build flag to change this, if necessary.
#define ANALOG_EC_ADC_MAX = ((1 <<
The maximum possible value of the ADC - one less than the resolution shifted up one bit.
#define ANALOG_EC_ADC_RANGE = (1 <<
The maximum possible range of the ADC - the resolution shifted up one bit.
#define ANALOG_EC_ADC_REFERENCE_MODE = DEFAULT
The voltage reference mode for the processor's ADC.
For an AVR board, this must be one of:
DEFAULT
: the default built-in analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards)INTERNAL
: a built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328P and 2.56 volts on the ATmega32U4 and ATmega8 (not available on the Arduino Mega)INTERNAL1V1
: a built-in 1.1V reference (Arduino Mega only)INTERNAL2V56
: a built-in 2.56V reference (Arduino Mega only)EXTERNAL
: the voltage applied to the AREF pin (0 to 5V only) is used as the reference.
If not set on an AVR board DEFAULT
is used.
For the best accuracy, use an EXTERNAL
reference with the AREF pin connected to the power supply for the EC sensor.
For a SAMD board, this must be one of:
AR_DEFAULT
: the default built-in analog reference of 3.3VAR_INTERNAL
: a built-in 2.23V referenceAR_INTERNAL1V0
: a built-in 1.0V referenceAR_INTERNAL1V65
: a built-in 1.65V referenceAR_INTERNAL2V23
: a built-in 2.23V referenceAR_EXTERNAL
: the voltage applied to the AREF pin is used as the reference
If not set on an SAMD board AR_DEFAULT
is used.
For the best accuracy, use an EXTERNAL
reference with the AREF pin connected to the power supply for the EC sensor.
#define ANALOG_EC_ADC_REFERENCE_MODE = AR_DEFAULT
The voltage reference mode for the processor's ADC.
For an AVR board, this must be one of:
DEFAULT
: the default built-in analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards)INTERNAL
: a built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328P and 2.56 volts on the ATmega32U4 and ATmega8 (not available on the Arduino Mega)INTERNAL1V1
: a built-in 1.1V reference (Arduino Mega only)INTERNAL2V56
: a built-in 2.56V reference (Arduino Mega only)EXTERNAL
: the voltage applied to the AREF pin (0 to 5V only) is used as the reference.
If not set on an AVR board DEFAULT
is used.
For the best accuracy, use an EXTERNAL
reference with the AREF pin connected to the power supply for the EC sensor.
For a SAMD board, this must be one of:
AR_DEFAULT
: the default built-in analog reference of 3.3VAR_INTERNAL
: a built-in 2.23V referenceAR_INTERNAL1V0
: a built-in 1.0V referenceAR_INTERNAL1V65
: a built-in 1.65V referenceAR_INTERNAL2V23
: a built-in 2.23V referenceAR_EXTERNAL
: the voltage applied to the AREF pin is used as the reference
If not set on an SAMD board AR_DEFAULT
is used.
For the best accuracy, use an EXTERNAL
reference with the AREF pin connected to the power supply for the EC sensor.
#define RSERIES_OHMS_DEF = 499
The default resistance (in ohms) of the measuring resistor. This should not be less than 300 ohms when measuring EC in water.
#define SENSOREC_KONST_DEF = 1.0
Cell Constant For EC Measurements.
This should be measured following the calibration example on https:/
Mine was around 2.9 with plugs being a standard size they should all be around the same. If you get bad readings you can use the calibration script and fluid to get a better estimate for K. Default to 1.0, and can be set at startup.
#define ANALOGELECCONDUCTIVITY_STABILIZATION_TIME_MS = 1
Sensor::
#define ANALOGELECCONDUCTIVITY_MEASUREMENT_TIME_MS = 0
Sensor::
It's not really quite instantly, but it is very fast and the time to measure is included in the read function. On ATmega based boards (UNO, Nano, Mini, Mega), it takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.
#define ANALOGELECCONDUCTIVITY_EC_RESOLUTION = 1
Decimals places in string representation; EC should have 1.
Range of 0-3V3 with 10bit ADC - resolution of 0.003 = 3 µS/cm.
#define ANALOGELECCONDUCTIVITY_EC_VAR_NUM = 0
Sensor variable number; EC is stored in sensorValues[0].
#define ANALOGELECCONDUCTIVITY_EC_VAR_NAME = "electricalConductivity"
Variable name in ODM2 controlled vocabulary; "electricalConductivity".
#define ANALOGELECCONDUCTIVITY_EC_UNIT_NAME = "microsiemenPerCentimeter"
Variable unit name in ODM2 controlled vocabulary; "microsiemenPerCentimeter" (µS/cm)