| |||||||
Опубликовано 2013-05-03 15:02:21 автором Ruslan Digital Power MeterI immediately bought the other day bicycle motor-wheel . It has long dreamed of , and here it is, in all its glory !
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
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 :
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 Комментарии - (10)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |