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 supplied 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 resistance 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):
\[meas\_voltage = \frac{analog\_ref\_voltage * raw\_adc\_bits}{ANALOG\_EC\_ADC\_RANGE}\]
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:
\[meas\_voltage = \frac{sensor\_power\_voltage * raw\_adc\_bits}{ANALOG\_EC\_ADC\_RANGE}\]
Now we can calculate the resistance of the water, knowing the resistance of the resistor we put in the circuit and the voltage drop:
\[R_{water\_ohms} = \frac{meas\_voltage * R_{series\_ohms}}{sensor\_power\_voltage - meas\_voltage}\]
Combining the above equations and doing some rearranging, we get:
\[R_{water\_ohms} = \frac{R_{series\_ohms}}{\frac{ANALOG\_EC\_ADC\_RANGE}{raw\_adc\_bits} - 1}\]
The conductivity is then the inverse of the resistance - multiplied by a measured cell constant and a 10^6 conversion to µS/cm.
\[water\_conductivity = \frac{1000000}{R_{water\_ohms} * sensor_{EC\_Konst}}\]
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 MS_PROCESSOR_ADC_RESOLUTION=##
- used to set the resolution of the processor ADC
-D MS_PROCESSOR_ADC_REFERENCE_MODE=xxx
- used to set the processor ADC value reference mode
Sensor Constructor
AnalogElecConductivity:: AnalogElecConductivity(int8_t powerPin,
int8_t dataPin,
float Rseries_ohms = 499,
float sensorEC_Konst = 1.0,
uint8_t measurementsToAverage = 1)
Construct a new AnalogElecConductivity object.
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 | 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
|
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 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.
AnalogElecConductivity_ EC:: AnalogElecConductivity_EC(AnalogElecConductivity* parentSense,
const char* uuid = "",
const char* varCode = "anlgEc")
Construct a new 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 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)