|
| |||||||
|
Опубликовано 2013-05-03 15:02:21 автором Ruslan Цифровий ВатметрКупив я тут днями велосипедне мотор- колесо. Давно мріяв, і ось воно, у всій красі!
Мотор постійного струму, вентильний, 48в, 500ват. Китайці обіцяють ККД близько 85%, що вже непогано для такої мощності. До нього в комплекті йшов контролер 800 ват, ручки газу і гальма. Блок акумуляторів - 4шт, 12в, 9а/часов і зарядний пристрій до них купував окремо. Зібрав я все це добро на свій старий гірський велик
Перші враження від електротяги просто не передати словами! Крутний момент максимальний з самого старту ( розганяється швидше 50- кубового скутера), максималка 45 км/год. Обкатавши все це добро, мені захотілося прикрутити до нього якусь фічу, що - небуть для індикації витрат енергії. Тут сам собою напросився цифровий ватметр. У попередніх статях ми навчилися міряти напругу і струм . Для того, щоб виміряти споживану потужність, потрібно напругу помножити на струм: ВТ = В * А. По суті, ватметр - це амперметр і вольтметр в єдиному пристрої. Давайте об'єднаємо схеми амперметра і вольтметра , описані в попередніх статтях, і отримаємо схему ваттметра:
Ватметр побудований на мікроконтролері atmega8 , який заслужено займає статус народного. Струм, напруга і потужність виводяться на Lcd -дисплей 16x2. На резисторах R8, R9 побудований дільник напруги з коефіцієнтом ділення 11, джерело опорної напруги виконаний на регульованому стабілітроні TL431 і налаштований на напруги 5.12 вольт.Ток вимірюється шляхом вимірювання падіння напруги на шунті R2, далі це падіння напруги посилюється операційним підсилювачем Lm358 і надходить на вхід АЦП adc0.
Програма написана на CodeVisionAVR
# include <mega8.h>
# include <delay.h>
# include <stdio.h> // бібліотека в якій лежить функція 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] ; // змінна в якій буде формуватися рядок для виведення на lcd
unsigned long int u ; // змінна для зберігання напруги в мілівольтах
unsigned long int a ; // змінна для зберігання струму
unsigned long int w ; // змінна для зберігання значень споживаної потужності
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); // читаємо значення АЦП з порту 0
u = read_adc ( 1); // читаємо значення АЦП з порту 1
/*
1. Вимірюємо струм
Струм, що протікає через шунт , вічісляется за законом Ома : I = U / R
R = 0,1 ом , a U (падіння напруги на шунт ) ми будемо вимірювати .
Так як АЦП у нас 10 - бітний , то максимальне число , яке поверне функція read_adc , ()
дорівнюватиме 1024 , це число буде еквівалентом напруги на вході adc0 .
Наприклад , якщо read_adc ( ) повернув 512 то це означає , що на вхід adc0 ми подали половину опорного напруги
Щоб обчислити реальна напруга , нам потрібно скласти пропорцію:
опорна напруга - 1024
шукане напруга - a
У нас опорна напруга = 5.12
Шукане напруга = 5.12 * a/1024 , або Искомое напруга = 0,005 * a
для простоти переведемо вольти в мілівольтах , Домножимо на 1000
Шукане напруга = 0,005 * a * 1000
Тут все добре , але ми не врахували коеффициент посилення ЗУ
розраховується за формулою: Кус = 1 + R1/R2 . Підставивши , одержимо:
Кус = (1 +4) = 5
Реальне напруга = 0,005 * a * 1000 /5 , отримуємо просто a
2. Вимірюємо напругу
Далі вимірюємо напруга на резисторного дільнику
Складемо пропорцію , як описано вище , і отримаємо :
Шукане напруга = 0,005 * u * 1000
Треба ще врахувати коеффициент резисторного дільника напруги
у нас він дорівнює Кдел = (R1 + R2) / R2. Підставивши , одержимо:
Кдел = (10 +1 ) / 1 = 11
Реальне напруга = 0,005 * u * 1000 * 11
*/
u = 55 * u ; // обчислюємо значення напруги в мілівольтах
a = a * 10 ; // обчислюємо значення струму за законом Ома : I = U / R = a/100 * 1000 = a * 10 в міліамперах
w = a * u ; // обчислюємо споживану потужність
sprintf ( buffer , "I = % u , % u U = % u , % u W = % u , % lu " ,
a/1000 , // Ціла честь струму
( a % 1000 ) / 10 , // Дрібна частина струму
u/1000 , // Ціла частина напруги
( u % 1000 ) / 10 , // Дрібна частина напруги
w/1000000 , // Ціла частина потужності
( w % 1000000) / 10000
) ; // Формуємо рядок для виведення
lcd_clear (); // чистимо дисплей перед виведенням
lcd_puts ( buffer ) ; // виводимо сформованості рядок на дисплей
delay_ms (100); // робимо затримку
} ;
}
Для того , щоб функція sprintf могла працювати зі змінними типу long int , необхідно провести додаткові налаштування. Для CodeVision AVR : Project - > Configure -> C compiler -> ( S ) printf Features - > Вибрати пункт " long , width , precision " . Проект у Протеус і вихідний код програми в архіві Watmeter.rar Комментарии - (10)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||