Voltímetro miniatura com monitor de tensão da bateria

Miniature voltmeter with battery voltage monitor

AVR Attiny85 based miniature voltmeter display and battery level indicator
Fig. 1: Image showing voltage reading on AVR Attiny85 based miniature voltmeter and battery voltage monitor
Most of the time, measurement in electronic circuits is done by measuring DC voltage. Typically, we will put the multimeter in DC voltage mode and check the voltage levels at various points on the PCB… Typically, we will put the multimeter in DC voltage mode and check the voltage levels at various points on the PCB. Mainly, our requirement is between 5V and 15V DC. The circuit shown is simple, takes up less space, and can be directly connected to DC voltage for measurement. To minimize size and power consumption, 8-pin MCU and 0.96” OLED is used in the circuit.
The Miniature Voltmeter has two operating modes. In the first mode (12V battery mode), it can be directly connected to the 12V battery, to measure the voltage and monitor the battery status. In the second mode (20 VDC voltmeter mode), it works like a normal DC voltmeter, which can measure from 0.0 to 20.0 VDC.
Two jumpers J1 and J2 have been provided to choose between mode 1 and mode 2. Once the mode is selected, the Attiny85 MCU continuously measures the voltage through its ADC channel, at pin 7 and converts it into digital value. The ADC value is converted to the corresponding voltage value using an algorithm in the code. In battery mode, depending on the ADC value, different battery statuses (LOW, Charged, Overcharged, etc.) along with the current battery voltage level are displayed on the OLED. In voltmeter mode, the corresponding voltage level is displayed on the OLED.
Component list: ATTINY85 – 1 no. OLED 0.96” – 1 no. LM7805 – 1 no. 1N4007 – 3 nos. 3 mm LEDs – 2 nodes. 100uF 50V – 1 no. 10uF 16V – 1 no. 0.1uF disk – 1 no. Trimpot 5K – 2 knots. Resistance of 10K 0.25W – 2 knots. Resistance of 4.7K 0.25W – 2 knots. Resistance of 8.6K 0.25W – 1 no. Resistance of 2.2K 0.25W – 1 no. Resistance 1K 0.25W – 1 no. 9V battery – 1 no. 2.54 mm jumpers – 2 knots. SPDT switch or slide switch – 1 no. Several. = connectors, PCB, IC base, Berg strip etc. IC1 (7805) is a 5V voltage regulator used for power supply of IC2 and OLED. IC2 is an 8-pin MCU (ATTINY85) which is the heart of the circuit. A voltage divider is used to provide input to the MCU. The controller accepts a maximum of 5 V as input on the ADC pin. Voltage divider is used to bring the voltage below 5V. 0.96” OLED (organic light emitting diode) display module (with 4-pin connections) is used here to make the overall design compact. Only two pins (SDA and SCL) are used for data transfer to the OLED display and two more pins for power supply. The screen has a resolution of 128×64 pixels. Small text is displayed using 16X8 bit font size, while measured voltage is displayed as large font size using 32x24 bit font size. Code Programming guide –
In this project, the ATtiny85 is programmed to display the charging status of the 9V or 12V battery (depending on the mode selected) by measuring the terminal voltage of the battery. The MCU is coded with embedded C using AVR Studio 4.
Constants used in the code
#define F_CPU 1000000UL :- Constant used to define the clock frequency of the MCU
#define BLINKER 0b00000001 :- Constant used to blink the LED as an indication that the MCU is working properly.
#define BATT12V 0B00000010 :- Constant used to define 12V battery mode.
Variables used in the code
A: – Variable used to store analog reading of the 10-bit ADC channel
V: – Variable used to convert ADC reading to voltage and indicate battery status
Prev_mode: – Variable used to indicate the previous battery mode (12V or 20V battery mode)
current_mode: – Variable used to indicate the current battery mode (12V or 20V battery mode)
dispstr(6)={'0′,'0′,'.','0′,'/',0} :- Matrix used to define the format of the OLED
Header files and libraries used in the code
#include : – Standard AVR header for input and output
#include : – Standard AVR header to provide time delays
#include Standard AVR header including program space utilities
#include “OLED_LIB.C”: – General purpose library containing functions to work with 0.96” OLED. This library can be used with any AVR microcontroller. Note that OLED_LIB defines pin 2 as SDA and pin 3 as SCL of ATtiny85.
#include “FONT_BASIC_16x8.H”: – This header file contains alphabet, numbers and symbols of size 16 × 8 pixels (small).
#include OLED_NUMS_32x24.H: – This header file only contains numbers of size 32×24 pixels (large) to display the voltage value.
Functions used in the code
ADC_init : – function used to initialize the ADC channel.
readADC : – function used to read the analog voltage of ADC channel 1
OLED_init : – function used to start OLED display
OLED_floodfill : – function used to display bright light by passing parameter 0xFF or clear OLED by passing parameter 0x00.
Algorithm –
1) When the voltmeter circuit is turned on, firstly, the OLED is initialized and checked by displaying a bright light. Then the OLED display turns off and a welcome message – “Welcome to Miniature Voltmeter” flashes on it. The MCU starts flashing an LED to indicate that it is working properly. The MCU checks the battery mode status (12V or 20V mode) by checking the digital input on pin 6 of the Attiny85. Now the controller is ready to take voltage readings.

DDRB = BLINKER;

OLED_init ; //start displaying OLED

_delay_ms(10);

OLED_floodfill(0xFF); // displays OLED with bright light as self-test

_delay_ms(500);

ADC_init ; // initialize the ADC system

OLED_floodfill(0x00); //blank OLED display

_delay_ms(500);

OLED_show_str_16x8 ( ”WELCOME TO“,6,0); // a welcome message

OLED_show_str_16x8 ( ”MINIATURE“,11,3); //is displayed on the OLED

OLED_show_str_16x8 ( " VOLTMETER ",6,6); // how to self-test text display on OLED

_delay_ms(1000);

OLED_floodfill(0x00); //blank OLED display

_delay_ms(300);

2) The user can take voltage reading from a standard (or known) voltage source and adjust the respective potentiometer (according to the current battery mode) to calibrate the voltmeter. In this circuit, the voltmeter is calibrated using a standard 12V voltage source where the ADC reading is set to 900 (for 12V input) in 12V battery mode and 750 (for 12V input) in battery mode. 20 V. After calibration, the miniature voltmeter is expected to provide exactly accurate voltage readings.

3) The MCU detects the battery voltage of 12 V or 20 V on pin 7 (ADC Channel 1) using the readADC function and stores this read value in variable A. The ATtiny85 has a 10-bit ADC channel, so the ADC reading (stored in variable A) can range from 0 to 1023. For voltage comparison to indicate battery status, the ADC reading of 750 is equivalent to 12 V in the case of 20 V battery mode and the ADC reading of 900 is equivalent to 12 V in the case of 12 V battery mode.
4) The value stored in A is converted into voltage and stored in the variable V assuming that the value of A being 750 (in the case of 20V battery mode) or 900 (in the case of 12V battery mode) is equivalent to the actual voltage of 12V. Please note that the conditions for indicating battery status are defined in the code accordingly. The above assumption is derived from the calibration of the miniature voltmeter. In 20V battery mode, using known voltage of 12V, the ADC reading is calibrated to 750 using the potentiometer. Similarly, in 12V battery mode, when using the known voltage of 12V, the ADC reading is calibrated to 900 using the respective potentiometer. Note that the conversion of ADC reading to voltage here depends on calibration. The standard formula for single-ended conversion (Vin = ADC*Vref/1024) is not used in the code, considering the fact that the rest voltage of different batteries may be different and may not fit a standard calibration equation.
PORTB ^= BLINKER; //toggle blinker to indicate MCU is working
 A = readAdc ( 1 ); // read ADC value from channel no 1
 curr_mode = (PINB & BATT12V); // check the mode of operation by usage of jumper J2
 // for 12V battery mode or 20VDC voltmeter
 if ( prev_mode != curr_mode )
 {
 OLED_floodfill(0x00);
 _delay_ms ( 50 );
 }
 if (curr_mode>0)
 V = A/6;
 else
 V = A/5;
5) The value of V is compared in else-if statements to indicate the charging status of the connected battery.
 if ( curr_mode>0 ) // in case of 12V battery mode, appropriate status is displayed on OLED 
{
 OLED_show_str_16x8 ( "12V BAT.METER",0, 0);
 if (V>150)
 OLED_show_str_16x8 ( "NOT 12V BAT " , 0 .6);
 else if (V>135)
 OLED_show_str_16x8 ( "OVER CHARG " , 0 .6);
 else if (V>120)
 OLED_show_str_16x8 ( "BATT. GOOD " , 0 .6);
 else if (V>100)
 OLED_show_str_16x8 ( "BATT. LOW " , 0 .6);
 else if (V>90)
 OLED_show_str_16x8 ( "BATT. WEAK " , 0 .6);
 else if (V>60)
 OLED_show_str_16x8 ( "BATT. DEAD " , 0 .6);
 else //if (V<30)
 OLED_show_str_16x8 ( "BATT.ABSENT " , 0 .6);
 }
6) The V value is formatted in decimal notation and the read voltage is shown on the OLED display.
 dispstr(0)=V/100+'0';
 V=V%100;
 dispstr(1)=V/10+'0';
 dispstr(2)='.';
 dispstr(3)=V%10+'0';
 dispstr(4)='/';
 dispstr(5)=0;
7) The ADC reading stored in A is compared to 1000 to check if the voltage exceeds the designated range.
 if ( A>1000 ) // in case the ADC read value is out of range then display as OVERFLOW
 {
 OLED_show_str_16x8 ( " OVERFLOW " , 0 ,0);
 _delay_ms ( 150 );
 OLED_show_str_16x8 ( "" , 0 ,0);
 _delay_ms ( 100 );
 }
Working: Initial setting:
After assembling the circuit on a printed circuit board, connect the power supply by turning SW1 towards the 9V battery. Then load/write the miniVoltMeter.hex file into the MCU (ATTINY85) using any AVR programmer.
Initially, OLED displays all pixels (128×64) in ON mode, making the screen bright for a while. It then displays a welcome message like WELCOME TO MINIATURE VOLT METER. It then displays the random voltage, which has not yet been calibrated.
Now configure the board to 12V BATTERY MODE, connecting Jumper J1 and disconnecting Jumper J2. Then connect a known voltage source of about 12 VDC or a 12 V battery to the signal terminals (or connect a multimeter in parallel to the terminals to know the exact input voltage). Now, configure the VR1 trim-pot to show the correct voltage on the OLED on the display.
Now, configure the board to VOLT METER MODE by disconnecting jumper J1 and connecting jumper J2. Then, with the same voltage source as the input signal, adjust the VR2 trim-pot to display the correct voltage on the OLED.
Now, the calibration is complete and the circuit is ready for use. Disconnect the signal input and configure the board to one of the modes as needed.
There are two modes of operation. 12V and 20V.
For 12V battery mode, connect jumper J1 and disconnect jumper J2. The voltage is read by the ADC channel of the MCU and displays the battery voltage on the OLED in large font. The top line of the OLED is displayed as 12V BAT. METER and final result show battery status as BATT.ABSENT / BATT.DEAD / BATT.WEAK / BATT.GOOD / OVER CHRG. etc.
For 20 VDC voltmeter mode, disconnect jumper J1 and connect jumper J2. the input signal voltage is read by the ADC channel of the MCU and displayed on OLED with large font in the center. Here, the top line of the OLED shows VOLT METER and the bottom line shows 20 DC VOLTS.
In both modes, if the input voltage exceeds the ADC input voltage value (about 5VDC), the upper line will flash with the message OVERFLOW. If, to read weak signals or voltages lower than 8VDC, SW1 must be turned to connect the 9V battery. The miniature voltmeter circuit can be used as a fast DC voltmeter for desktop purposes, voltage and status monitor for battery chargers, battery banks, etc.

Project source code




 /*
 Filename: miniVoltMeter.C
 author: Fayaz Hassan
 Date: 15-02-2018
 MCU: ATtiny85 (A)
 Display: OLED (I2C)
 */
 #define F_CPU 1000000UL
 #include 
#include 
#include 
#include "OLED_LIB.C"
 #define BLINKER 0b00000001
 #define BATT12V 0B00000010

 //================================================ ========================================

 void ADC_init ( )
 {

 ADCSRA = ( (1 << ADPS2) (1 << ADPS1) (1 << ADPS0) (1 << ADEN) );

 }
 
//================================================ ========================================

 int readAdc (int channelno)

 {

 ADMUX = (channelno%4);
 ADCSRA = (1 << ADSC);
 while (ADCSRA & (1 << ADSC));
 return ADC;

 }
 //================================================ ========================================
 int main()

 {
 int V=0;
 int A=0;
 int prev_mode = -1;
 int curr_mode = 0;
 char dispstr(6)={'0','0','.','0','/',0};
 _delay_ms ( 500 );
 DDRB = BLINKER;
 OLED_init ;
 _delay_ms ( 10 );
 OLED_floodfill(0xFF);
 _delay_ms ( 500 );
 ADC_init ( );
 OLED_floodfill(0x00);
 _delay_ms ( 500 );
 OLED_show_str_16x8 ( " WELCOME TO ",6,0);
 OLED_show_str_16x8 ( " MINIATURE ",11,3);
 OLED_show_str_16x8 ( " VOLT METER ",6,6);
 _delay_ms ( 1000 );
 OLED_floodfill(0x00);
 _delay_ms ( 300 );
 readAdc ( 1 );
 readAdc ( 1 );
 while(1)

 {

 PORTB ^= BLINKER;
 A = readAdc ( 1 );
 curr_mode = (PINB & BATT12V);
 if ( prev_mode != curr_mode )

 {
 
OLED_floodfill(0x00);
 _delay_ms ( 50 );

 }

 if (curr_mode>0)
 V = A/6;
 else
 V = A/5;
 if (curr_mode>0)
 {

 OLED_show_str_16x8 ( "12V BAT.METER",0, 0);
 if (V>150)
 OLED_show_str_16x8 ( "NOT 12V BAT " , 0 .6);
 else if (V>135)
 OLED_show_str_16x8 ( "OVER CHARG " , 0 .6);
 else if (V>120)
 OLED_show_str_16x8 ( "BATT. GOOD " , 0 .6);
 else if (V>100)
 OLED_show_str_16x8 ( "BATT. LOW " , 0 .6);
 else if (V>90)
 OLED_show_str_16x8 ( "BATT. WEAK " , 0 .6);
 else if (V>60)
 LED_show_str_16x8 ( "BATT. DEAD " , 0 ,6);
 else //if (V<30)
 OLED_show_str_16x8 ( "BATT.ABSENT " , 0 .6);
 }

 else

 {

 OLED_show_str_16x8 ( " VOLT METER " ,4, 0);
 OLED_show_str_16x8 ( "0-20 DC VOLTS" ,0 ,6);
 }

 dispstr(0)=V/100+'0';
 V=V%100;
 dispstr(1)=V/10+'0';
 dispstr(2)='.';
 dispstr(3)=V%10+'0';
 dispstr(4)='/';
 dispstr(5)=0;
 if (dispstr(0)=='0' )
 dispstr(0) = ':';
 OLED_show_str_32x24 ( dispstr , 5, 0.2); 
if (A>1000)

 {

 OLED_show_str_16x8 ( " OVERFLOW " , 0 ,0);
 _delay_ms ( 150 );
 OLED_show_str_16x8 ( " " , 0 ,0);
 _delay_ms ( 100 );

 }

 prev_mode = curr_mode;

 }

 return 0;

 }

Circuit diagrams

Circuit-Diagram-MiniatureVOLT-METER-cum-Battery-Voltage-Monitor

Project video

https://www.youtube.com/watch?v=U34_OSzjZhQ

Related Content

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.