| |||||||
|
Опубликовано 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)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |