Latest Post

Tutorial for Atmeag8 /AVR based Voltmeter

               It measures the Ac voltage and shows readings in RMS value.

Basics Of AC signal 

The AC signal ,its amplitude varying in accordance with time. In india AC frequency is 50Hz.

Then the Time period one full cycle ,
        
  T = 1/frequency 
  T = 1/50Hz = .002second 
                     = 20milli Second
                     = 10 Milli second for Half Cycle








There are a lot of methods for measuring AC volt digitally

we could find the RMS value by multipliying the Peak Voltage with 0.707. 

   Vrms = Peak Voltage * 0.707 .

Approximatly Indian Line AC Peak volatge is 325v.

  Example : 
                 325v *0.707 = 229.775Volt      .(appro = 230Vrms).

But Microcontroller could only sense  up to 5 volt  as well as it couldnt sense negative values

so we cannot  give 230 volt directly to It .
It can be rectify by using a Stepdown transformer ,which has an advantage of safety.
Ac voltage can be reduce by using transformer to comfortable range . (ie 0 to 5volt DC)

make the calculation  as   ,
 The voltage Divider would give a 5 volt when the Vrms 230v. [will be more give details on the way ].


The full wave rectifier output will give to ADC of micro controller . Then do corresponding coding.

Microcontroller Section 
I am using here Amega8. 
we need to mesure only one half cycles repeatedly because  the waves same are repeating 
Basics

I selected , the F_cpu frequency is the internal RC Oscillator 8MHz.
Atmega8 ADC uses Prescalar [frequency reducer or divider by 2th,4th etc]
Atmega ADC  Prescale Frequency is in between 50Khz to 200Kz
ADC conversion time is in between 13 to 260 micro second.

ADC frequency = F_cpu / Prescaler

                         = 800,000HZ  / 8
  
                        = 62.5KHz

At high frequency ADC conversion would be fast while at lower frequency the conversion will be more accuracy.

ADC conversion time Calculation 

Conversion Time = 1/ADC frequency

                           = 1/62500 
                           = 0.000016 Second
                           = 0.016 Milli Second
                           = 16 Micro Second.     [At 62.500KHz]

So 16 mirco second would taken for one cycle of  conversion.with 62,5KHz.

13 ADC cycles required for one conversion

ie,
    13 * 16Micro Second = 230 Micro Second [approximately]
                                      = 230us.

The Half wave has 10milli second time duration.[100000microsecond].

There the available conversion times is 

                                        =  Total time period for a half cycle /one ADC conversion time  
                                        
                                        = 10000 micro second / 230 micro second
                 
                                        = 43.4 samples  [ for one half cycleie 10 milli second]

                                       
    Image Shows only 7 Samples per half cycles .in our case it is 43

And again reduced the sampling to 40 .

calculation of Vpeak

 Takes the largest Vpeak from the 40 samples.
Vrms = Vpeak * .707
*****************************************************************************

Atmega8 ADC StepSize Calculation

The Atmega8 ADC is a 10 Bit /[ie the Maximum high value is 1023 =1111111111] at which the ADC will give fullscale Value .
The ADC  require a clock as well as a reference voltage .
The resolution of ADC output decide the Step size.

ADC o/p = Vin * 1024 / Vref

Examples;
  Vin =5volt , Vref =5volt 

                 ADC o/p = 5 * 1023 /5 = 1023 [ADC highest Value]

               Step Size  voltage = Vref / 1023 = 0.004887 volt =4.88millivolt
             One binary digit changes when 4.88volt changes takes place


           

     

Image's Step Size is 1.25 volt




*******************************************************************************************************

 Microcontroller based Digital AC Meter Part 2 Code And Circuit

First Part available here



Circuit Diagram 

#include"lcd.h"
#include "adc.h"
#include "delay.h"
double volt_read_disply();
int main(void)
  
{   
     int adc_value1=0;  
  LCD_SetUp(PB_0,PB_1,PB_2,P_NC,P_NC,P_NC,P_NC,PB_4,PB_5,PB_6,PB_7);
  LCD_Init(2,16);     
     adc_init();
    
     LCD_Clear();
  LCD_GoToXY(0,0);  
  
  LCD_DisplayString("  g-Electron"); 
  _delay_ms(1000); 
  
 while(1) 
 {  
       adc_value1 =  volt_read_disply();
    LCD_GoToLine(1);  
    LCD_DisplayString(" Volt : ");    
    LCD_DisplayNumber(10,adc_value1,3);   
    LCD_DisplayString("V");  
    _delay_ms(1300);
 } 
}

double volt_read_disply()
{   int i,adc_value[40]={0}; int temp =0;
 
 adc_init();

  for(i=0; i<40;i++)                        // samples taking from 41 times 9.4milli second taken about on complte half cycle
   { 
   adc_value[i] = read_adc(0);  // reading voltage           
  }
   
  temp = adc_value[0];  
 for(i=0; i<40; i++)
 {
  if(temp<adc_value[i])
  temp=adc_value[i];
 }  
 
      return ((double)temp*0.224828935); // int to double casting
   
}

<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://3.bp.blogspot.com/-bsuAxmt2W2M/WaLG0a2OmfI/AAAAAAAAA7A/gwGwwZroobwxjmxNymj-UZbn0AfBv43mwCLcBGAs/s1600/Capture.PNG" imageanchor="1"><img border="0" data-original-height="604" data-original-width="846" height="456" src="https://3.bp.blogspot.com/-bsuAxmt2W2M/WaLG0a2OmfI/AAAAAAAAA7A/gwGwwZroobwxjmxNymj-UZbn0AfBv43mwCLcBGAs/s640/Capture.PNG" width="640" /></a>
<br />
<pre class="brush:csharp"></pre>
<pre class="brush:c++"> *<b> main.c</b>
 *
 *  Created on: Aug 12, 2017
 *      Author: thannara123




#include<stdio .h="">
#define FALSE 0
#define TRUE  1  // 0r //!FALSE
struct menu
 {
   char menu_up_key;
   char menu_down_key;
   char menu_enter_key :1; // bit feild 1 bit
 };
struct menu s1= {0}; //s1.menu_up-key =1;
void struct_1( struct menu,const char *menu_display[]);



int main()
{

     const char *menu_display[10];
      menu_display[0] = "Menu0";
      menu_display[1] = "Menu1";
      menu_display[2] = "Menu2";
      menu_display[3] = "Menu3";
      menu_display[4] = "Menu4";
      menu_display[5] = "menu 5";
      menu_display[6] = "menu 6";


       struct_1(s1,menu_display);
             getchar();
             return 0;

      }


void struct_1(struct menu s1 ,const char *menu_display[])
{

     char ch;
      do{
            ch=getch();


            if(ch!='\0')
            {
              ch=getch();
              if(ch=='H')
              {
               s1.menu_up_key++;
               if(s1.menu_up_key==7)
                 s1.menu_up_key =0;
            // printf("UP\n");
                  printf(" %s\n",*(s1.menu_up_key+menu_display));
               }
         else    if(ch=='P')
               {
              s1.menu_up_key--;
              if(s1.menu_up_key==-1)
                  {  s1.menu_up_key =6;
                   goto here;
                  }
                //printf("down\n");

                  here:
         printf("%s\n",*(s1.menu_up_key+menu_display));


                   }

            }
               }
              while(ch!='e');// while oka key
}
</stdio></pre>
<pre class="brush:csharp">/*
 * button_key.c
 *
 * Created: 7/30/2017 12:02:39 PM
 *  Author: Krishna
 */ #include <avr io.h="">
 #include "delay.h"
  #include "button_key.h"
  #include "lcd.h" 
   
void menu_key_display(struct menu s1,const char *menu_display[]);
void UP_Down_Keyvalue(struct menu s1,int i,int j);

 /* Function Key Value For get key  */
int Key_pressed(void)
 {
 while(1){
    if (LEFT_S) {  while(LEFT_S);return 1; }     
 if (RIGHT_S){  while(RIGHT_S);return 2; }
 if (UP_S)  {  while(UP_S); return 3; }
 if (DOWN_S) { while(DOWN_S);return 4 ; }
 if (OK_S) { while(OK_S);return 5 ; }
 }
 }


 /* Function Key Value For Up Key  &amp; Enter*/

 void menu_key_display(struct menu s1,const char *menu_display[])
 {  
  int ch;
   int a;
  int  menu_position =0;
   LCD_DisplayString(menu_display[menu_position]);
            do{ 
   
    repat:         
    ch = Key_pressed();
    if(ch==1||ch==2)
    {
                  if(ch==2)
                    {  if(ch==2)
                   { if(s1.menu_side_key==4)
                     s1.menu_side_key = 0;
                  LCD_Clear();
                  LCD_GoToLine(0);
                              LCD_DisplayString(*((++s1.menu_side_key)+menu_display));
         menu_position=1;           
        
                 }
                      }
                   else if(ch==1)
                   {  
                             if(ch==1)
                    {if(s1.menu_side_key==1 ||s1.menu_side_key==0)
                      {
                    s1.menu_side_key=5;
                      }
                      LCD_Clear();
                            LCD_DisplayString(*((--s1.menu_side_key)+menu_display));                           
          menu_position=1;  
                         }
                   } 
          }
     
    if(menu_position==0)
    goto repat;
        }while(ch!=5);
      
        a = s1.menu_side_key;
  switch(a)
     {
 case 1: // set time
          {
    LCD_Clear();
       LCD_GoToLine(0);
       LCD_DisplayString(menu_display[5]);
    LCD_GoToLine(1);
    LCD_DisplayString("  HH:MM:SS:PM/AM");
    UP_Down_Keyvalue(s1,2,4);   
          break;
          }
 case 2: // Set date
        {
         LCD_Clear();
         LCD_GoToLine(0);
         LCD_DisplayString(menu_display[6]);
      LCD_GoToLine(1);
      LCD_DisplayString("  DD:MM:YY");
      UP_Down_Keyvalue(s1,2,3);    
         break;
        }

 case 3: // set alarm
          {
         LCD_Clear();
            LCD_GoToLine(0);
         LCD_DisplayString(menu_display[7]);
      LCD_GoToLine(1);
      LCD_DisplayString(" HH:MM:SS:AM/PM");
      UP_Down_Keyvalue(s1,2,4);     
          break;
             }
 case 4:  // set alarm
           {
            LCD_Clear();
          LCD_GoToLine(0);
          LCD_DisplayString(menu_display[8]);
    LCD_GoToLine(1);
    LCD_DisplayString("  HH:MM:SS:PM/AM");
    UP_Down_Keyvalue(s1,2,4);   
          break;
            }
     }
   
  while(Key_pressed()!=5);
 
      
 }




 /* Function Key Value For UP_Down Key */
 void UP_Down_Keyvalue(struct menu s1,int i,int j)
 {   
 
  int ch,lower,upper;   
  do{ 
    if(j==4)
     {
      if(i==2)upper=1;
      if(i==3)upper=9;
      if(i==5)upper=5;
      if(i==8)upper =5;
      if(i==9)upper =9;
     }
      if(UP_S)  
      {
      while(UP_S);   
      if(s1.menu_up_key==upper)
      s1.menu_up_key = lower-1;
      LCD_GoToXY(1,i);
      LCD_Printf("%d",++s1.menu_up_key);
      s1.time[i-2]=s1.menu_up_key;         
      }
   else if(DOWN_S) // down
            
          {    while(DOWN_S);
            if (s1.menu_up_key==lower)
            s1.menu_up_key = upper+1;       
            LCD_GoToXY(1,i);
            LCD_Printf("%d",--s1.menu_up_key);
      s1.time[i-2]=s1.menu_up_key;      
     }
          if(RIGHT_S)
      
             { while(RIGHT_S);
       s1.menu_up_key=0;
          if(i==9) goto exit1;
          if(i==3||i==6)
          ++i;
          i++;
              }
      exit1:
           if (LEFT_S)
             { while(LEFT_S);
        s1.menu_up_key=0;
            if(i==2) goto exit2;        
            if(i==5||i==8)
            --i;
            i--;
    
             }
    exit2:continue;
  
  
  } while (ch!=5);  // if Okay key exit loop
 
 }







</avr></pre>
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>

Timer 

What is a Timer ? 

A Timer is device it sense the time interval and produce an output at a set value . example alarm Timer setting.(Timer in Wikipedia )


,What is the need of a timer in Micro controller ?
1) Some time  micro controller Code need some accurate  Delay  ( Example blinking An LED in each      accurate 1 sec. Look LED Blinking example

2)Some Time the code needs the code Repeat

3) Most of the Interfacing devices with micro-controller needs a clock (accurate interval of clocks)
   Example:   LCD module require Clock  Signal Look LCD Interfacing
               

Timer in 8051

Also a Timer actually require a clock pulse  (pling) .These pulse are given from controller  (actually it is in software based not giving ) see below picture
8051 type controller has  two Timer Timer 0 and Timer 1 (These two timer is the length of 16 bit ,0000 to  FFFF ).These Timer is named as TR0 and TR1. 



The Timer Setting/configuring  can controlling by the TMOD register 



These TMOD register Values is used to decide how the Timer Works .
Sample program




download the fullcode and Test

<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: center;">
<b>Switch Bounce</b></h2>
<div>
<b><br /></b></div>
Microcontrolers may not in Human thinking frequency .Human thinking frequency is lies in some of low Hz . &nbsp;Microcontroler works variety range of frequency ie ,12Mhz,20 Mhz etc . &nbsp;In a push Button &nbsp;micro controller interfacing, Human and Micro controller are feels that whether the push is pressed or not &nbsp;in different way as follows in the graph .<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-w9bjhmmUnqw/V6DD2eYyQfI/AAAAAAAABkk/pypViae-JRcMcCgZyWtXASp4fmDUXJyeACLcB/s1600/switch_debounce_04_lrg.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="225" src="https://1.bp.blogspot.com/-w9bjhmmUnqw/V6DD2eYyQfI/AAAAAAAABkk/pypViae-JRcMcCgZyWtXASp4fmDUXJyeACLcB/s320/switch_debounce_04_lrg.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-ogNB4Vrampg/V6DD2EN6QGI/AAAAAAAABkg/BNSeJko3f6453xg22toVn_yg-LxdBqoEACEw/s1600/switch_tutorial5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://2.bp.blogspot.com/-ogNB4Vrampg/V6DD2EN6QGI/AAAAAAAABkg/BNSeJko3f6453xg22toVn_yg-LxdBqoEACEw/s400/switch_tutorial5.png" width="400" /></a></div>
<br />
<br />
Some small duration pulse due to denounce generated as multiple touch error<br />
<b><u>Hardware solution</u></b><br />
<div>
It can be made by a resistor and a capacitor in the following manner or any other for comfortable<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-_NIjPZ3JGJo/V6DLltFP4jI/AAAAAAAABlI/68oiyuqCglkqrlqZ_7iDaiNWWUV1QUA9QCLcB/s1600/images%2B%25281%2529.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-_NIjPZ3JGJo/V6DLltFP4jI/AAAAAAAABlI/68oiyuqCglkqrlqZ_7iDaiNWWUV1QUA9QCLcB/s400/images%2B%25281%2529.png" width="346" /></a></div>
<br />
<br />
<br />
When ever the switch is pressed the capacitor will charge &nbsp;rapidly ,practically the first charge wil be across &nbsp;the &nbsp;,capacitor ,<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-KOEbmFnidfk/V6DMP0hT0CI/AAAAAAAABlM/BtAt9HboqN03MZQ2U1YQTth1-nNEHkwrwCLcB/s1600/switch_tutorial7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://4.bp.blogspot.com/-KOEbmFnidfk/V6DMP0hT0CI/AAAAAAAABlM/BtAt9HboqN03MZQ2U1YQTth1-nNEHkwrwCLcB/s400/switch_tutorial7.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So we can avoid the denouncing effect .</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The capacitor and the resistor will be select in accordance with time constant . as follows</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-zz7vt62r5t8/V6DNSQmtzBI/AAAAAAAABlc/gGMZ3wNukysx_YbGdLylmQiHpDgER3M0wCLcB/s1600/debounceR.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-zz7vt62r5t8/V6DNSQmtzBI/AAAAAAAABlc/gGMZ3wNukysx_YbGdLylmQiHpDgER3M0wCLcB/s1600/debounceR.jpg" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-RM1cwzYU9qU/V6DNSnnQH_I/AAAAAAAABlg/UsH9p4d5AE4KavWofyPnqgBcEWBn_DXVQCLcB/s1600/debouncevcap.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="233" src="https://4.bp.blogspot.com/-RM1cwzYU9qU/V6DNSnnQH_I/AAAAAAAABlg/UsH9p4d5AE4KavWofyPnqgBcEWBn_DXVQCLcB/s640/debouncevcap.jpg" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<a href="https://1.bp.blogspot.com/-zz7vt62r5t8/V6DNSQmtzBI/AAAAAAAABlc/I0f-OLDqC-c2HDU_ue1xZJO8pOGD6P14ACEw/s1600/debounceR.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-zz7vt62r5t8/V6DNSQmtzBI/AAAAAAAABlc/I0f-OLDqC-c2HDU_ue1xZJO8pOGD6P14ACEw/s1600/debounceR.jpg" /></a><br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For more information <a href="http://www.ganssle.com/debouncing-pt2.htm">go here</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Will be update&nbsp;</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br /></div>

Parallel to serial  Interfacing with Micro controller 

Interfacing with 74HC165 with 8051


   I am trying to make multiple input with using minimum input port of micro controller ,ie 3 wire .
By using a 3 wire we can interface more input as we wish.


 I am making a tutorial for it , Basics of 74HC165  which is a parallel to serial shift register .


   












Only three pin is connected with this IC . 
1)   SH/LD  or PL  is used load  parallel data to the IC .A low pulse (ground) is applied for store the         parallel data at the pin from A to H . And a High (5 Volt) is applied to stop the reading from the          PIN A to H .
2) Then to read the loaded or saved data to Micro controller we have to give clock to the PIN 2 of           74HC165  (CLK) . 8 pulses is applied to read 8 bit (Pin A to B)

3) QH / SO . serial out pin is used to get the stored parallel data to serially.

The CLK INH pin must be connect in ground for enable clock.


    To use cascaded 74HC165 for increasing i/p .connect the Seriall output pin (PIN 9) of first satge into serial input of first stage see the following circuit.
   




see the code below





  
  #include  
#include
#include "lcd.h"  
sbit PL  = P1^0;   // Loading parallel data to HC165.
sbit CLK = P1^1;   // Clock pulse to HC165.
sbit Beep  = P1^2;   // 
sbit data_in  = P1^3;

  void clock(void);
  void display(unsigned char value);
     
void main()
{  
 unsigned char position ,no_of_ip = 17;
  lcd_init();
  string("   gElectron");     
  while(1)

   {  
      PL = 0 ;
  delay(2);
  PL = 1;

   for(position = 1; no_of_ip > position; position++ , clock())
  {     
  
    if(data_in == 1)
     display(position);   

  }
   } 
}  

 void clock(void)
 {
   CLK = 1;
   delay(1);
   CLK = 0;

 }

void display(unsigned int value)
  {  
  unsigned int a[1];
    Beep =   1;
    lcd_init();
 lcd_cmd(0x01);   
    string("Pressed key ");
    lcd_cmd(0xc0); 
  sprintf(a,"%d",value);  
     string(a); 
     delay(1);
     Beep = 0;
     
  }   


Download the whle file here github.


MKRdezign

Test

Contact Form

Name

Email *

Message *

Powered by Blogger.
Javascript DisablePlease Enable Javascript To See All Widget