Опубликовано 2013-05-02 16:24:12 автором MRS

Digital ammeter on the microcontroller


In a previous article digital voltmeter on the microcontroller we have learned to measure the voltage with the ADC , and you probably even then the question arose: how to measure the current ? This is what we will discuss in this post . Since voltage is simple: missed through a voltage divider ( if necessary) and submitted to the ADC , as well as on current account ? To measure current, you can go two ways:
  • Measure voltage drop across the shunt (resistor relatively small resistance) skhema OS as usilitelya
  • Use Hall sensor to measure the magnetic field skhema OS as usilitelya The magnetic field generated by the conductor is proportional to the current which flows therethrough . The current sensor is a Hall effect magnetic field sensor which produces a voltage proportional to the magnetic field. Undoubted advantage of the current sensor is a Hall effect measurement circuit isolation and current meter .
The first option is more simple , well, then your rake. The fact that the shunt resistance is low , accordingly the voltage drop on it , too, is small. Increasing the shunt resistance , the voltage drop across it was somehow much for ADC , we will increase the loss in the shunt P = I 2 * R.Tut begs op amp ( it's a thing that can multiply the voltage . example, if we have the voltage varies in the range of 0-0.1 volts , then passed it through the OS with a gain of 50, we get a range of 0-5 volts ) . Circuit of the op-amp as an amplifier shunt is shown below skhema OS as usilitelya The sensor signal is amplified DA1.1, buffered repeater DA1.2 ( can be omitted) . Resistor R2, you can adjust the gain op amp ( sensor sensitivity ) is calculated by the formula U out = U inp * ( 1 + R 1 / R 2 ).
The general scheme of digital ammeter skhema digital ampermetra In the scheme with voltage shunt R2 amplified by the operational amplifier lm358. The gain is adjusted trimmer RV1. Further amplified signal reaches the ADC leg adc0. On a regulated zener tl431 built reference voltage 5.12 volts. Getting the software part of the project. Source code is shown below

# include <mega8.h>
# include <delay.h>   
  
 // Alphanumeric LCD Module functions   
# asm   
   . equ __ lcd_port = 0x12; PORTD   
# endasm   
# include <lcd.h>   
     
# include <stdio.h>  // library, which contains the function sprintf   
# define ADC_VREF_TYPE 0x00   
  
 // Read the AD conversion result   
unsigned int read_adc (unsigned char adc_input)   
{  
ADMUX = adc_input | (ADC_VREF_TYPE & 0xff);   
 // Delay needed for the stabilization of the ADC input voltage   
delay_us ( 10 );   
 // Start the AD conversion   
ADCSRA | = 0x40;   
 // Wait for the AD conversion to complete   
while ((ADCSRA & 0x10) == 0 );   
ADCSRA | = 0x10;   
return ADCW;   
}   
  
void main (void)   
{  
char buffer [ 32] ;  // variable that will form the string for output to lcd   
int adc;  // variable to store the ADC   
int u;  // variable to store the voltage   
float a;  // variable to store the current   
  
PORTB = 0x00;   
DDRB = 0x00;   
  
 // Port C initialization   
PORTC = 0x00;   
DDRC = 0x00;   
  
 // Port D initialization   
PORTD = 0x00;   
DDRD = 0x00;   
  
 // Timer / Counter 0 initialization   
 // Clock source: System Clock   
 // Clock value: Timer 0 Stopped   
TCCR0 = 0x00;   
TCNT0 = 0x00;   
  
 // Timer / Counter 1 initialization   
 // Clock source: System Clock   
 // Clock value: Timer1 Stopped   
 // Mode: Normal top = FFFFh   
 // OC1A output: Discon.   
 // OC1B output: Discon.   
 // Noise Canceler: Off   
 // Input Capture on Falling Edge   
 // Timer1 Overflow Interrupt: Off   
 // Input Capture Interrupt: Off   
 // Compare A Match Interrupt: Off   
 // Compare B Match Interrupt: Off   
TCCR1A = 0x00;   
TCCR1B = 0x00;   
TCNT1H = 0x00;   
TCNT1L = 0x00;   
ICR1H = 0x00;   
ICR1L = 0x00;   
OCR1AH = 0x00;   
OCR1AL = 0x00;   
OCR1BH = 0x00;   
OCR1BL = 0x00;   
  
 // Timer / Counter 2 initialization   
 // Clock source: System Clock   
 // Clock value: Timer2 Stopped   
 // Mode: Normal top = FFh   
 // OC2 output: Disconnected   
ASSR = 0x00;   
TCCR2 = 0x00;   
TCNT2 = 0x00;   
OCR2 = 0x00;   
  
 // External Interrupt (s) initialization   
 // INT0: Off   
 // INT1: Off   
MCUCR = 0x00;   
  
 // Timer (s) / Counter (s) Interrupt (s) initialization   
TIMSK = 0x00;   
  
 // Analog Comparator initialization   
 // Analog Comparator: Off   
 // Analog Comparator Input Capture by Timer / Counter 1 : Off   
ACSR = 0x80;   
SFIOR = 0x00;   
  
 // ADC initialization   
 // ADC Clock frequency: 500,000 kHz   
 // ADC Voltage Reference: AREF pin   
ADMUX = ADC_VREF_TYPE & 0xff;   
ADCSRA = 0x81;   
  
 // LCD module initialization   
lcd_init ( 16 );   
  
while ( 1 )   
      {  
       adc = read_adc ( 0);  // Read the ADC port 0   
           /* The current flowing through the shunt is calculated by Ohm's law : I = U / R   
            R = 0,1 Ohm , a U ( voltage drop across the shunt ) we measure .   
            Since we ADC 10-bit , the maximum number that the function returns read_adc (),   
           will be equal to 1024, this number is equivalent to the input voltage adc0.   
           For example, if read_adc () returned 512 , it means that the input adc0 we gave half the reference voltage   
           To calculate the real power, we need to make a proportion :   
            reference voltage - 1024   
            desired voltage - adc   
            We reference voltage = 5.12   
            Seeking voltage = 5.12 * adc/1024 or Seeking voltage = 0,005 * adc   
            For simplicity translate Volts in millivolts by multiplying by 1000   
            Seeking voltage = 0,005 * adc * 1000   
            Everything is good here , but we did not take into account the gain op amp   
            calculated by the formula : Gain = 1 + R1/R2. Substituting , we obtain   
            Gain = (1 +4) = 5   
            The actual voltage = 0,005 * adc * 1000/5 just get adc   
            */   
            u = adc;   
           sprintf (buffer, "I =% d,% 02d A",   
           (int) (u/100), / * get current by Ohm's law I = U / R * /   
           (int) (u% 100)  // The fractional part of the current   
           );  // string to form the output   
           lcd_clear ();  // clear display before displaying   
           lcd_puts (buffer);  // display the formation of a string to the display   
           delay_ms ( 100);  // do delay   
      };   
}

Project Proteus and source code archive Ampermeter_P

The following article will describe how to make vatmetr simple to u

Комментарии - (5)

  • Илья говорит:
    Столкнулся с проблемой измерения силы тока при помощи МК, именно усилителя токового шунта, нашёл то что искал. Автору СПАСИБО.
  • Geha говорит:
    Есть приборы (расходомеры)с токовым выходом. И у меня есть идея собрать прибор миллиамперметр на AVR с расчетом и выводом на экран расхода в М3/ч или Т/ч. Как осуществить?
    • Admin говорит:
      Нужно смотреть что у вас на выходе расходометра, он цыфровой или аналоговый? если аналоговый, кидаете, выход на ножку ацп и измеряете показания, если цыфровой то разбираете протокол его работы. Но здается мне что ваш расходометр, просто изменяет частоту на выходе типа этого http://greenchip.com.ua/28-0-291-0.html , тогда меряете частоту каким то таймером.
  • unknown_ID говорит:
    Доброе время суток.Статья полезная,познавательно для начинающих,однако у вас в статье,точнее в комментариях в программном коде "закралась" ошибка.Да в учебниках так и пишут коэффициент усиления не инвертирующего операционного усилителя К=(1+R1/R2),однако в вашем случае К=(1+(R7+RV1)/R4),а ведь вашу статью используют ,как за основу курсового и не могут разобраться именно из-за этого. https://www.cyberforum.ru/avr/thread2442845.html

Добавить комментарий

Для отправки комментария вы должны авторизоваться.