Grove Capacitive Water Sensor fails to work after power cycle

I recently purchased two of the Grove capacitive water sensors I will use them to measure the amount of water in a small tank used for watering plants.

Upon testing they work great, but when you unpower the device and then power it again - the sensor returns zero. The device is working and responding to I2C calls, but it is not returning the correct value. To make it work, I have to take the sensor out of the tank, wipe it with a dry cloth and then it will start measuring correctly.

Both the sensors I purchased work exactly the same. If I unpower them, they no longer show the correct value.

This basically makes the sensor useless to me and for anyone that had hoped to build this into an unattended system? Did you not test this before starting to sell it?

1 Like

I am sorry that we did not consider the case of power failure when we were designing. I have fed back your information to the r&d department and hope it can be solved later. @Jensa

@ Baozhu is the source code available somewhere? If so, I could take a look at solving it myself?

@Baozhu any update? Is the sourcecode public?

@Jensa Sorry, I forgot to reply you. I will find out the source code and send it to you immediately @Jensa There you go

1 Like

Hi, i just discovered the exact same problem. Did you solved this problem, or do you have any solution?

1 Like

Sorry @Vach. I’m just using this for a personal project, so I have not been able to set aside time for it. Hopefully, @Baozhu can do it.

Thats ok, thx for reply. I am just a little bit pissed off, because i need to measure water level in my bachelor project and i dont have time to find alternative… I hope this will have solution, because otherwise as you said, this sensor is useless for unattended system

I actually lecture Embedded Systems at a uni here in Oslo, Norway. Based on how I teach, I would say that this is not really a problem @Vach. You cannot be blamed for non-working hardware, so just present the paper as if the sensor is working? Then make a note in your paper that you have discovered a bug in this device. If someone grading your project, he/she will likely not encounter this bug. If they do - it’s great that you’ve made a note of this, so he/she will know how to work around it.

I know, sorry @Jensa , i could have tested this sensor sooner, so it’s mainly my fault, now i am under time pressure, This is not only bachelor project, I was hoping it would really work, not just theoretically (or at least for to 14 days), so i could use it on my home. The topic is design and implementation of home irrigation system. But if I will not figure out an alternative today, i have no choice and I will be presentating theoretical not fully tested solution :frowning:.

Same problem here, bought 3 of them … if they were working I would buy hundreds…
Will this issue be solved soon?
Does anyone know any alternatives (which is also based on capacitive sensing)?

I have made a bash script to convert raw i2c data into % value for raspberry pi if someone needs it:

Any update @Baozhu? Based on what @Michael says, it really looks like you could make good money on fixing this bug?

Hi all,

I have the same problem as I would like to use the sensor in a scenario where there would be a substantial sleep time between two measurements.

In my case, I’m using a DFRobot FireBeetle ESP32 board to which I’ve hooked up several sensors (via an I2C multiplexer). I can use the ESP32 deep sleep mode to reduce power consumption between two measurements, but have to keep the sensors powered to not break their calibration. So, the versatility of the sensors it substantially reduced by that.

@Baozhu: I had a quick look at the source code, but I think it’s a bit beyond my current abilities to see how this could be solved. Do the ATtiny MCUs that are used have a non-volatile storage section that could survive a power cycle? If so, how much effort would it be to save the calibration data to that area? Also, failing that, is there any way to restore any of the data from the I2C master side?

You mentioned the method. We haven’t tried it yet. Is it safe?

I haven’t tried myself yet.

The problem I have is that I don’t have a working development environment set up for ATtiny 1-series MCUs. I would need to install Atmet Studio first, but since I’m not running Windows would have to do in a VM. Also, I don’t have a programmer, but could probably repurpose a serial-to-USB converter for that. The upshot is, I still have a way to go before I could test any changes myself.

In terms of the code changes required, I think one would need to

  1. change this line to not initiate the calibration by default. Instead, calibration values could be retrieved e.g. from flash and written into this structure.
  2. add support for a calibration command that can be received via I2C from the master. Once calibrated, the updated values should be written to e.g. flash memory.

@Baozhu Does this make sense? You probably know the structure of the code better than probably anyone else.

Anybody with a working toolchain willing to give it a go? Not sure how quickly I’m ready to try.

EDIT: Not sure why this was flagged as spam. If anybody feels like hiding the post again, please tell me what the problem is.

I am really sorry that I am not the developer of this software. I have given feedback to the corresponding developer.They are evaluating it.

1 Like

Hi all,

After a lot of trial and error, I think I might have a tentative solution.

The original code relies on some of Atmel’s QTouch library’s processing functionality around touch keys. For example, the library implements hysteresis automatic re-calibration to detect and avoid error states.

If e.g. an object accidentally covers a touch key for a prolonged time, normally, it could appear as a prolonged key press. The library has ways of automatically re-calibrating in this case to compensate for the object. All this processing enters the key pressed flag for each touch pad.

The problem is that after a power cycle, the library initially calibrates each sensor and assumes that in the current state each key is not pressed. This obviously represents a problem since if some pads of the sensor were submerged before, the same pads that are still submerged would now appear as not submerged according to the flag.

The original firmware was relying on the key pressed flag. If the flag was indicating that a key was pressed, i.e. the corresponding sensor pad was submerged, it would cast the raw sensor value from an unsigned 16 bit integer to an unsigned 8 bit integer and send that over the wire. If the flag was indicating that the key was not pressed, it would just send a zero. The same for all other sensor pads.

I’ve changed the code to just always send the raw sensor value as an unsigned 16 bit integer, ignoring the key pressed flag.

This way, one looses the ability to use some of the smarts of the QTouch library, but they were the cause of the problems in the first place anyway. A capacitive water level sensor just works under different boundary conditions than a touch key array.

I have pushed my changes to a fork of the original repository; see

I will soon also add the hex binaries there that can be flashed onto the sensor’s MCUs to apply the changes.

A bit of additional work is now required on the receiving end of the raw data. It might be possible to just apply a relatively simply threshold to detect when a pad is submerged, I’ve seen values jump from around 500 to around 1000 when going from non-submerged to submerged. But it’s also possible that values drift with changing ambient temperature or humidity. I need to do more testing to find out.

Any feedback, just let me know.

P.S.: There was also a bug in the original source code that caused the firmware to always only send the value for the lowest pad. So it must have been a different version than what comes flashed onto the sensors when shipped.

EDIT: Not sure why this was flagged as spam. If anybody feels like hiding the post again, please tell me what the problem is.

1 Like

Published a first version and binaries; see GitHub repo.

1 Like

In case anybody wants to flash the alternative firmware to the water level sensor’s MCUs, you can use a Python package called pyupdi. I can’t post the link to GitHub here since the URL filter wouldn’t let me.

The there also explains how you need to wire everything up. You’ll need a serial port, or, more likely, a USB-to-serial converter, a 4K7 resistor, some cables, and some pin headers soldered to the UPDI contacts on the back of the sensor’s PCB. You’ll need to flash both MCUs marked u1 and u2, respectively, where u1 is responsible for measuring the 12 upper pads and u2 is for the 8 lower pads.

On the other side of the I2C bus, you’ll need to adjust your code to now read two bytes per pad from the bus which represent the little endian unsigned 16 bit integer with the respective pad’s reading. To get the water level, you can, as done before already, count the number of pads from the bottom that exceed a certain threshold value and then multiply by 5 to get the level in mm.