Everyone needs a level at some point whether you are a pro or just hanging a shelf on a wall you want to make sure that it’s going to be straight! Let’s create an accurate Digital Level that works in both the Horizontal (LEVEL) plane, Vertical (PLUMB) plane as well as angles in between like a 45. These would be the same 3 bubble indicators you would have on any decent level you purchase at the hardware store.

We’ve built in some nice features and housed it all in a nice 3D printed enclosure that looks like any standard level, printed in what I call DeWalt Yellow (But it’s really Hatchbox brand Yellow PLA!)

  • Automatic rotating screen so that the view of the angle is always readable to you even if you flip it completely upside down. Like how your phone screen flips as you rotate it.
  • A few menu options to change from Normal mode with the angle rounded to the nearest whole number, Precision Mode to display 1 decimal place value for a more precise reading and Calibration.
  • Auto calibration – Which only needs to be performed the first time it is set up and likely never again. The values are stored in the Nano’s onboard EEProm and called back every time it is powered on so your calibration values are always saved for you.

Parts List

Wiring & Assembly

Digital Level Diagram
Digital Level Diagram CLICK TO ENLARGE


This is a relatively simple project, It is really just a handful of wires, the Arduino Sketch is where the magic happens! I opted to add a lithium battery alone with a TP4056 charging board and a boost converter to up the 3.7v battery to a solid 5v. I am using an 18650 battery because I have quite a few of them pulled from old laptops with an 18650 cell the level will get hours and hours of use before needing to be charged. It also gives the level a small bit of weight so it doesn’t feel “cheap”.  You could just use 4 AA batteries if you’d like!

With an 18650 cell or a Li-Po pack you’ll need a boost converter to bump the 3.7v of the battery up to a stable 5v level for the boards, all 3 of the main components, Nano, MPU6050 and OLED display have onboard voltage regulators with 5v output. So applying less than 5v to the regulator may cause issues.

The Enclosure


Now this is a matter of preference. I wanted to mimic the style of a traditional bubble level so I spent some time in SolidWorks designing one to 3D Print. A few versions later I had created a sturdy enclosure that can print without supports but it does require a rather large printer to print in one piece, it’s about 12″ in length (~304mm). You could cut it in half down the center with your slicer (I recommend PrusaSlicer) and print it in 2 parts then glue together. It will NOT scale down, if you try your components will not fit in their designated spots.

Watch our video on YoutTube on how components are supposed to be fitted in the enclosure!


Full Sketch Available on our Github: https://github.com/DesignBuildDestroy/digital_spirit_level

This was tricky, getting familiar with rotational dynamics of an MPU is not a straight forward task. I’ll admit there has definitely got to be a better way to do this than how I am accomplishing it in this sketch. A more mathematical approach to figure out both what direction you are rotating toward (for the screen flip) as well as what angle you are rotating on the given axis we want to show plumb or level. However my method works just fine as you can see in the video for this particular project. Using an MPU to fly a drone, well, that’s another story…

The Sketch is pretty large taking up 96% of the available programming flash space on the Arduino Nano. Using Jeff Rowberg’s Arduino MPU6050 library for DMP requires us to store the firmware to push to the MPU6050 on startup which takes up some space. Nothing too concerning though. A good chunk of the space is really taken up by the OLED display text for the Menus.

If you have questions or if you want to see a more detailed write up of the software let us know in the comments!

Future Improvements

Understanding more of how Quaternion calculations work and cleaning up the bunch of IF statements that try to decipher what position the device is held in to determine screen orientation as well as the angle is a big opportunity here. The way I am doing it works but it doesn’t feel right at all. I’m sure there is a much cleaner approach mathematically that would create a cleaner code.

Another idea I had after building this was adding another menu option to show angles from 0 to 180 to maybe use it more like a protractor, this wouldn’t be hard to implement.

We’d love to hear your ideas on improving this!

Comment on our YouTube Video or leave a note below!