DIY EC sensor

OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Alright, I had a look at different ADC components in those microcontrollers and it seems that most of them are somewhat sufficient. Using a 1kHz frequency I only need something above 10 kilo samples per second (ksps) or 10 kHz. I would only have to test whether the microcontrollers also have the speed to multiply and add with this frequency on top of I2C communication.

I could use an ATtiny84, since it has a lot more pins than an ATtiny85. Problem is the price point, since an ATtiny84 costs 4-5$ plus the hardware required for programming it. I could possibly DIY a programmer using a Pi Zero I have lying around, but that's a lot of effort, so I will postpone this (probably by a lot).

I will start testing with a Pi Pico, since that seems to be the simplest and cheapest option.


I also had a look at the limitations of the ADC. Using a 10bit resolution ADC I would "only" reach a resolution of about 1023 steps (2^10-1) in the 3.3V reference range, e.g. roughly 3.2 mV. This would "only" give me a conductivity resolution of roughly 1%, e.g. 10 µS/cm steps at 1,000 µS/cm or 200µS/cm at 20,000 µS/cm.
With a 12bit ADC this might improve about 4 times, so even more argument to use a Pi Pico (or similar).


In the meantime I will try to improve the analog circuit I have been testing so far.
 

robsworld78

Well-Known Member
View Badges
Joined
Feb 14, 2020
Messages
985
Reaction score
1,325
Location
Edmonton, Canada
Rating - 0%
0   0   0
Alright, I had a look at different ADC components in those microcontrollers and it seems that most of them are somewhat sufficient. Using a 1kHz frequency I only need something above 10 kilo samples per second (ksps) or 10 kHz. I would only have to test whether the microcontrollers also have the speed to multiply and add with this frequency on top of I2C communication.

I could use an ATtiny84, since it has a lot more pins than an ATtiny85. Problem is the price point, since an ATtiny84 costs 4-5$ plus the hardware required for programming it. I could possibly DIY a programmer using a Pi Zero I have lying around, but that's a lot of effort, so I will postpone this (probably by a lot).

I will start testing with a Pi Pico, since that seems to be the simplest and cheapest option.


I also had a look at the limitations of the ADC. Using a 10bit resolution ADC I would "only" reach a resolution of about 1023 steps (2^10-1) in the 3.3V reference range, e.g. roughly 3.2 mV. This would "only" give me a conductivity resolution of roughly 1%, e.g. 10 µS/cm steps at 1,000 µS/cm or 200µS/cm at 20,000 µS/cm.
With a 12bit ADC this might improve about 4 times, so even more argument to use a Pi Pico (or similar).


In the meantime I will try to improve the analog circuit I have been testing so far.
That sounds like a great idea, we can easily add a placeholder for the Pico on the EC PCB, a person just needs to solder the pins being used so shouldn't be too difficult. It'll also look good and no wires that could affect the readings. :)
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Alright, since I decided to run the PI Pico as an I2C slave (WiFi would probably be possible as well in the Future) I need to program it using either C/C++ or the Arduino IDE.

Does anybody have any experience doing that ? For simplicity I’ll probably start with the Arduino IDE. From what I gathered that seemed to be the fastest and easiest start. If necessary for performance reasons and such, I’ll go to C later.
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
I revisited the analog circuit I built. As it turns out: the capacitance multiplier I built earlier is actually counter productive in this case. I measured the voltage after it as ~4.1 V. Seems as that's not enough headroom for the 3.3V regulator, so the voltage quality drops.

If I remove that capacitance multiplier the ripple is a bit higher, but the regular VCC drops from the other consumers are gone and the ripple is still low enough:
B4B12BBA-E6FD-43BE-91F8-C533ED6F40E2.jpeg


Output voltage signal is now also perfectly stable as measured with a multimeter. So keep in mind: leave your regulators enough headroom :grinning-face-with-sweat:
 
Last edited:
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
As mentioned, I have removed one of the input filters on the circuit. I will finalize the design and publish it here and on GitHub if anybody is interested. It does however use quite a lot of components as you can see:
002813DD-E445-42D4-9348-139F16906002.jpeg

