Knowing water levels is important for environmental monitoring and flood control. After experiencing two hurricanes at my home in Palm Harbor, Florida in 2024 (the second of which caused significant flooding in my area), I decided to build a device to measure real-time water levels of lakes, ponds, water tanks, and more.
Off-Grid Water Measurement: Nordic Thingy: 91 XThe measurement device I built uses a toilet float and other readily available/3D-printed parts to rotate a Nordic Thingy:91 X with changes in the surrounding water level. The Thingy:91 X senses its angle via a built-in low-power ADXL367 accelerometer, and produces the actual float height with a bit of trigonometry.
The Thingy:91 X's cellular modem sends information wirelessly to the Golioth cloud IoT service, which passes this information to Grafana for visualization. The all-in-one sensing plus data design means that no external electronics are needed for the project. Everything fits securely inside a small waterproof enclosure.
This project page covers the overall mechanical build, while Chris Wilson's Cellular water level sensor firmware writeup explains the flashing and database setup. Read on to see how the device is put together mechanically, and how you can build your own.
AssortedPurchased Components
- Thingy:91 X
- Pelican 1010 Micro Case, clear (https://amzn.to/45q0S9A)
- Toilet Float (https://amzn.to/3HMBqBe)
- (6) Zip-ties (https://amzn.to/3GLphN2)
- Paracord (https://amzn.to/3IRQ6j4)
1/2" PVC Pipe Cuts
- (6) Top horizontal supports & horizontal legs (200mm ~8in)
- (2) Down (vertical) supports (500mm ~20in)
- (1) Bottom horizontal support (420mm ~16.5in)
- (1) Movable float pipe (1000mm ~40)
- (1) Cap pipe section (25mm ~1in)
- (5) Pipe cap (1 if used in stake mount configuration)
- (2) Two-way elbow
- (3) Four-way tee elbow
- Pipe cement
Use either mm OR inch listed dimensions when cutting PVC pipe (they are slightly different–inches used in video). Roughly 12 feet of 1/2 inch PVC pipe is used in total. Suggest you purchase (2) 10 ft sections.
The PVC system can be built in other configurations, and different pipe lengths and installations can be set up in the Golioth interface via the FLOAT_LENGTH and FLOAT_OFFSET variables.
3D-Printed Parts [See Attachments]
- Pelican-PVC-Mount
- PVC-float-adapter
- Stopper (optional, modeled, but not used)
Cut PVC pipe to lengths per BOM. Drill a roughly 6.5mm hole through center of float pipe, 10mm from end. Assemble PVC float adapter, aligning printed hole with drilled hole in PVC, then insert the float. Drill through aligned holes in the 3D-printed fixture and pipe, plus the fully-inserted float to create a hole through all three parts. Use zip-tie to secure the float to pipe and PVC-float adapter as shown below.
Modify (1) four-way elbow as shown below, using a rotary tool and/or sandpaper to enlarge the OD of the two inline pipe connections so that PVC pipe rotates freely when inserted. This allows the main pivot to move according to the water/float level. Do not modify the other (90º) pipe connections.
Modify (2) two-way elbows by drilling a roughly 6.5mm hole through roughly the center of the bend for paracord insertion.
Attach PVC pipe and fittings as shown in the images below (with the exception of the top plug assembly–leave this until a bit later). Optionally use pipe cement on non-rotating joints, but consider which joints you may want to disassemble later for transport and/or modification (see reinforcement cord section below)
Assemble 3D-printed Pelican case mount to the PVC assembly with (2) zip-ties though holes on bottom as shown below. Attach Pelican 1010 case with (4) zip-ties through the side handles with the lid latch facing the float. Place programmed and activated Thingy:91 X inside the Pelican case with its yellow door facing toward the float. Close and latch the Pelican case. The Thingy:91 X is a near-perfect fit, and will stay in place with no additional hardware.
Plug a small length of PVC pipe and a pipe cap into the top of the 4-way PVC tee to keep water out.
Tie a knot in the end of a (~2m) length of paracord. From the outside of the assembly, run it through the previously drilled hole in one of the elbows and feed it through the entire PVC pipe assembly to the other elbow. As needed, temporarily pop the rotating PVC pipe section out and/or use a stiff piece of wire to help feed the paracord through. This process may be easier if PVC pipe lengths are not yet cemented together.
Reassemble the device, then pull the cord somewhat tight and loop it around the elbow to secure it as shown below. Ensure pivot arm can rotate with the arm's weight. Loop cord multiple times or otherwise knot before final tightening. This cord attachment may not be necessary in all situations, but is designed to keep the middle joint in place when under stress.
Instead of using (200mm ~8in) as horizontal members, cut the end of two of these sections at 45º to form sharp points. Attach the opposite (non-cut) ends to tees with PVC cement as shown below. Attach the middle support section to both tees with PVC cement. Optionally drill holes through the top of the tee and upper PVC pipe sections for zip-ties.
The bottom stakes may be nailed in on-site, then the top can be attached with friction and/or zip-ties. 3-way tees will ideally be used here, but 4-way tees can also be used. See images below for more details:
Feet and stake mounting give you lots of options, but this mechanical design can be implemented in many other ways. Experiment and adapt as needed!
Testing and UsageWith firmware installed, SIM card inserted, and your project set up in Golioth and Grafana as outlined in Chris' code writeup linked 👆, turn on your Thingy:91 X, close the yellow door, place it in its waterproof box, and close the latches. Set it up with the float... floating in the body of water you wish to measure.
Go into the Golioth interface under your device and select the LightDB Stream tab, then Expand data. Note the float_height
, float_length
, and float_offset
values, each of which is reported in inches.
float_height
- Water level with respect to a set zero point - the resultfloat_length
- Distance between the pivot axis and approximately the center of your float. This will not change unless the float pipe length is changed or modified.float_offset
- Used to set a water level zero point. Also accounts for changes in PVC fixture height. With a 0 offset, the device will report afloat_height
of ~0 when the float pipe is horizontal.
If the float_height
is not ~0 in relatively calm water (it will vary slightly), change the FLOAT_OFFSET
by an equal and opposite value to the current float_height
. For example, if the float_height
at your physical zero state reads as -4, modify the FLOAT_OFFSET
by a value of +4. Select Settings for your device in Golioth and edit the value in question.
Multiple readings are taken and averaged before sending data to the cloud. ACCEL_NUM_SAMPLES dictates the number of samples taken per transmitted data point, and ACCEL_SAMPLE_DELAY_MS dictates the delay between each sample in milliseconds.
The STREAM_DELAY_S
setting controls how often the Thingy:91 X sends data to the cloud. When testing, a short interval (e.g. 5 seconds) can be useful. However, when deployed, sending information over and over will eat up data and battery power. The STREAM_DELAY_S time period should be set to greater than ACCEL_NUM_SAMPLES * ACCEL_SAMPLE_DELAY_MS.
With your device hardware and software set up correctly, you can monitor water levels via the Golioth LightDB Stream interface–refresh manually, or set auto-refresh via the (🔄 and...) icons toward the upper-right of the screen. Open up your Grafana project to see nice graphs of the data.
Note that if the float is resting on a dry lake/creek/other body of water, it will read as ~1.5 inches higher than if it was suspended in water at this level. This is because the float does not sink into solid ground as it does with water, thus the angle will be affected correspondingly. This needs to be considered if a no-water situation will be encountered.
This is just a brief intro into how to use the interface. For details, see Chris Wilson's Cellular water level sensor firmware writeup.
Final Thoughts and Future OpportunitiesThis water monitoring device has been tested and refined for around a month in a Florida swamp, plus a short trip to the beach to measure tide changes. As of now, I would consider this to be a functional prototype and/or reference design, though longer-term testing would be needed to really prove it out.
If you want to build your own, use these documents and videos as reference material, but don't be afraid to experiment with it to meet your specific needs. For example, a water level alarm could be implemented to inform you when a set point has been reached, or out-of-range accelerometer feedback could tell you if the system has been knocked over. You could also experiment with a longer pivot arm in situations where the water level is expected to experience a greater shift.
Thanks for reading. I hope that you enjoyed the project, and that you might even be inspired to build your own! -JC
Note any Amazon links are affiliate
Comments