728x90

728x90

Showing posts with label Voltmeter. Show all posts
Showing posts with label Voltmeter. Show all posts

Monday, March 1, 2021

Arduino Reading The Analog Voltage And Display On The SH1106 OLED GLCD

Overview

Analog Uno has up to six analog input pins ranges from A0 to A5. Since the ADC module of ATMega328P is 10-bit resolution, the digital reading result ranges from 0 to 1023. By default the reference voltage of the Arduino module is internally connected to the +5V VDD.

With the analogRead() function, it return the 10-bit analog reading from any channel between A0 and A5. The argument of this function counts from 0 to 5, representing the A0 to A5 analog channel.

SH1106 OLED GLCD is a modern easy to use with a simple shared library. The interfacing to this display from Arduino requires only four pins.

Arduino Interfacing And Programming

In this example I use the analogRead() function to read the analog input voltage fed to A0. A POT as shown in the picture below varies the input voltage from 0 to 5 V.

Arduino Reading The Analog Voltage And Display On The SH1106 OLED GLCD
A picture of this programming example

Without any voltage divider circuit to scale down the input voltage, the maximum voltage reading is 5 V. I wish to make a simple 100 V DC voltmeter at next post.

Arduino Reading The Analog Voltage And Display On The SH1106 OLED GLCD
Schematic Diagram

I add a by pass capacitor C1 to eliminate noise. The capacitance could be a 10 nF or a 100 nF.

Arduino sketch lists below.

Arduino Reading The Analog Voltage And Display On The SH1106 OLED GLCD
I took a screen shot of sketch due to lack of code formatting in blog

You can click here to download archive of this example.


Saturday, January 2, 2021

PIC18F4550 ADC Simple Digital Volt Meter

The ADC module of PIC18F4550 could read an analog input voltage up to 5 V DC with some DC offset. However, the outside analog voltage fed to the ADC could be greater than 5 V DC by adding a simple voltage divider circuit. 

The voltage divider circuit is very simple, built by two resistors in this case. The output voltage from the divider circuit is smaller than the input according to the dividing factor. The factor created by picking up a different resistances of the selected's. The designer may decide and take a little math calculation using voltage divider theorem to get a specific division factor. 

I don't show the overall process of math calculation here. You can see this post to get a full detail.

A simple DIY DC voltmeter with PIC18F4550
The MCU reads the analog input voltage fed to RA0.

PICC Source Code



Schematic Diagram

A simple DIY DC voltmeter with PIC18F4550
Schematic Diagram

Click here to download the zip file of this example.

If you want a standard PCB for ATMega32 micro-controller, you can order my AVR Microcontroller project from PCBWay with a reasonable price. Click here to get a free $5 credit for new account.

Interfacing ATMega32 to 74HC595 shift register
ATMega16 ATMega32 Experiment Board PCB from PCBWay

 

Saturday, June 27, 2020

ATMega32 50 Volts DC Digital Voltmeter

Analog To Digital Converter (ADC) Module

The ADC module relates only with analog voltage value from any analog-output sensors or other analog circuits. Analog voltage value could be scaled to a smaller range value by using a two-resistor voltage divider circuit. For example a 50 V DC voltage could be scale to a range of lower than 5 V DC because the maximum analog reference voltage of ADC module of this device is +5 V DC.

ADC Scaling Circuit Using Voltage Divider Rule


For the voltage divider of two resistor, I do a calculation as follow.

ATMega32 50 V DC Digital VoltmeterATMega32 50 V DC Digital Voltmeter 

V (ADC) is the analog voltage fed to the ADC pin. It's the measuring voltage divided by 11, or 0.09 of the measuring voltage.

Using these two values of resistor, we could measure the analog voltage up to 50 V DC.

Program For Digital Voltmeter


ATMega32 50 V DC Digital Voltmeter
A sample of program. The voltage reading is 26.37 Volts.

Atmel Studio C source code. Click here to download source file.

 

Schematic diagram is here.

ATMega32 50 Volts DC Digital Voltmeter
The CPU clocks at 4 MHz. The display made up to five distinct single-digit SSDs.


Saturday, June 6, 2020

Making a simple +5 V voltmeter with ATMega32 ADC module

In the previous post, we have introduce about the ADC module of ATMega32. Actually the maximum reference voltage of the ADC is +5 V in usual. From this concept we can measure an input analog voltage input to any ADC channel at +5 V full scale reading.

The reading ADC value in the single ended conversion could be obtained from:
Making a simple +5 V voltmeter with ATMega32 ADC module
Reference voltage VREF is normally +5 V. Input voltage must not exceed +5 V.

To calculate the voltage, we can obtain it from:
Making a simple +5 V voltmeter with ATMega32 ADC module 

In this example, I use ADC0 to read an analog input voltage fed from a POT. The POT varies an analog output voltage from 0 V to +5 V DC. The MCU displays the reading result of the voltage from 0.0 V to 5.0 V.

Making a simple +5 V voltmeter with ATMega32 ADC module
ADC0 read the input analog voltage. PortC and PortD drive a two-digit
SSD. The voltage reading is from 0.0 V to 5.0 V.

Source code is here:

#include <avr/io.h>
#define  F_CPU 4000000UL
#include <util/delay.h>
int main(void)
{ float voltage;
 char _voltage;
 char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
  0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
    //PortC as output
    DDRC=0xFF;
    //PortD as output
    DDRD=0xFF;
    //PA0 or ADC0 as an analog input
    DDRA=0;
    //Turn on the ADC module
    ADCSRA|=(1<<ADEN);
    while (1)
    {
     //Start the conversion
     ADCSRA|=(1<<ADSC);
     //Wait for the completion
     while((ADCSRA&(1<<ADSC))==1);
     /*Convert ADC to voltage*/
     voltage=(ADCL+(ADCH<<8))*5.0/1024;
  voltage*=10;
  /*convert float to SSD data*/
  _voltage=(char)voltage;
  /*Displaying the Data*/
  PORTD=0x00;
  PORTC=ssd[_voltage/10]|0x80;
  PORTD=0x01;
  _delay_ms(10);
  PORTD=0x00;
  PORTC=ssd[_voltage%10];
  PORTD=0x02;
  _delay_ms(10);
    }
}

Making a simple +5 V voltmeter with ATMega32 ADC module
The ADC reading is 2.5 V analog voltage.

Back to main tutorial page ATMega32 tutorials in C with Atmel Studio 7.




Saturday, May 30, 2020

Designing a positive and negative DC voltage meter using the 10-bit ADC module

The ADC module's resolution is up to 10-bit, yield an acceptable measuring accuracy with the voltage within 50 V DC.

In this example, I use this ADC module to measure a DC voltage within -25 V to +25 V. So the total voltage magnitude is 50 V.

Since the maximum reference voltage is 5 V in magnitude. I use a voltage divider circuit to scale the input voltage to the lower 5 V.


Designing a positive negative voltage meter using the 10-bit ADC module

From the voltage divider:

Designing a positive negative voltage meter using the 10-bit ADC module

The V(ADC) is at 5 V maximum. V(MEASURE) could be 50 V in magnitude. So we divide the V(MEASURE) by 11.
But in the program simulation I don't use 11. I use 9 because it cause a lot of error. 
In the real hardware test, you can try 11.

The voltmeter display the measuring voltage on a five-digit multiplexed SSD. The ADC reading is scheduled every one second due the timer 0 scheduling. The analog DC input voltage is fed from a -25 V and +25 V voltage terminals, giving a 50 V DC magnitude. 

Designing a positive and negative DC voltage meter using the 10-bit ADC module
Schematic diagram a digital two poles voltmeter. A POT used for adjusting the analog input
voltage, varies from -25 V to +25 V.

Source code:

#include<xc.h>
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = ON
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
/*_XTAL_FREQ use for __delay*/
#define _XTAL_FREQ 4000000

void driveDisplays(  int analogRead){
 unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 float voltage;
 int _voltage;
 /*Voltage Calculation total reference is
  +5V with centered ground*/
 voltage=((5.0*((float)(analogRead)/1024))-2.5)/9.1;
 //voltage/=11;
 _voltage=(int)(voltage*10000);
 /*Check negative voltage*/
 if(_voltage&0x8000){
     _voltage=-_voltage;
     PORTD=0x00;
 PORTC=0x40;
 PORTD=0x01;
 __delay_ms(10);
 }
 /*Decimal Place*/
 PORTD=0x00;
 PORTC=ssd[_voltage/1000];
 if(_voltage>=1000)
     PORTD=0x02;
 __delay_ms(10);
 /*Floating point*/
 PORTD=0x00;
 PORTC=ssd[(_voltage%1000)/100]|0x80;
 PORTD=0x04;
 __delay_ms(10);
 PORTD=0x00;
 PORTC=ssd[(_voltage%100)/10];
 PORTD=0x08;
 __delay_ms(10);
 PORTD=0x00;
 PORTC=ssd[_voltage%10];
 PORTD=0x10;
 __delay_ms(10);
}
int readADC(void){
    GO=1;
    while(GO);
    return (ADRESH<<8)+ADRESL;
}
void portInit(void){
    /*Analog and digital Port
     Configuration*/
    PORTB=0x00;
    PORTC=0x00;
    PORTD=0x00;
    /*RB4 for analog input*/
    TRISB4=1;
    TRISC=0x00;
    TRISD=0x00;
}
void adcInit(void){
    /*Select external Voltage reference
     +2.5V to -2.5V*/
    VCFG1=1;
    VCFG0=1;
    /*Result is right justify*/
    ADFM=1;
    /*By default is analog,
     but again set it to analog*/
    ANS11=1;
    /*Select FRC Clock of ADC module*/
    ADCON0bits.ADCS=0x03;
    /*Turn on ADC Module*/
    ADON=1;
    /*Select AN11 RB4*/
    ADCON0bits.CHS=0x0B;
    /*initiate a conversion*/
    GO=1;
    /*Wait until GO=0 "done"*/
    while(GO);
}
void timerInit(void){
     /*Select FOSC*/
    T0CS=0;
    /*Select timer 0 Prescaler*/
    PSA=0;
    /*Enable Timer 0 Overflow
     interrupt*/
    T0IE=1;
    /*Turn on Global interrupt
     Control*/
    GIE=1;
    /*Clear interrupt flage*/
    T0IF=0;
    /*Clear timer 0 register*/
    TMR0=0;
}
int adcResult;
int counter=0;
void main(void){
    portInit();
    adcInit();
    timerInit();
    
    while(1){
        driveDisplays(adcResult);
    }
}
void interrupt _ISR(void){
    if(T0IF){
        counter++;
        T0IF=0;
    }
    /* If it's one second*/
    if(counter>=15){
        adcResult=readADC();
        counter=0;
    }
}

Designing a positive and negative DC voltage meter using the 10-bit ADC module
A screen shot shows a positive voltage reading 24.84 V nearest to the positive terminal.

Designing a positive and negative DC voltage meter using the 10-bit ADC module
A screen shot shows a negative voltage reading -24.89 V nearest to the negative terminal.








Friday, May 29, 2020

Working with ADC references voltage of PIC16F887

By default two references voltages of the ADC internally connected to VDD and VSS, supplying a +5 V reference voltage for the ADC module. We can change the reference voltage to any value in the total range of +5 V DC.

The VREF+ and VREF- pin could be programmed to externally connect to any voltage reference. By assigning the 'VCFG0' to '1' allows the VREF+ pin connect to external positive voltage. Similarly, by assigning the 'VCFG1' to '1' allows the VREF- pin connect to external negative voltage.

For this example, I connect the VREF+ pin to +2.5 V and the VREF- pin to -2.5 V. Hence, the total reference voltage for the ADC module is,

Working with ADC reference voltage of PIC16F887

The step voltage size is 0.00488 V. In this case the the lowest voltage of -2.5 V gives the ADC reading result 0. While the maximum voltage +2.5 V gives the ADC reading result 1023. The zero analog input voltage yields the ADC reading result to 512.


Working with ADC reference voltage of PIC16F887
Schematic diagram. RA3/AN3 is used for positive voltage reference connects to +2.5 V.
RA2/AN2 is used for negative voltage reference connects to -2.5 V. The voltage reading displays
between -2.5 V to +2.5 V.

Source code:

#include<xc.h>
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = ON
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
/*_XTAL_FREQ use for __delay*/
#define _XTAL_FREQ 4000000

void driveDisplays(  int analogRead){
 unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 float voltage;
 int _voltage;
 /*Voltage Calculation total reference is
  +5V with centered ground*/
 voltage=(5*((float)(analogRead)/1024))-2.5;
 _voltage=(voltage*100);
 /*Check negative voltage*/
 if(_voltage&0x8000){
     _voltage=-_voltage;
     PORTD=0x00;
 PORTC=0x40;
 PORTD=0x01;
 __delay_ms(10);
 }
 /*Decimal Place*/
 PORTD=0x00;
 PORTC=ssd[_voltage/100]|0x80;
 PORTD=0x02;
 __delay_ms(10);
 /*Floating point*/
 PORTD=0x00;
 PORTC=ssd[(_voltage%100)/10];
 PORTD=0x04;
 __delay_ms(10);
 PORTD=0x00;
 PORTC=ssd[_voltage%10];
 PORTD=0x08;
 __delay_ms(10);
}
int readADC(void){
    GO=1;
    while(GO);
    __delay_ms(10);
    return (ADRESH<<8)+ADRESL;
}
void main(void){
      int adcResult;
    /*Analog and digital Port
     Configuration*/
    PORTB=0x00;
    PORTC=0x00;
    PORTD=0x00;
    /*RB4 for analog input*/
    TRISB4=1;
    TRISC=0x00;
    TRISD=0x00;
    /*Select external Voltage reference
     +2.5V to -2.5V*/
    VCFG1=1;
    VCFG0=1;
    /*Result is right justify*/
    ADFM=1;
    /*By default is analog,
     but again set it to analog*/
    ANS11=1;
    /*Select FRC Clock of ADC module*/
    ADCON0bits.ADCS=0x03;
    /*Turn on ADC Module*/
    ADON=1;
    /*Select AN11 RB4*/
    ADCON0bits.CHS=0x0B;
ADON=1;
    /*initiate a conversion*/
    GO=1;
    /*Wait until GO=0 "done"*/
    while(GO);
    while(1){
        adcResult=readADC();
        driveDisplays(adcResult);
        
    }
}

Working with ADC reference voltage of PIC16F887
The screen-shot shows the analog voltage input of -1.49 V. 

Back to main tutorials page.


Using ADC module to read analog voltage between 0 to 5 volts DC

In this previous post, we introduced about using ADC module of PIC16F887. Generally, the voltage references VREF+ and VREF- are internally wired to VDD and VSS, respectively. PIC16F887 could be supplied in a range of 2.0 V to 5.5 V. Generally, the supply voltage is +5 V because most external devices work at +5 V.


Step size is an analog voltage per unit of the ADC resolution.
Using ADC module to read analog voltage between 0 to 5 volts DC
For VREF+ = +5 V (VDD) and the VREF- = 0 V (VSS), we get the step size of
Using ADC module to read analog voltage between 0 to 5 volts DC
For example if the ADC result equal to 512, the voltage is,
Using ADC module to read analog voltage between 0 to 5 volts DC
Similarly, we get find the digital result equivalent to the analog input voltage,
Using ADC module to read analog voltage between 0 to 5 volts DC
In this example, I use a POT to adjust the analog input voltage varies from 0 to +5 V. To find the voltage we can use the equations listed above. But we can use another short form as,
In the C program, we must use the floating point to measure the analog voltage.

Using ADC module to read analog voltage between 0 to 5 volts DC
Schematic diagram. RB0 is AN12 analog input, measuring the input voltage
from 0 to +5 V. PORTC and PORTD display the measuring voltage with
one floating point.

The C source code:

#include<xc.h>
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = ON
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
/*_XTAL_FREQ use for __delay*/
#define _XTAL_FREQ 4000000

void driveDisplays(unsigned int analogRead){
 unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 float voltage;
 int _voltage;
 /*Voltage Calculation*/
 voltage=5*((float)analogRead/1024);
 _voltage=voltage*10;
 
 /*Decimal Place*/
 PORTD=0x00;
 PORTC=ssd[_voltage/10]|0x80;
 PORTD=0x01;
 __delay_ms(10);
 /*Floating point*/
 PORTD=0x00;
 PORTC=ssd[_voltage%10];
 PORTD=0x02;
 __delay_ms(10);
}
unsigned int readADC(void){
    GO=1;
    while(GO);
    __delay_ms(10);
    return (ADRESH<<8)+ADRESL;
}
void main(void){
    unsigned int adcResult;
    /*Analog and digital Port
     Configuration*/
    PORTB=0x00;
    PORTC=0x00;
    PORTD=0x00;
    TRISB=0x01;
    TRISC=0x00;
    TRISD=0x00;
    /*Result is right justify*/
    ADFM=1;
    /*By default is analog,
     but again set it to analog*/
    ANS12=1;
    /*Select FRC Clock of ADC module*/
    ADCON0bits.ADCS=0x03;
    /*Turn on ADC Module*/
    ADON=1;
    /*Select AN12 RB0*/
    ADCON0bits.CHS=0b1100;
    /*initiate a conversion*/
    GO=1;
    /*Wait until GO=0 "done"*/
    while(GO);
    while(1){
        adcResult=readADC();
        driveDisplays(adcResult);
        __delay_ms(20);
    }
}

Using ADC module to read analog voltage between 0 to 5 volts DC
Simulation screen shot. The measuring voltage displays 3.9 V DC.










320x50

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (57) AVR (58) CCS PICC (28) DAC (1) DHT11 (2) Display (106) Distance Sensor (3) DS18B20 (3) dsPIC (3) dsPIC30F1010 (3) dsPIC30F2010 (1) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (68) Interrupt (19) Keil (5) Keypad (10) LCD (48) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (73) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (5) PIC (108) PIC12F (3) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) PWM (11) RTC (9) Sensor (11) SH1106 (1) Shift Register (11) Shift Registers (3) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (31) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)

tyro-728x90