IuT voltmeter for a breadboard

Measure several voltages on a breadboard and display results on a smartphone for less than $10 for parts

Similar projects worth following
*non-native English speaker, language corrections are welcomed

MOTIVATION: Conventional digital multimeters (DMMs) are usually quite bulky and inconvenient to use along with a breadboard. In many cases one wants to monitor/observe voltages at several circuit nodes, ideally at the same time. The latter is not possible with a single DMM; re-connecting the DMM lead(s) may affect the existing breadboard connections.

AIM: build an inexpensive IuT voltemeter, which can be easily connected to a breadboard and reports data from several measurement channels through a web server to a smartphone or tablet

1) inputs to be protected from overvoltage
2) must be powered from an isolated non-grounded power supply for at least 4 hours
3) resolution down to mVs with decent accuracy and repeatability
4) cost of components below $10; use off-the-shelf modules for easy and quick assembly

The project's challenge - build an IuT instrument for breadboard users (circuit designers, tinkerers, students, makers) at low cost

What will it address - the need for measuring/monitoring several voltages during circuit prototyping, tuning and evaluation

How will it change the world - every person who builds the IuT voltmeter will spend a few dollars on parts, which is good for the global economy. The side effect is productivity and convenience increases for the user.

Project licensing - some permissive open source license (MIT?); contributions of other people will be acknowledged, and relevant license(s) stated as appropriate.

Design intentions

- usable straight away with any mobile phone or tablet etc, equipped with a web browser, with automatic refreshes of the measured voltage(s)

- fully self contained (no need to connect to any additional network)

- use of inexpensive ESP8266 then ESP8285 modules for implementing both a web server and an access point

- use of ADS1x15 module for voltage measurements

- protect inputs of ADS1x15 from overvoltage with resistors in series (no damage if the voltmeter's input is connected to a voltage source of up to 50 V)

- rechargable Li-ion battery for powering the device (to be capable of 4 hour operation without recharging it; allows for operating the IuT voltmeter independently of the breadbord circuit's power supply and does not require earthing of the volmeter similarly to a conventional DMM);

- have three hardware revisions (design based on WeMos mini base board and shields and ADS1x15 module; replacement of the original Li-ion management shield with more power efficient modules as a custom shield; PCB for permanent assembly of the device using custom modules)

- ESP82xx is to be programmed in Lua (NodeMCU firmware) for the ease of development and debugging at first; other options may be used to improve operation of the functional design at later stages if desirable

- future enhancements - automatic gain control to provide the best resolution for the measured voltage (firmware; relatively easy to add); gradual addition of JavaScript code in order to improve appearance of the measured voltages (use of some seven segment library), using AJAX instead of page reload, configure the voltmeter from the served page (enable/disable particular channels, give labels, set voltage threshold activating audio warnings, use the voltmeter for plotting measured voltages over time (I am new to JavaScript but all the relevant libraries seem to be available for the above actions)


Captive portal script that complies with the present version of the Lua firmware. Please add the following line to the end of IuT_00.lua: dofile("dns-liar1.lua") to enable this functionality.

lua - 1.89 kB - 05/18/2019 at 13:23



The stress test - serving two clients simultaneously. Please note that the client system's time is displayed.

x-ms-wmv - 3.12 MB - 06/09/2017 at 15:38



Video showing operation of the IuT voltmeter for a single connected tablet. Please note that the page automatically reloads every 300 ms which can be seen from some flicker of the address bar.

x-ms-wmv - 7.08 MB - 06/09/2017 at 15:36



HTML page with embedded Javascript that displays clients's time and self reloads every 300 ms. Used for testing before being added to the server code.

HyperText Markup Language (HTML) - 445.00 bytes - 06/09/2017 at 12:17



A service code to delay starting the main file (IuT_00.lua) by 3 seconds, during which the user can abandon automatic execution by connecting pin 3 to ground

lua - 444.00 bytes - 06/09/2017 at 12:17


View all 8 files

  • 1 × Wemos mini module WiFi access point + web server, £3.12 on aliexpress
  • 1 × ADS1115 (or ADS1015) ADC module Measures voltages, around £1.50 on aliexpress
  • 1 × Wemos tripler base Connects three modules together, £1.12 on aliexpress
  • 4 × Through hole resistor of around 10 kOhm Protection for the ADC inputs
  • 1 × Turned pins strip (min 5 pins) To insert jumper wires

View all 8 components

  • Captive portal goes live

    AlexanderN05/16/2019 at 13:11 0 comments

    It was a while since I put the previous project entry. Nevertheless it is better late than never, isn't it?


    In order to operate the device using the previous version of the firmware, one needed to connect to the access point IuT_voltemeter (no password required) with their smartphone/tablet/laptop, and entering the IP address of the web server, namely, in a web browser. The new revision allows enetering any valid web address , e.g. (Please be warned that typing any word will probably not do the trick as the browser will try to ask non-accesible search engine for entries).

    The starting point for the captive portal was the CaptiveIntraWeb project developed by Andy Reischle 4 years ago. Since then the NodeMCU Lua firmware evolved to the point that this older code did not work at all, and required fixing.

    Fortunately the required amends were not too difficult to debug. The amended firmware makes use of newer net.udpsocket Lua module. There is a sure possibility to take advantage of the net.dns Lua module but I decided to amend a working code rather than try to develop a new one from scratch not to getting too deep into the DNS protocol (I lightly used the following two sources that worked very well for my needs: DNS Query Message Format and DNS Response Message Format).

    It was necessary to amend the Lua code that was placed into the file dns-liar.lua, and call this code from the IuT_00.lua as follows (I put this call at the very end of the file)


     In turn, the dns-liar1.lua contained the following code where I left all the acknowledgements

    -- dns-liar1.lua
    --Thanks to Thomas Shaddack for optimizations - 20150707 ARe
    local i1,i2,i3,i4=dns_ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
    -- constants required for a proper DNS reply
    --% code in this section was modified to amend the deprecated APIs
    --% see for details 
    udpSocket:on("receive", function(s, data, port, ip)
        --print(string.format("received '%s' from %s:%d", data, ip, port)) -- DEBUG
        --s:send(port, ip, "echo: " .. data) -- from the docs example replaced below
        s:send(port, ip, dns_tr..dns_str1..dns_q..dns_str2..dns_strIP)    
    --old callback code - deprecated
    --  print(dns_pl)
    --  print(dns_tr..dns_str1..dns_q..dns_str2..dns_strIP)
    --  svr:send(dns_tr..dns_str1..dns_q..dns_str2..dns_strIP)
    --  collectgarbage("collect")
    udpSocket:listen(53) -- DNS requests are sent to the gateway IP : 53
    function decodedns(dns_pl)
      local a=string.len(dns_pl)
      dns_tr = string.sub(dns_pl, 1, 2) -- get the first 2B of the request -> request ID
      local bte=""
      local i=13
      local bte2=""
      while bte2 ~= "0" do
        bte = string.byte(dns_pl,i)
        bte2 = string.format("%x", bte )
        dns_q = dns_q .. string.char(bte)
      --print(string.format("DNS request: '%s' for %s",dns_tr,dns_q)) -- DEBUG
    print("DNS Server is now listening. Free Heap:", node.heap())


    Bonus youtube link: ESP32 NodeMCU Lua Firmware - Config, build and flash | How to from Alija Bobija

  • Function, procedure, interrupt sevice routine, callback function - which is better to use?

    AlexanderN07/16/2017 at 11:28 0 comments

    Some time ago I came accross the term REST (ReST) and how important it was. I tried reading a lot of articles (starting from Wikipedia and ending with the likes of "How did I explain REST [and some other little things] to my wife") to get the idea. Some of the sources cited a long list of references which included PhD theses, books and internet archives going a few years back. Unfortunately I am not a diamond to be around forever and work through these lists. (Most importantly, there is no known diamond of my weight as of yet.) Therefore, when I figured out that, if I folow the table below, I comply with REST/ReST/RESTful/you_name_it

    Action on resourceHTTPSQL (for comparison)
    Create new POSTCREATE
    Access existingGETSELECT
    Update existingPUTUPDATE
    Delete existingDELETEDROP

    I have got my rest despite some people would rightly say that I missed a lot of important points. This log entry is used to clarify a few points that I think are important before describing recent amendments to the firmware.

    Read more »

  • Made for each other: B0505 and Wemos mini

    AlexanderN07/07/2017 at 14:00 0 comments

    The original intention was to equip the IuT voltemter with a LiPo battery and a battery shield with the view to have an isolated instrument like any digital multimeter (DMM). I found that using the shield with a quite beefy 720 mAh battery lasted for the 4 hours I specified for the design. Unfortunately this combination wasted more power than I could tolerate, and pushed the cost of the instrument up too high to my liking. I decided to look for an alternative solution.

    First I would like to discuss why did I want to have an isolated instrument. I am sure for most breadboard prototyping needs it is perfectly fine to have the voltemeter powered from a power bank or even a mains adaptor. However some measurements (e.g. high side current measurements) do require isolation of the device-under-test (DUT) and IuT voltmeter's grounds. There are some inexpensive isolation DC/DC convereters available, and this log entry describes how the voltmeter performed when it was powered from the B0505 1W converter.

    Read more »

  • To pull or not to pull - that is the question

    AlexanderN06/19/2017 at 23:15 0 comments

    ... which turned to have the following short answer - to pull down with a 680 kOhm resistor. For a detailed answer

    Read more »

  • Project tracker

    AlexanderN06/17/2017 at 20:51 0 comments

    I found out that too many things need to be properly noted even for this well defined little project.

    These are

    - features and options (completed)

    - features and options under development and development alternatives

    - to do later list (essential and non-essential features, options, refinements, cool things)

    - things to revisit if time permits

    - anything else

    Read more »

  • Test 2: performance

    AlexanderN06/17/2017 at 17:51 0 comments

    Some observations and test results

    - protection

    - consistency of measurements

    - operation of the access point

    - dynamically serving the web page

    - operating the design from a single battery charge

    - at last but not at least - how did the voltmeter measured voltages

    The outcome - this is a voltmeter that underreports the measured voltages by 6 mV in the worst case at full scale measurement (below 0.5%).

    Read more »

  • Functionality test 1: passed

    AlexanderN06/09/2017 at 15:35 0 comments

    Here is the video of IuT voltmeter serving a tablet with the reload interval of 300 ms

    and the stress test - serving two clients simultaneously

  • Firmware 2 & web page : enabling basic functionality

    AlexanderN06/08/2017 at 21:08 0 comments

    This log is about configuring the ESP for operating as WiFi access point (straightforward), enabling TCP server and programming relevant callback to serve dynamic web pages (learned a few new to me useful things), adding JavaScript code to reload the web page from the server automatically every 300 ms (my first practical use of JavaScript) and adding a script to start all the things on power up (init.lua).

    Read more »

  • Hardware - revision 2

    AlexanderN06/08/2017 at 20:27 0 comments

    This revision was planned to have a trippler baseboard, a mini lite and a battery shield from Wemos, an ADC module (attached to the third base) all soldered to the baseboard in order to reduce the height of the device. However, following the experience with oldered battery shield for the revision 1, I decided to socket all these modules. As it turned out later, this was a wise provision to make.

    Read more »

  • Firmware 1: how to stop worrying and reinvent the wheel

    AlexanderN06/04/2017 at 20:07 0 comments

    I was not afraid of writing driver code for the ADC module, and I did. When I later built the NodeMCU firmware, I found that this driver was already written and available for inclusion. Nevertheless using such a driver would be difficult without reviwing the ADC datasheet, and I did not worry too much for reinvenbting the wheel. Hence the title of this log.

    Read more »

View all 12 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates