ATtiny85 NanoCurrent Meter With OLED Display

by JD_K in Circuits > Microcontrollers

2792 Views, 6 Favorites, 0 Comments

ATtiny85 NanoCurrent Meter With OLED Display

1c Title.jpg

The main purpose of this project is to test ultra low current circuits, which is important when you want to tinker with low power devices that you intend to run on batteries over prolonged periods of time. It was inspired by the Nano Current Meter at technoblogy.com and the version by OneCircuit. Basically, the original device uses the properties of a capacitor to measure ultra low current circuits (in microamps (uA) or even nanoamps (nA)). 


The version I present in this Instructable is different in a few ways. I modified the project for an ATtiny85 for the microcontroller, and used an OLED for the display. This has advantages though because an OLED can display more information than a 3-digit display. Also, because I like to explore and tinker with projects, I added a few other features:

  • external trigger, for automating the measurement with an external device
  • serial data output for optional datalogging in the future
  • 3.3 voltage option
  • kilohm resistance calculator


I hope you find this Instructable interesting. If you are not interested in this project specifically, maybe you would find it helpful to see some of the challenges I came across in building this. These include printing variables on the OLED, trying to prevent leaking current through the voltage regulator, problems with displaying decimals consistently with the TinyOzOLED library, and problems with the ATtiny85 and Software Serial library not transmitting properly. 


The Basic Premise of the Device

The way the device works, you connect the circuit you are testing to the main capacitor and to the zero-volt pin of the device. The ATtiny85 microcontroller uses one of its pins as an output to charge up the capacitor to the Vcc voltage which is usually 5 volts. If you don’t know, capacitors are an electrical component that can charge up with an electrical charge, and will discharge when the supply voltage is removed. So, after charging the capacitor, the ATtiny85 switches the pin from an output to an analog input pin and measures the capacitor’s voltage over time. The circuit you are testing will be drawing its current from the capacitor. As this is occurs, the voltage that was charged on the capacitor will slowly drop, which is what normally happens when capacitors discharge. When the input pin measures a certain voltage on the capacitor, the ATtiny85 records the time it took the circuit to discharge to this voltage. This time is proportional to the amount of current that circuit consumed. If the circuit draws more current, the capacitor will drop to the target voltage faster; if the current draw is less, then it takes longer. The calculated current is then displayed to the OLED screen. The maximum current the device can measure is 10 uA, and the minimum is 30 nA. (Reminder: the maximum current through a digital pin of the ATtiny85 is 40 milliamps which is 4000 times higher than what we are talking about, but don’t think you can hook up a motor, for example, to the ATtiny85 and see what the device measures. The device can get damaged above the 40 mA.) At this point the device switches the input pin back to an output and continues to supply the 5 volts. If you then press the reset button, the program and measurement will start all over again. That is essentially it. The device measures voltage and time to calculate current. If you would like more detail on the calculation, I direct you to the technoblogy.com page linked at the beginning of this Instructable.

Components and Tools

2 parts.jpg
3 Capacitor.jpg

Components

  • ATtiny85 microcontroller
  • OLED display 0.96inch
  • 1 microfarad (uF) capacitor (must be +/- 5% tolerance) * (I got mine here)
  • AMS1117-5V voltage regulator
  • 10 uF capacitors x2 (for the voltage regulator, these can be electrolytic)
  • 100 nanofarad (nF) ceramic capacitor (the device seemed to work well without this, but I included it because it was in the original design I copied, and I have lots)
  • 8-pin DIP socket (for ATtiny85 microcontroller)
  • Switch x2 (latching push button or slide switch; I use one of each)
  • Momentary push button (aka tactile switch)
  • Screw terminal
  • LED x1 (any colour, I used blue)
  • Resistor for the LED (e.g., 1kOhm; exact value is not critical but usually 220 Ohm or greater; the purpose of this LED is as an indicator so a larger resistor is fine as it does not need to be so bright) 
  • 10 kOhm resistor x1
  • Various header pins (I used five 2-pin male headers, one 2-pin 90-degree male header, two 2-pin female headers, and one 4-pin female)
  • Jumper connector x1
  • Perfboard (3x7cm)
  • 9volt rechargeable battery and battery clip to connect it to the screw terminal (other voltage sources would do, it just has to work with the voltage regulator)
  • Optional: two jumper wires as an option to connect to the test circuit


Tools:

  • Soldering iron, wire and solder
  • Digital multimeter (to check connections, and accuracy)
  • Wire cutters
  • Wire strippers
  • File (for filing female header pins)
  • Arduino, jumper wires, and solderless breadboard (for prototyping, programming the ATtiny85, testing the device)
  • A bunch of 1 MegaOhm resistors (for testing the device)


*A note about the 1uF capacitor: As stated by technoblogy.com and OneCircuit, the accuracy is highly dependent on the precision of the capacitor. So, I looked for a while to find a non-electrolytic capacitor with a tolerance as low as 5%, but that was not too expensive for this little project. If you don’t have such a capacitor, I included the link above where I found mine. 


Another note about the confusing pin numbers: before I go further, I should just point out that the ATtiny85 has 8 pins, and the numbering of these pins is very confusing when you start working with them. Here is a picture here but basically:

Physical pins: There is a small dimple near pin 1, which you could think of as the top left pin of the chip. Then the pins are numbered down the left side, then up the right side. Pin 8 would then be the top right. These are often referred to as the “physical pin numbers”. 

Digital pin names in Arduino IDE: In the software used to program the chip, there is a very different numbering scheme. This software is an open-source (donation-optional) download called Arduino IDE. The numbering in that software starts a pin 0, which is on the bottom right (physical pin 5), and goes up the right side for pin 1 and pin 2. Then pin 3 is second from the top left (physical pin 2), and lastly pin 4 in the software is physical pin 3.

Analog pins in the Arduino IDE: If you use any of the pins for measuring analog voltage, the numbering is yet again different. For this project, I use the analog pin A3 (the 3rd analog pin), but this is physical pin 2. 

In this Instructable, most of the time I will refer to the physical pins, but I will also include the digital pin numbers if I am referring to programming as well.


The Circuit Diagram

NanoCurrentMeter_OLED_SoftSerial_bb.png
4 terminalNoBending.jpg
5 bending terminal pins.jpg
6b terminal fits.jpg
7 soldering AMS1117.jpg
11b soldering capacitors to AMS.jpg
8b soldering LED socket.jpg
12b Progress.jpg
13b Complete.jpg
14b Complete with OLED.jpg
15b Underside CloseUp.jpg
15b Underside.jpg
9b Terminal block and pins.jpg
19b Front.jpg
21b Back.jpg
23b CloseUp Power end.jpg
22b CloseUp Tesitng end.jpg
17 connecting 3v3.jpg
18 3v3 nanoammeter.jpg
ATtiny85 NanoCurrent Meter with OLED

I have included a Fritzing diagram of the wiring. When planning your board, layout the components on the perfboard to get a sense of where everything should go. Then remove them and start soldering, starting with the pieces with the lowest profile, like the resistor. That way components are less likely to fall out while you are soldering larger and larger components.


On the right side of my device are the connections for the supply voltage, which for me will usually be the rechargeable 9V battery. Whatever voltage source I use, it has to be at least 6.5 volts for the AMS 1117- 5.0V voltage regulator. There are options for connecting the voltage supply with the screw terminal or male & female jumper wires. I bent the wires of the screw terminal to save space on the perfboard. If you do this, you have to force the pins of the screw terminal into the perfboard on an angle, but it gives saves a little space on the board. Below to the connectors, there is an on/off pushbutton switch, and an LED indicator with its 1 kOhm current-limiting resistor. The value of the resistor must be at least 220 Ohms or so to protect the Led, but since this LED is being used as an on/off indicator, and not for illumination, up to several thousand Ohms can be used to dim the LED.


The AMS 1117-5.0V voltage regulator is necessary because the device needs a stable supply voltage for accuracy. When using this voltage regulator, it needs a capacitor on the input pin and one on the output. The datasheet for the AMS 1117 recommends 22uF tantalum capacitors but I used 22uF electrolytic capacitors. Both capacitors have the cathode (don’t mix up anode and cathode) connected to the voltage regulator’s ground pin. The AMS 1117 is meant to be a surface mount device rather than a through hole component (all the other components in the project are through hole). However, it is easy enough to solder the voltage regulator to a standard perfboard lining up the three pins to three holes, then apply enough solder on the underside to flow through the holes and electrically connect the pins of the AMS 1117 to the capacitors and wiring. The AMS 1117 work quite well for what I use them for and I like that they are low drop out voltage regulators, and have thermal protection, etc. By the way, if you look on the Arduino, they use these voltage regulators too. 


For the OLED display, I cut a row of female header pins down to a 4-pin piece to use as a socket. That way I can disconnect the OLED if I need it for another project, or I drop the device and crack the display by accident :) 

Be aware, that not all OLED displays have the pins in the same order, so please check yours before soldering the wires. Mine is (from left to right) SDA, SCL, VCC then finally GND. The SDA pin connects to physical pin 5 of the ATtiny85, and SCL to pin 7. 


Under the OLED I have a slide switch and a jumper connector which connects two 90-degree male pins. If you do not have the 90-degree pins, you can use regular male header pins but it will have to put them on a different part of the board so you can connect an external voltage source to it later. The pin on the left is connected to the AMS1117, and the pin on the right is connected to the VCC (physical pin 8) of the ATtiny85. So, removing the jumper connector, you can supply a regulated 3.3 volts to the ATtiny85. Sliding the switch connects pin 6 of the ATtiny85 to ground, giving it a LOW signal. In the programming, when this pin (which is digital pin 1 in the Arduino IDE software) reads a LOW, the ATtiny85 is programmed to calculate the current using a formula for this lower voltage rather than 5 volts. This switch, therefore, allows for a quick shift from 5volts to 3.3 volts, and vice versa without having to re-program the microcontroller each time. 


The right side of the board is the testing side. There is the large white 1uF capacitor, the ATtiny85, a black pushbutton, and various connection options. The capacitor is what is measured for our calculations. The pushbutton is a reset, and when activated, connects the reset pin (physical pin 1) of the ATtiny85 to the zero volts ground. This is how you re-start the program and therefore re-start the measurement. There are two red male header pins and a red jumper wire all connected, plus two black male header pins and a brown jumper wire. These are the positive (red) and negative (black/brown) connections for the circuit you want to test. The red connectors are also connected to one end of the capacitor and pin 2 of the ATtiny85. It is this pin 2 that charges up the capacitor, then changes to an input and measures the voltage on the capacitor. 


I put a small 100 nF capacitor near the VCC pin of the ATtiny85 which connects to the VCC pin and to ground. I found the device worked without it, but since it was in the original design, I included it. It is meant to help smooth out any small changes to the voltage supply to the ATtiny85.  


Lastly, there are two male header pins between the ATtiny85 and the large white capacitor. One of these is connected to pin 1 of the ATtiny85, which is the reset pin, and the other male header is connected to pin3. The reset header pin will function just like the reset button. In other words, if you connect to this, and give it a LOW signal of zero volts, the ATtiny85 will reset and start the program again. This allows for an external device, like an Arduino, to trigger another measurement without someone having to press the button. 


The other header pin, connected to pin 3, is used as a transmit pin. This transmits the raw nanocurrent data as serial data. Together with the reset pin, these two pins should allow the added functionality of an external data logger to record current measurements over time. The data logger can trigger a reset of the device with a LOW signal to start a new measurement, and then record the serial data from pin 3. It would have to be at least a couple of minutes between measurements as the nanocurrent meter can take over a minute and a half at the lower end of its measurement range as it waits for the 1uF capacitor to discharge.


In the video, I connect an Arduino to the device to test the serial data. To do this, you first upload a blank sketch to the Arduino, which is usually the “BareMinimum” in the Basics example sketches. Then connect the ground pins of the device and the Arduino, as well as the transmit pins (physical pin3 of the ATtiny85 to pin D1 of the Arduino). In the Arduino IDE software, make sure the com port is correct for the Arduino by clicking Tools>port. Then open the Serial Monitor for the Arduino. At that point you can power up the device, and when it measures on the OLED you should see the raw nanoamps displayed without units or spaces in the serial monitor. In the video I even show the Arduino controlling the nanocurrent meter.

The Code

I am including my code below. I used an Arduino and the Arduino IDE software, to program the ATtiny85. I won’t explain how to do this here. (Stay tuned, I am planning another Instructable for my ATtiny85 programmer.) However, if you want more information on how to program these chips with an Arduino, you can find information here at the HiLow Tech website, or search for one of the many ATtiny85 programming tutorials on the internet (there are lots)! Make sure to set the clock of the ATtiny85 to “Internal 8MHz”.


Unless someone wants me to explain the code, I won’t go through it all here just because of space. If you have specific questions, please feel free to send me a message below. If you would like more information on the original programming including an explanation of the calculation, have a look at the two links in the introduction of this Instructable.


A few words about the some of the modifications though…

The original project used a 3-digit 7-segment display. Therefore, a lot of the original program was devoted to displaying values on this display. Since the ATtiny85 does not have enough pins for the segments and digits, I used the OLED. So, I eliminated the programming for the 7-segment display and used a library called TinyOzOLED to help display on the OLED. I found the library here. (Libraries are pre-made programs that people have published so you don’t have to start programming from scratch). However, I was getting what looked like random large errors in my results. I figured out that the TinyOzOLED library would not print a zero in the first decimal place. For example, if the result was supposed to be 1.03, the library would print 1.3. I modified the original library and will include my version here if you are trying to make this project. I apologize in advance if there is some etiquette to modifying someone’s library, this is my first time. In any case, this is just a quick patch for this project and not a proper correction of the library (more info at the end of this instructable).


The other library in this project is the Software Serial library, which is included in the Arduino IDE. This library allows for the ATtiny85 to use serial communication like the Arduino is able to do. I was not interested in receiving data, but the library expects some value for a receiving pin. So, in the code I declare the receiving pin as -1, and then not connect any pin for receiving when I wired everything together. The transmit pin is pin 3, otherwise known as pin 4 in the Arduino IDE software (confusing numbers, I know).

Testing and Calibrating the Device With the Multimeter

To test the finished product, I put a bunch of 1 megaOhm resistors on a breadboard in series and measured the exact values with the multimeter. That way I knew what the total resistance was, and could use Ohm’s Law (voltage = current x resistance) to calculate what the current should be. So, for example, I measured the exact voltage of my AMS1117 with a multimeter and got 5.02 volts. And If I place 5 resistors in series and measured exactly for 5 megaOhms (5 million Ohms) then I can calculate the expected current:


 5.02 volts / 5,000,000 Ohms = current


This calculates to:

current = 0.000001004 amps

which is the same as 1.004 uA


Using different combinations of 1megaOhm resistors I had a bunch of values that I could compare my device to. I initially found my device was consistently about 4% lower from the expected current, (not too bad!). So, I corrected the equation in the code that calculates current, which was “nA = 1732868 / Time” and added 4% to get “nA = 1,802,183/Time”. This worked quite well. Very consistent, and very accurate to the calculated current. If you are making this project, left the original equation in the code, so you can adjust it to match it to your device. Anyway, It was at that point, I realized that my digital multimeter also measured currents as low (nanoamps) as what this device does. To my surprise the two have identical results, so my device at least as accurate as the multimeter. Yah me!


Near the completion of the project, I decided it may be helpful to display what the resistance of the test circuit must be. Again, the device measures voltage and time to calculate a current. And with the values for voltage and a calculated current, you can use Ohms law to calculate the resistance (voltage divided by current). This resistance value is printed on the OLED, but is printed in kOhms, so 1 million Ohms will be displayed as “kOhms = 1000”. At first, it looks weird for reporting resistance, but it was easy to implement and I am less likely to miscount the number of digits (I mix up 1000000 and 10000000 – too many zeros).

Finishing Up

Looking Back at Hiccups Along the Way and the Troubleshooting to Solve Them

In converting the code to display on the OLED, I tried a few libraries. However, the data from the device is a “long” variable, and some libraries, like ACROBOTIC_SSD1306.h, could not display the data on the OLED because the data were not “character” variables. I tried to convert from a “long” to a “char” but I couldn’t make it work. To make things more challenging, since I am using an ATtiny85, there are less libraries for connecting to an OLED than other microcontrollers like Arduino. In the end I was able to get the TinyOzOLED library to work. I am thankful to the author for it but I had issues with it as well. One was that it flipped the screen upside-down most of the time. It was strange that if I used a different library, it would flip right-side up. And even if I then used the TinyOzOLED library again, it would start off right-side up, but then would eventually flip upside-down. Why it sometimes does and other times does not I couldn’t figure out. In the end I gave up on trying to fix the orientation because the device worked, and now I don’t even notice it is upside down anymore.


As I mentioned in the section about the code, I was getting errors printing decimals. It seemed random at first, but I created an Excel spreadsheet to record predicted values and the results I was measuring to see what was going on with the data. Doing that, I was able to see a pattern when the results were suddenly off 40 or 50%. Being able to see the pattern visibly on the spread sheet helped clue me in to the fact that the TinyOzOLED library was not able to handle the first decimal being a zero value. I was able to surmise the problem was somewhere in the printNumber function in the header file (the file ending in ".h") of the library. I made notes of what changes I made and tinkered with the file. My fix was a couple of lines to tell the microcontroller to print a zero first if the decimal portion was less than 0.1. It worked. If you search for “JD” in the header file TinyOzOLED_decimalFix.h included in the library in this Instructable, you should find the three lines I added.


About the current leakage through the AMS 1117… If you connect the input and ground pins to the positive and negative terminals of a battery, the voltage regulator will leak current even if nothing is attached to the output pin. This can drain the battery over time even if left off. Similarly, if you connect the output and ground pins to the terminals of a battery, the voltage regulator will still leak some current (about 1 mA) in through the output pin to ground. Since I wanted the option of being able to use a 3.3 volt source between the voltage regulator I wanted to be able to disconnect the voltage regulator from the ATtiny85. So while making the device I used a “double pole, double throw” (dpdt) switch. These are very common. A dpdt switch allows two separate circuits to connect simultaneously, and if you switch it off, it disconnects both as well. In the end I added the jumper connector though, so the voltage regulator will never be accidentally left connected when I use a 3.3 voltage source. 


Lastly, another problem that stumped me for days was trying to get the Software Serial library to print out the raw data. I kept getting gibberish, or a series of question marks. I searched the internet several times for a fix to this problem, but the solution given most of the time is to check that the baud rate, which is 9600 in my case, was the same on the transmitting and receiving devices. This was not the problem; and I even tried slower baud rates, but still no luck. I tried just printing out text rather than the data, but that did not work either. I tried isolating the ATtiny85 on a breadboard by itself (no other components) in case there was some sort of interference, but still the exact same. Then I checked another project I made that used the ATtiny85 and the Software Serial library. The only difference I found was that this other project had the transmit pin on physical pin 3 rather than pin 2. This did the trick. For some reason which is beyond me, Software Serial did not transmit on pin 2 (pin 3 in the Arduino IDE). So, I modified the soldering and switch a few things around.


Well, that is about it for this Instructable, thanks for reading. It was so rewarding to get the nanocurrent meter up and running, especially with all the changes of using a different microcontroller and display. That was challenge enough. But to see that the accuracy of the device was within 5% of the predicted values using basic physics (Ohm’s Law), or the results of the multimeter, was really satisfying. And now that all the pins of the microcontroller each have a purpose (transmitting data, changing to 3.3volts), I feel like this project is complete. Now, on to the next one…