The electrical switch IC on the left is not even included yet.
I therefore think that the microcontroller approach is much better. I have started programming my Raspberry PI Pico with the Arduino IDE and am coming along nicely. I will post an update later when I finish the LockIn Test I am setting up right now.
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
As mentioned, I got the Raspberry Pi Pico to work in the Arduino IDE. I can output a PWM at 1 kHz and sample that with 10-100 point per cycle. Below is an example where I sample both the PWM voltage @ 3.3V 1kHz and the intermediate voltage between two "identical" resistors:
1666520610436.png


Works fine, there are some limitations however:
I cannot set a precise sample timing for the ADC, so I have to do that manually. This results in discrepancies, as you can see above, value1 (blue) is still measured low at sample 958, whereas the sample of value2, measured directly afterwards (about 10µs delay ?), already measures high.

My two attempts at timing so far are:
- use interrupts to detect the flanks and flip a phase from +1 to -1 and vice versa
----> still sporadic discrepancies between this phase and the ADC reading
- get the samples of both excitation and measurement immediately after each other (see above)
----> still sporadic discrepancies

I'll continue trying a few things. Maybe I'll have to live with this. When I play around with the timings I can get the error rate down to 0.1%, which might be enough with some filtering.
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Solved it, I'm now at an error rate well below 0.01%.

For anybody who is interested:
instead of logging the flanks using interrupts seperately from the periodic ADC readings, I now start taking ADC readings exactly after a flank has been detected. That way I ensure that the flank always happens before the first reading is taken. Afterwards I take 10 readings before the next flank comes.

Onwards ^^
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Alright, I built the excitation test circuit on the microcontroller:
055917E7-2A21-4692-B4E5-CD285C7D79F0.jpeg


- PWM is output at Pin #20 on the top left corner and fed back into the Pins #19 and #17.
- The PWM goes through one of the two resistors on the top left, as decided by the CMOS analog switch, controlled by the blue wires.
- The PWM then goes through one of the two resistors at the bottom: either the drift correction resistor or the measurement probe, currently replaced by a resistor.

Because the AC coupling leads to negative voltages on the switch circuit, I had to protect power and GND leads with diodes. Sadly the switch IC still distorts the output voltage and introduces a DC offset of 0.15V that would go into the water.

So either I omit the whole analog switch IC and therefore omit the ability to switch ranges and correct drift, or I omit the AC coupling and do the same setup as @robsworld78 : use a 5V power and I2C isolator (which I sadly would need to buy).

I'll test both methods and see if I even need drift correction.
 

robsworld78

Well-Known Member
View Badges
Joined
Feb 14, 2020
Messages
985
Reaction score
1,325
Location
Edmonton, Canada
Rating - 0%
0   0   0
Alright, I built the excitation test circuit on the microcontroller:
055917E7-2A21-4692-B4E5-CD285C7D79F0.jpeg


- PWM is output at Pin #20 on the top left corner and fed back into the Pins #19 and #17.
- The PWM goes through one of the two resistors on the top left, as decided by the CMOS analog switch, controlled by the blue wires.
- The PWM then goes through one of the two resistors at the bottom: either the drift correction resistor or the measurement probe, currently replaced by a resistor.

Because the AC coupling leads to negative voltages on the switch circuit, I had to protect power and GND leads with diodes. Sadly the switch IC still distorts the output voltage and introduces a DC offset of 0.15V that would go into the water.

So either I omit the whole analog switch IC and therefore omit the ability to switch ranges and correct drift, or I omit the AC coupling and do the same setup as @robsworld78 : use a 5V power and I2C isolator (which I sadly would need to buy).

I'll test both methods and see if I even need drift correction.
Looking really good. I think either way isolation will be needed as probes will interfere with each other in the same body of water. During your testing it might be good to drop a pH probe in the same water to see the effects. If you don't want to add the extra components DF Robot has one available.

 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Ha, got the measurement down to what I want. The output signal is resolved and stable far below the least significant bit (I scaled the output to 12 bit resolution, e.g. 0 to 4095). You can see the signal is stable in the first digit after that, measurement is 1 value per second:
1666860232020.png

Even if I wobble the components the changes are not significant, still well below 1 bit:
1666860186809.png

If I change the test resistor (I added a ~3.1k parallel to the previous 1.4k equaling to about 0.96k). The Output takes 4-6 s, exactly as expected for the desired filter constant of 1s:
1666860066786.png


The signal changes from 2022.3 to 1663.5, which calculates to test resistor values of 1.38k and 0.97k, which is perfectly within the 1% tolerance of the used resistors.

I'll play around with the circuits accuracy, range and stability. In the meantime I'll look if I can find that isolator.
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Alright, I improved the calculation. I found a systematic offset and improved the noise ... to zero ^^
e.g. I hit the 32bit resolution limit of the regulars floats ^^
I switched to double precision (64bit) and tested the measured values and noise over the desired range (assuming a standard K=1.0 probe):
Resistor= ConductivityMeasured ValueNoise
none 0 µS/cm~ 17.025 µS/cm (+/- 1%)~ 0.005 µS/cm
1419 Ohm (+/- 1%) 704.7 µS/cm (+/-1%)~ 722.065 µS/cm (+/- 1%)~ 0.01 µS/cm
97.6 Ohm (+/- 1%)10245.9 µS/cm (+/- 1%)~10696.0 µS/cm (+/- 1%)~ 0.5 µS/cm
19.1 Ohm (+/- 1%)52356.0 µS/cm (+/- 1%)~51070.0 µS/cm (+/- 1%)~10 µS/cm

Seems that I still have an offset in the measurement, but it is looking good ! So Noise is typically lower than 0.02% and far from the upper end even lower than 0.002%. That means I can easily resolve changes in conductivity of about 0.01%:
Noise_CalcInBetween_1419Ohm+11MOhm.png


Looks great, so the circuit should work almost as good for salt water and a standard K=1.0/cm probe. Downside for salt water is of cource the increased current flow, but that should still be around 1mA, so not sure if that is harmfull for marine life. As mentioned, humans react to currents around 10mA, lethality onsets somewhere there as well, around 20-30mA,

[Addition]: Just found this article. There are seemingly some species are sensitive to electric fields:
"Elasmobranchs, such as sturgeons, sharks, skates, and rays utilize natural EM fields in their daily
lives and, as a result, are at a higher risk of influence from anthropogenic EMF sources than non-
electrosensitive species."

The resulting behavior is that they attack/avoid the source of electric fields depending on the strength.
 
Last edited:

Ranjib

7500 Club Member
View Badges
Joined
Apr 16, 2016
Messages
9,848
Reaction score
17,081
Location
Pleasant Hill, Concord
Rating - 0%
0   0   0
this is an epic journey. I love so much reading through your posts. These intricate details will help us replicate, rebuild such system. Im super looking forward to what you settle with at the end :-0), and when it happens, how it will be. I'll build one, if nothing to learn electronics fundamentals .
thank you
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
this is an epic journey. I love so much reading through your posts. These intricate details will help us replicate, rebuild such system. Im super looking forward to what you settle with at the end :-0), and when it happens, how it will be. I'll build one, if nothing to learn electronics fundamentals .
thank you
Thank you as well for providing my current hobby ;)

I'm pretty sure that I will settle with the microcontroller version in some shape or form, since the resolution is vastly superior. I'll still have to test whether this needs electrical isolation in a real tank for stable measurements. I'm currently interested in trying it like it is. The AC coupling should limit interference for the pH probe and together with the LockIn detection technique at 1kHz it should make the reading somewhat resistant against outside interference from other components. If that works, I have a built-in Grounding probe, since one of the probe's electrodes is always at circuit GND ^^

I was slightly struggling with deviations of the measured values from what they should be. I'm pretty convinced that this comes from the ADC, as it clips the top of my 1kHz waveform differently for different test resistors:
1667660199851.png

The Maximum of the ADC is 12bit, so a value of 4095, which is SUPPOSED to be 3.3V. The Raspberry Pi Pico is however, not allmighty and it buys its versatility with imperfections. The ADC is both fed and referenced by the onboard 3.3V rail. This is filtered with a RC lowPass of 200 Ohm and 2µF, but since the ADC itself draws something in the range of 100-200µA through this, this supply current results in a drop of ~20-40 mV, so the actual Reference voltage (e.g. a value of 4095) it not 3.3V, but 3.27V.
I have found a solution however: you can feed the ADC directly from 3.3V, bypassing the 200 Ohm. This increases noise, but extends the measurement range to 3.3V.

A similar thing happens at GND, where the value doesn't drop perfectly to 0, but has an offset of ~10:
1667660278101.png

That's however a known "problem" and not a concern for me, since I just need to measure the waveform in it's entirety to compare bottom and top level.
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Alrigth, I was able to correct the clipping at the upper end. As mentioned in the previous post, this comes from a systematic offset in the reference voltage pulled through the RC LowPass filter (which reduced noise). This can be overcome by connecting the 3.3V OUT with the ADC ref pin, bypassing the RC filter:
1667999410577.png
1667999648453.png


As mentioned, this raises my measurement range to 3.3V, instead of around 3.27V, with the downside of increasing noise. Since I am doing digital filtering afterwards, I don't realy care about the noise:
1667999906500.png

yAxis is ADC bins and xAxis is measurement number (roughly one measurement per 50µs). Comparing to the previous post you can see that the values no longer hit the 12bit maximum value of 4095. As I could have thought, this was not the solution to the dicrepancies, however, as the clipping is rather small compared to the actual value, e.g. something like 10/4095 = 0.24%.

I did however see much larger discrepancies up to 1.6% (see the "raw" values):
ResistanceDeviation_Corrected_Model.png


Then I remembered the details of the Pi Pico ADC, which has (large) systematic errors. This was later updated in the official RP2040 datasheet. It basically says that the bin numbers 0...4095 that the ADC gives are not perfectly linear due to mistakes in design/manufacture and has large systematic errors:
1668000521453.png

The graph shows this error in bins (yAxis) vs the bin number (xAxis 0...4095).
It basically means if the ADC shows you a value of ~600 it's actually ~606, e.g. 600 + the plotted value @600. If you correct for this, you get much better results, as you can see in the graph above for the orange "corr" curve. The spikes are much lower, representing the accuracy of the multimeter used to determine these resistances, rather than my circuit. The values also have a constant error of around 0.3%, but I thinbk that has the same origin. It's the accuracy of my reference resistor measured with my multimeter (if that's 0.2% too large, all measured results will be 0.2% too large as well). As soon as I calibrate the circuit properly with a conductivity reference solution this should vanish.

Great stuff !
Now I'll have to transfer this correction to the Pi Pico and see if it still works there.

Another thing I want to try: A notorius problem with my current circuit is the lackluster accuracy at high conductivities and the high currents the circuit will put through the water at these conditions. I do however have a possible solution to this problem. I can use header pins so the user can manually choose a larger resistor by placing a short. This will DECREASE the signal over the test resistor even further, BUT I can use the third ADC Input to permanently connect an Operational Amplifier to boost the signal in those situations.

If that works I think I will be ready to prototype a PCB.

Stay tuned ;)
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Recreated the Model Transfer Function on the Pico:
INL_plot.png

Looks identical to me. I didn't bother to copy all 4096 values by hand, so the first 700 need to suffice ^^

INL correction also works, I'll check the circuits calibration later and send you the results :)
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
Done, I still encountered further discrepancies at low resistances, e.g. high conductivities of 10.000 to 50.000µS/cm (blue curve):
1668366685211.png

I could however nail that down by slightly improving the model for the Integral Nonlinearity. That results in something like the orange curve. I think that's good enough to assume that there are no huge discrepancies left. The only thing that should dominate the deviation now are the uncertainties on the test resistors.

I'll go and try 10 resistors of each type to see the spread and try to get a good estimate for my circuit's accuracy in the next days.
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
As mentioned earlier my current problem is getting an accurate series of resistors to test the linearity of my circuit. I therefore tried 6-8 resistors of every one that I used, in the hope that they have a nice spread around their tabulated value. This still results in discrepancies of the average values:
1668966798340.png

gray dots are the different resistors measured with the circuit, black is their average
orange dots are the different resistors measured with my multimeter, red is their average

Since I wasn't sure that these discrepancies come from my circuit, I tested the resistors with my multimeter as well and as you can see, it shows the same discrepancies. I am therefore going to assume, that the discrepancies come from the resistors NOT scattering around their tabulated value, but having systematic offsets, since both my measurement methods show this discrepancy.

I therefore tested another method to get an indication of the circuit's linearity in measured resistance. I used the 3250 and 390 Ohm resistors I have already used above and connected them in parallel. In theory, they should be similar to about +/- 0.2% as you see above. I can therefore test a resistor scale that's definitely linear to about +/- 0.2% if I connect those in parallel. Well, as you can see it didn't quite work as expected if you only look at one series:
1668969248496.png


That varies widely. If you compare both series though, you can see that this error is actually systematic in the number of resistors, not the resistance itself. I therefore expect that this comes from contact resistance on the breadboard since I connected resistor Nr1 to 7 always in more or less the same spot. If you look at the discrepancy between the two series, it is 0.1% at maximum. This 0.1% results from both the circuit AND the resistor's inaccuracies.

I am therefore confident that the circuit is able to measure accurately to 0.1% as it is and that anything else that pops up can be handled with software.


Next up: test how well I can boost signals for high conductivities using an OP-Amp.
 
Last edited:
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
I build the Amplification circuit and immediately noticed a problem: my signal is centered at the middle of my 3.3V range, so I can measure the full waveform from bottom to top. So my signal is ~1.65V on average. If I simply amplify this by a factor of 10, the output signal would try to reach 16.5V, which it can't so it simply stays at my VCC voltage of 3.3V :grinning-face-with-sweat:

I had to devise a difference Amplifier that again ends up centered at ~1.65V which meant finding fitting resistor values in my arsenal. That took some time, but I managed it:
1669748749009.png

Value 1 (blue) is my excitation voltage.
Value 2 (red) is my test voltage
Value 3 (green) is my 10x amplified test voltage
value 4 the fraction of value1 divided by value 2

As you can see it more or less works as intended. The amplified signal is still more or less in the middle. The deviation results from the imperfect resistor values I had to use. The oscillation on top is amplified as well. Sweet. Now to look at the resulting signal:
Signal_NoAmp_19,7_Ref1400.png
Signal_Amp_19,7_Ref1400.png

Left is original without Amplifier, Right is with the Amplifier
The value itself is off, since I haven't calibrated the amplification factor precisely yet, but the noise is pretty much the same at about +/- 20 µS/cm.
That is somewhat interesting, since it means most of this noise comes from external electrical noise and simply get's amplifed as well. If some of this noise came from the inaccuracies of the ADC I would have expected the noise to actually decrease.

Well, this means I can still try to measure very high salt-water conductivities with a higher reference resistor to protect the marine life:
Signal_NoAmp_19,7_Ref10020.png
Signal_Amp_19,7_Ref10020.png

Left is original without Amplifier, Right is with the Amplifier

Finally there is a difference between the two ! I was starting to worry, whether this effort has been for nothing :grinning-face-with-sweat:
Without the amplifier the noise is much larger, about +/- 150µS/cm. However, WITH the amplifier Noise is down to about +/- 50µS/cm. Worse than before, but at 0.1%


Again, this would have the benefit of limiting currents through the water to non-dangerous 0.16 mA instead of possibly harmful 1.6mA.
Now to decide: would somebody even want this added protection feature for his marine life ? :grinning-face-with-sweat:
After all, the typical conductivity probes are well shielded behind some glass, so that only a small shrimp could possibly enter and get high on some sparks ...
 
OP
OP
S

Sral

Valuable Member
View Badges
Joined
May 2, 2022
Messages
1,006
Reaction score
978
Location
Germany
Rating - 0%
0   0   0
My probe looks like this:
image.jpg

The opening is very small, just 12 mm in diameter and the slits on the sides have about 4-5mm width. Inside you have a glass ring blocking the entrance even further, and within that ring are the two square electrodes, one of which you can just about see in the picture.

how do your probes look like and would you be afraid of jolting the smaller marine life in your tank that could get in there ?
 

Ranjib

7500 Club Member
View Badges
Joined
Apr 16, 2016
Messages
9,848
Reaction score
17,081
Location
Pleasant Hill, Concord
Rating - 0%
0   0   0
My probe looks like this:
image.jpg

The opening is very small, just 12 mm in diameter and the slits on the sides have about 4-5mm width. Inside you have a glass ring blocking the entrance even further, and within that ring are the two square electrodes, one of which you can just about see in the picture.

how do your probes look like and would you be afraid of jolting the smaller marine life in your tank that could get in there ?
for the marine life, i wont worry. i worry more abut the probe getting clogged. but if its easy to detect and clean up.. i think rest is fine. we can alway put it inside a plastic/3d printed harness, like the power heads?
 
Back
Top