P2 - Very strange behavior with analog 0-2.5V analog input - Zero Drift?

There are a lot of very smart people out here in the Particle community I'm hoping I can get some insight or ideas on what I'm doing wrong. It's a bit unclear if this is a board design issue, sensor issue, firmware issue on the P2, ground loop, some impedance issue or maybe I'm doing something dumb in the user application code.

I am using the P2 and a Hydrostatic Sensor to detect the level of a liquid in a tank. It displays this liquid level locally on a 16x2 LCD display as well as animates it via an LED strip. I call it a LED sight glass.

The first 1 hour, 12 hour or even 24 hours it works great. It's very accurate and overall I am very happy with it. However, some seemingly random duration of time from being first turned on, the analog input will "jump" up by ~ 0.15 Volts. If I leave it all hooked up and powered on over night, I'll walk in in the morning and instead of saying the tank is 0", it'll say there is 7" of liquid in the tank.

The hydrostatic sensor itself is just a basic ratiometric sensor.
VCC: 3.3V
Vout: 0-2.5V
Range: 0-39"
At 0" of liquid level (i.e. no liquid in the tank) Vout = 0.005 V.
At ~7" of liquid level Vout = ~0.15V

image

In this case, Vout is tied to A0 on a Particle P2. What I can not explain is the following behavior:

A few other unproven general observations:

  • One person indicated simply powering it off and back on does not fix the issue.
  • I am using this same sensor on Boron's and I've yet to observe the issue there although not adequately tested side by side.

A few hypothesis I need to test:

  • Can I repeat the issue on a different Analog input pin on the P2?
  • Can I repeat the issue on a different Particle Device (Boron or otherwise)?
  • Can I repeat the issue using just a simple voltage divider circuit on pin A0 of the P2?
  • Do I need to add some large resister value or a Capacitor from Vout of the sensor to GND?
  • The sensor cable has a shield as well. Can I reproduce it if the shield is tied to GND?
  • Does it still happen if I turn off VCC to the sensor when not taking a reading? I.e. turn it on ONLY when i need to take a reading and then turn it off. I need to take readings near real time but maybe I'd turn it off for 1 second every 60 seconds or something like that. I currently have a transistor I control from a GPIO pin to turn power on/off to the sensor. Currently I leave it on all the time. But maybe I need to cycle it occasionally. This seems like a "hack" vs fixing the root cause though.

I've already been in contact with the hydrostatic sensor supplier. They've indicated they have never seen this behavior before as well. Any idea what this could be? Or what additional tests should I consider to help identify this issue?

Any help or suggestions would be greatly appreciated. @bko - If I recall, you have some special expertise and background in the analog signals and filtering space, Any thoughts.

Here is another strange piece to the puzzle... the dynamic seems to be different if I power it by a straight USB wall outlet, a USB adapter plugged into a 110VAC outlet (both incorrect behavior). Then when I use a standalone USB battery bank (or when plugged into my computer USB port) it reads correctly the entire time.

I'm truly stumped...

As you mentioned, you could try a largish "bleeding" resistor between A0 and GND to get rid of any (potential) capacitive build-up of charge.

Alternatively you could try to discharge any such charge via another GPIO instead of depowering the entire unit using a transistor (as you also mentioned).
Just hook the largish resistor between A0 and any other GPIO which you could regularly switch from INPUT to OUTPUT LOW and back or without extra resistor from INPUT to INPUT_PULLDOWN and back.
This way you can control when that "discharge" happens so that it won't interfere with your measuring cycle.
Instead of doing this on a regular basis you could do that on demand, when you detect a sudden change in the analog reading.

The "puzzle" about the difference between battery vs. USB power may come from the noise your USB adapter may produce - which a battery obviously doesn't.

If the current demand of the sensor allows ( < 500mA), you could also take its Vcc from the Photon 2's 3v3 pin rather than directly from the source. This way you make sure that the reference voltage for the two devices is exactly the same.

1 Like

@ScruffR - Thanks for the guidance and ideas. I've never seen a "build up of charge" before like this on an analog input so I greatly appreciate the guidance. In the next version of the board I'll likely add the secondary GPIO method as that seems like a little better than just turning power on/off. Disadvantage of the P2 is it's a bit harder to add that in. :slight_smile:

And yeah using a GPIO to power it instead of 3V3 pin will also be a good improvement. I'm pretty sure it takes a marginal current. However, I used a transistor to give it some freedom to use other types of devices that I knew couldn't be powered by a standard GPIO. If I used GPIO it would prevent a few other devices from being used.

My initial workaround is this within Loop:

        //This should not be needed but let's give it a try anyhow. We use a GPIO to drive a transister to power the sensor. Let's cycle it off for 1/2 second once every 30 seconds. Delay an additional 1/2 second after powering it on to give it time to power up before taking another reading. 
        if(millis() - lastOutputOffTime >= 29000) {
            digitalWrite(SensorPower, HIGH);
            delay(500);
            digitalWrite(SensorPower, LOW);
            delay(500);
            lastOutputOffTime = millis();
        }

This seems like a "hack" but so far, the hack seems to work. Is this type of trickery normal for low voltage 0-2.5V analog inputs? I also am using a 15' cable and at times I can add in another 15' "extension" so up to 30'. Is this just capacitance of the cable that is causing this and what I'm seeing is somewhat expected? Is it just a poorly chosen supplier for the Hydrostatic sensor? I like all the workaround suggested but trying to understand what's happening here for my understanding.

Nope, as your comment mentions, "this should not be needed" :wink:

IMHO the chip the P2 is based on appears to be more finicky in many aspects than the previous generations were - I'm still bummed that the STM32 based Particle devices had to be phased out :pensive:

3 Likes

First some background:

I have seen the "charge can build up" kind of problem before, particularly when the analog input (A/D) being driven is very high impedance. You can set the input impedance to say 1Mohm with a 1Mohm resistor from the input to ground in cases like this. 100k ohm or even 10k ohm would be fine here too, I think. It might help, but I think your problem is noise related.

You don't say what kind of cable you have between the sensor in the tank and the board or how long that cable is. Cables can have a phenomenon known as dielectric soakage where charge builds up in the dielectric of the cable. Certain types of cable show this effect more easily such coax with high dielectric material, but any kind of cable can in theory be affected. I don't really think you have this problem since you have a pretty simple DC signal here, but if you have more than say 50 ft or 15 meters of high dielectric cable it could be a problem. Lowering the input impedance can help with this problem, but the only real solution for dielectric soakage is to use an AC signal on the cable that does not have any long-term DC bias. That seems a bit hard here.

Another problem with long cables is noise being induced on them from their environment. This can cause problems like you are seeing even when the noise is common mode (that is, induced in to both wires of the cable). This is why a lot in industrial low-voltage signals use RS 485 or 4-20mA current loop techniques to suppress the induced noise. Twisted pair cabling is often a good choice in noisy environments. If you are using coax cable, connecting the shield to ground at only one end would be good.

You didn't say if the tank is metal and if the signal ground is connected to it. I would avoid connecting electrically to a metal tank if possible. It could be a noise source since the outside of the tank is subject to noise (the metal tank does act as a Faraday cage blocking noise on the inside, but not on the outside). If the tank is metal, is it grounded to the earth? Dissimilar metals can also induce voltages via galvanic action and certain metal pairs are best avoided like aluminum and stainless steel.

Your experiment with the USB power pack is very interesting! I wonder if the noise is such that any added noise from the AC powered USB sources is pushing something over the edge.

Finally your code solution of turning it off and on again is a time-honored technique, but I think it would be best to find the source of the problem.

Since your sensor is basically a DC level, I would try a common-mode choke to help block noise. This is an inductor that has two separate paths for signal and ground that are wound on to a common ferrite. The idea is that noise induced on the cable signal and ground will be cancelled out. You could also try a ferrite bead or other inductor on just the signal side. A capacitor to ground or RC filter for low-pass filtering--that can be helpful too, but as you increase the capacitance you slow down the response rate of the sensor, so you have to make a trade-off there.

Can you put a scope (or other data-logger) on the sensor signal and try to see what happens over time? Be careful with the scope ground since the probe ground is typically connected to earth ground when the scope is plugged in. With a scope you can try the USB AC power vs. the battery pack and see what is happening there too. If you don't have a scope, you might try two of your devices connected to the same sensor, one powered from battery and one from AC USB power, but I think the battery powered one with just work.

So that was a long-winded way of saying, my gut feeling is you have an electrical noise problem.

6 Likes

Pin drive strength for the P2 and Photon 2 is now included in the Device OS firmware API documentation and datasheets.

  • The drive strength on the P2 and Photon 2 is 4 mA per pin in normal drive and 12 mA per pin in high drive mode.
  • There is a maximum of 200 mA across all pins. On the P2, the total maximum could be further limited by your 3.3V regulator.
  • Drive strength selection is only available in Device OS 5.5.0 and later on RTL872x devices.
3 Likes

I'd think that your tests from various power sources points towards your initial issue being noise from the supply.

General Question : When using ratiometric analog pressure sensors in the past, I'd measure the Vcc with another GPIO instead of assuming (3.3 / 4095.0) in the calculation. That could range from 3.27V to 3.38V. I felt like that was accomplishing "something" , but I'm obviously not sure.
Maybe you can identify the Voltage change at the sensor's Vcc input when it starts reading 6-7" of water ?

After that, I'm pretty sure 15' and 30' of cable will be a headache for you. And a lot of what @bko discussed can change for each installation environment.

I got around this by bringing the pressure source much closer to my MCU & Sensor by using very small flexible tubing instead of the long runs of wire (acting as an antenna). Since the liquid isn't "flowing" in the tube, there is no pressure loss. There's almost no magic VooDoo that can happen to a water pipe.... that can't be said for long low-voltage analog wires.

I generally use 4mm tubing with the quick connectors [ and I²C sensors when possible :slight_smile: ] .
image

This might not be an option for your project, but I wanted to mention it just in case.

4 Likes

One technique that I have used for remote sensors is to put a voltage regulator and I2C ADC (ADS1015) at the sensor and use a TI P82B715DR I2C redriver on both ends of the cable. This greatly extends the length allowed, and you can also run the bus at higher voltages for greater noise resistance (5V to 12V). You can also run the ADS1015 at 5V which can also come in handy for certain sensors.

4 Likes

You wouldn't have a rough schematic for one of those re-driver cables do you?

@bko - Thank you very much for the detailed response. Looks like I have some more homework to do. I was foolishly thinking this application was going to be stupid simple. Because really... how hard can it be to detect liquid level in a tank and light up some LEDs. :rofl: but obviously I'm eating my own words a bit.

Seems like I have a few options:

  • Continue with the same ratiometric (0-2.5 Volt) sensor and lower the input impedance, maybe use a GPIO pin to power it, add an on board small battery to stabilize the power, add a choke, etc.
  • Switch to I2C version of the sensor. My board already ha an I2C port on it but as discussed, this too may limit range or I can deploy some of Rick's suggestions. I'm in the 30-60' range. Nearly all setups are in the 30'.
  • Switch to a different sensor altogether. I previously used an ultrasonic sensor but it was a bit of a pain to assemble and a bit more finicky to setup.

Appreciate everyone's thoughts and ideas... Unless there is some additional software wizardry I can deploy, it seems most solutions are dependent upon hardware changes. I'm kind of stuck with what I have for the next 2 months or so but then will dive deep into the hardware at that time.

Much appreciated!!!

1 Like

Something else that hasn't been mentioned yet :
Send your level reading wireless to your existing Particle/screen.
That of course requires another battery or power source for the tank location and a processor, but it becomes modular for future installs. XBee radios (and I'm sure others) can be programmed to read (and Sleep) the sensor and transmit the value to your Particle board. There are Lot's of wireless options.

I believe these A/D input pins are multiplexed. If you are reading more than one A/D pin/channel then I’ve seen errors when one channel input is close to zero and the other channel voltage input level is close to the rail. I’ve had to throw away a few readings each time I change from one channel conversion to another on a project years ago (not a Particle A/D btw).

If you’re only using one A/D then this won’t be the problem.

Do you have a buffer on your sensor output? Maybe add a unity gain opamp and see what happens?