The KAPtery closed on December 31, 2024. Products can no longer be ordered from these pages. Some products are available for purchase from Ennapurna in France. For questions, replacement parts, special requests, or leftover inventory, use the Contact page above.
Will trigonometry help an Arduino measure water depth?
Can a gadget measure and record the water depth in my springhouse? |
A prototype of the tilting-arm water level measurer was able to measure the height of objects in my office with an error of several millimeters. That system depended on a brute force calibration which involved relating the raw output of an accelerometer to a range of measurements (e.g., heights of the end of the tilting arm above the floor). A more elegant approach is to use trigonometry to derive a dimension of a triangle from the angle measured by the accelerometer. This approach is much easier to transfer to a new location like the spring house where I want to measure water depth.
An advantage of the earlier method is that it did not require knowing the tilt angle of the arm--the raw accelerometer output was regressed directly against height. Trigonometry requires an angle, so the accelerometer output had to be converted to an angle. The raw accelerometer output is related to angle, but it is a non-linear relationship.
Figure 2. For some reason, the tilt data produced by an accelerometer have a nonlinear relationship to tilt angle. Probably for the same reason, the relationship is trigonometric. Source |
It's not too hard to learn that the curve in Figure 2 is a sine wave. To convert accelerometer output (12 bit) to an angle the formula is:
angle = arcsine(output/4096) (note: this is somewhat simplified)
So now I can convert accelerometer output to tilt angle, and more importantly, so can the Arduino. When the Arduino knows the angle, it can use trigonometry to find dimensions of right triangles. Every different tilt angle creates a new triangle in which the arm is the hypotenuse and the other two sides are vertical or horizontal. The length of the hypotenuse (arm) is known, as is the height of the arm's pivot point. So the Arduino can compute the length of each triangle's adjacent side and derive the height of the arm's end above the floor (Figure 4).
The MMA8451 accelerometer I used is a 3-axis accelerometer and these calculations were done using only the Y-axis output. All three axes can be used to get a more robust estimate of tilt angle, but the math is messier. I could not parse the method in this document from the manufacturer (e.g., equation 55), but I could grasp the simplified version in this post. I implemented the simplified version and it worked well for part of the range of tilt angles but not for the rest. I gave up and went back to using only the Y-axis data which seems to yield sufficiently accurate and precise results for the entire range of angles I need (25° to 85°).
The two minute video below shows the device in action computing the height above the floor and displaying the measurement in real time.
The data logging shield is not needed in this implementation, and the cost of the required components (Nano, MMA8451, and LCD) is about $8.00 on eBay. The low cost makes this an excellent candidate for a STEM project or if you wanted a really inconvenient ruler.
Here is the sketch running on the Nano.