Опубликовано 2013-05-03 15:02:21 автором Ruslan

Digital Power Meter


I immediately bought the other day bicycle motor-wheel . It has long dreamed of , and here it is, in all its glory !

motor wheel 500 w

The DC motor , valve , 48V , 500vat . The Chinese have promised an efficiency of about 85 % , which is not bad for such a moschnosti.K it was complete controller 800 watts, the throttle and brakes. The battery pack - 4 pieces , 12c , 9a/chasov and charger to them acquired separately .

I gathered all this stuff on my old mountain is great

elektrichesky velosiped

First impressions of the electric drive train just beyond words ! Maximum torque right from the start ( accelerate faster than 50cc scooter ) , the maximum speed of 45 km / h.

Break in this whole thing , I wanted to tie it to some kind of feature, that realties to indicate the cost of energy. Then he asked for a digital power meter.

In the previous article we learned how to measure the voltage voltage and current. To measure the power consumption should be multiplied by the current voltage : W = B * A. In fact, the power meter - is ammeter and voltmeter in a single device . Let us join the scheme ammeter and voltmeter as described in previous articles, and obtain the circuit power meter :

skhema power meter on mk

Power meter is built on the microcontroller atmega8, which is deserved status of people . Current, voltage and power output to the display Lcd- 16x2.

Resistors R8, R9 built a voltage divider with a division factor 11 , a voltage reference is made in a regulated and TL431 zener voltage is set to 5.12 volt.Tok is measured by measuring the voltage drop across the shunt R2, further shunt voltage is amplified by the operational amplifier Lm358 and the input of the ADC adc0.

The program is written CodeVisionAVR


# include <mega8.h>  
# include <delay.h>  
# include <stdio.h>  // library which contains the function sprintf  
 
 // Alphanumeric LCD Module functions  
# asm  
   . equ __ lcd_port = 0x12; PORTD  
# endasm  
# include <lcd.h>  
    
# 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 which will form the string for output to lcd  
unsigned long int u;  // variable to store the voltage in millivolts  
unsigned long int a;  // variable to store the current  
unsigned long int w;  // variable to store the values of power consumption  
PORTB = 0x00;  
DDRB = 0x00;  
 
 // Port C initialization  
PORTC = 0x00;  
DDRC = 0x00;  
 
 // Port D initialization  
PORTD = 0x00;  
DDRD = 0x00;  
 
 // Timer / Counter 0 initialization  
TCCR0 = 0x00;  
TCNT0 = 0x00;  
 
 // Timer / Counter 1 initialization  
TCCR1A = 0x00;  
TCCR1B = 0x00;  
TCNT1H = 0x00;  
TCNT1L = 0x00;  
ICR1H = 0x00;  
ICR1L = 0x00;  
OCR1AH = 0x00;  
OCR1AL = 0x00;  
OCR1BH = 0x00;  
OCR1BL = 0x00;  
 
 // Timer / Counter 2 initialization  
ASSR = 0x00;  
TCCR2 = 0x00;  
TCNT2 = 0x00;  
OCR2 = 0x00;  
 
 // External Interrupt (s) initialization  
MCUCR = 0x00;  
 
 // Timer (s) / Counter (s) Interrupt (s) initialization  
TIMSK = 0x00;  
 
 // Analog Comparator initialization  
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 )  
      { 
       a = read_adc ( 0 )  // read ADC value from port 0  
       u = read_adc ( 1 )  // read ADC value from port 1  
           /*  
                   1. Measure current
            The current flowing through the shunt , vichislyaetsya by Ohm's law : I = U / R  
            R = 0,1 Ohm , a U ( voltage drop across the shunt ) will be measured .  
            Since the ADC have a 10-bit , the maximum number that the function will return read_adc, ()  
            will be equal to 1024, this number is equivalent to the input voltage adc0.  
            For example, if read_adc () returned 512 then it means that the input adc0 E filed half a reference voltage  
            To calculate the actual stress , we need to make a proportion :  
            reference voltage - 1024  
            the desired voltage - a  
            We reference voltage = 5.12  
            The required voltage = 5.12 * a/1024, or Seeking voltage = 0,005 * a  
            For simplicity translate volts in millivolts by multiplying by 1000  
            The required voltage = 0,005 * a * 1000  
            Everything is good here , but we do not take into account the coefficient of op amp  
            calculated by the formula : Gain = 1 + R1/R2. Substituting , we get :  
            Gain = (1 + 4) = 5  
            The actual voltage = 0,005 * a * 1000/5 , we get just a  
                   2.  Measure voltage   
            Next measure the voltage across the resistor divider  
            We form a proportion , as described above, and we get :  
            The required voltage = 0,005 * u * 1000  
            We must also take into account the coefficient of the resistor voltage divider  
            We it is Kdel = (R1 + R2) / R2. Substituting , we get :  
            Kdel = (10 +1 ) / 1 = 11  
            The actual voltage = 0,005 * u * 1000 * 11  
            */  
               
            u = 55 * u;  // calculate the voltage in millivolts  
            a = a * 10  // calculate the current value according to Ohm's law : I = U / R = a/100 * 1000 = a * 10 miliamperah  
            w = a * u;  // calculate the power consumption  
           sprintf (buffer, "I =% u,% u U =% u,% u W =% u,% lu",  
                     a/1000,  // The whole honor current  
                     (a% 1000) / 10  // The fractional part of the current  
                     u/1000,  // integer part of voltage  
                     (u% 1000) / 10  // The fractional part of the voltage  
                     w/1000000,  // Integer part of the power  
                     (w% 1000000) / 10000  
                    )  // Form a line to output  
           lcd_clear ();  // clean the screen before displaying  
           lcd_puts (buffer);  // deduce the formation of the string to display  
           delay_ms ( 100),  // make the delay  
 
      };  
} 

Order to function sprintf could work with variables of type long int, required further customization. For CodeVision AVR: Project-> Configure-> C compiler-> (S) printf Features-> Select the item "long, width, precision".

The project is in the Proteus and the source code of the program in the archive Watmeter.rar

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

  • Виктор говорит:
    Скажите, а почему мигает индикатор? Я думал что мигает только в протеусе, собрал в железе, то же самое.. ((
  • AdminRu говорит:
    Здравствуйте. Мигает потому что частота обновления слишком маленькая, нужно увеличить частоту работы мк, до 4 мегагерц
    • Виктор говорит:
      А как сделать чтобы показания так не прыгали? Я пытаюсь измерять напругу от транса через диодный мост и кондеры. Но прыжки нереальные. Как устаканить контроллр?
      • AdminRu говорит:
        Добрий день. В каком диапазоне прыжки? попробуйте измерить напряжение какого нибудь постоянного источника например батарейки, сообщите результат.
  • nick говорит:
    если не секрет - а где купили моторколесо?
  • Максим говорит:
    Добрый день. Неплохо было бы добавить часы и считать емкость (ампер*час) чтобы видеть: во время зарядки(для этого надо мерять "отрицательный" ток) - насколько "живые" аккумуляторы; во время езды - видеть сколько еще заряда осталось... ну и по скорости вычислять на сколько метров(километров) еще хватит(но для этого надо приделать датчик холла или геркон на вилку и магнит на спицу)
    • AdminRu говорит:
      В мотор колесе уже есть аж три датчика хола, так что скорость и километраж вычислить не проблема

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

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