Опубликовано 2013-04-11 11:24:04 автором Ruslan Контролер вітрогенератора Після виготовлення вітряка , постало питання про контроллер заряду акб.Задача:
- Контролер повинен виводити значення струму і напруги на lcd дисплей
- Показувати потужність, яку виробляє Вітрогенератор в конкретний момент часу, рахувати кількість вироблених кіловат/годин
- Регулювати зарядку АКБ, не даючи напрузі піднятися більше, ніж 14.2 вольта і току - більше 1/10 ємності АКБ
- Всю зайву енергію, яку виробляє вітряк, контролер скидає на баласт (ним може бути який-небудь тен вольт на 12, кіловат на 2-3)
Важливо: Баласт потрібно підібрати так, щоб при зарядженої АКБ контролер міг завантажити вітряк, інакше той піде в рознос, і вам доведеться лопасті збирати по сусідах.
Контролер був виготовлений на мікроконтролері avr atmega8
Внутрішній вигляд контролера Схема контролера Програма написана на c в CVAVR # include
# include
/ / Alphanumeric LCD Module functions
# asm
.equ __ lcd_port = 0x12; PORTD
# endasm
# include
# include / / бібліотека в якій лежит функція sprintf
int Af = 4000, Uf = 14200;
unsigned long int u; / / змінна для зберігання напруги в мілівольтах
unsigned long int a; / / змінна для зберігання струму
unsigned long int w; / / змінна для зберігання значень споживаної потужності
void incSkvag ()
{
if ( OCR1AL!= 0) OCR1AL-;
}
void decSkvag ()
{
if ( OCR1AL!= 255 ) OCR1AL++;
}
# 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;
}
interrupt [ TIM0_OVF ] void timer0_ovf_isr ( void )
{
TCNT0 = 0x64;
a = read_adc (3); / / читаємо значення АЦП з порту 0
u = read_adc (5); / / читаємо значення АЦП з порту 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
- Вимірюємо напругу
Далі вимірюємо напруга на резисторного дільнику
Сформовані пропорції як описано вище і отримаємо
Шукане напруги = 0,005 * u * 1000
Треба ще врахувати коефіціент резисторного дільника напруги
в нас він дорівнює Кдел = (R1 + R2) / R2 підставивши отримаємо
Кдел = (10 +1 ) / 1 = 11
Рельной напруги = 0,005 * u * 1000 * 11
* /
u = 55 * u +400; / / обчислюємо значення напруги в мілівольтах
a = a * 10; / / вичесляем значення струму за законом ома I = U / R = a/100 * 1000 = a * 10 , в міліамперах
w = a * u; / / вичесляем споживану потужність
/ / регулювання напруги та струму
if ( ( a > Af ) | | ( a > 8000) ) / / регулювання по струму
{
incSkvag ();
}
else
{
if ( u > Uf ) / / регулювання по напрузі
{
incSkvag ();
}
else
{
decSkvag ();
}
}
}
void main ( void )
{
/ / Declare local variables here
unsigned char i = 2 , k [ 3] [ 32] ;
sprintf ( k [0 ] , " Setup A = % i " , Af ) ;
sprintf ( k [ 1] , " Setup U = % i " , Uf ) ;
/ / Input / Output Ports initialization
PORTB = 0b00011100 ;
DDRB = 0b00000010 ;
/ / Port C initialization
PORTC = 0x00;
DDRC = 0x00;
/ / Port D initialization
PORTD = 0x00;
DDRD = 0x00;
/ / Timer / Counter 0 initialization
/ / Clock source : System Clock
/ / Clock value : 0,977 kHz
TCCR0 = 0x03 ;
TCNT0 = 0x00;
/ / Timer / Counter 1 initialization
/ / Clock source : System Clock
/ / Clock value : 15,625 kHz
/ / Mode: Fast PWM top = 0x00FF
/ / OC1A output : Inverted
/ / 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 = 0xC1 ;
TCCR1B = 0x0B ;
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
OCR1AH = 0x00;
OCR1AL = 0xff ;
OCR1BH = 0x00;
OCR1BL = 0x00;
/ / Timer / Counter 2 initialization
/ / Clock source : System Clock
/ / Clock value : Timer2 Stopped
/ / Mode: Normal top = 0xFF
/ / 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 = 0x01;
/ / USART initialization
/ / USART disabled
UCSRB = 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 ;
/ / SPI initialization
/ / SPI disabled
SPCR = 0x00;
/ / TWI initialization
/ / TWI disabled
TWCR = 0x00;
/ / Alphanumeric LCD initialization
lcd_init ( 16 ) ;
/ / Global enable interrupts
# asm ( " sei " )
while ( 1)
{
sprintf ( k [ 2] , "I = % u , % uA U = % u , % uV \ nW = % u , % lu K = % i " ,
a/1000 , / / Ціла честь струму
( a % 1000 ) / 100 , / / Дрібна частина струму
u/1000 , / / Ціла частина напруги
( u % 1000 ) / 100 , / / Дрібна частина напруги
w/1000000 , / / Ціла частина потужності
( w % 1000000) / 100000 , / / Дрібна частина потужності
OCR1AL
) ; / / Формуємо рядок для виведення
/ / ------------------------------------------------ ---------------
/ / робота з кнопками
if ( PINB.2 == 0)
{
/ / перемикаємо меню
if ( + + i > 2 ) i = 0 ;
}
if ( PINB.3 == 0) / / перевіряємо чи натиснута кнопка плюс
{
if ( i == 0 ) { Af = Af +10 ; sprintf ( k [ i ] , " Setup A = % i ma " , Af ) ;}
if ( i == 1) { Uf = Uf +10 ; sprintf ( k [ i ] , " Setup U = % i mv " , Uf ) ;}
}
if ( PINB.4 == 0) / / перевіряємо чи натиснута кнопка мінус
{
if ( i == 0 ) { Af = Af -10; sprintf ( k [ i ] , " Setup A = % i ma " , Af ) ;}
if ( i == 1) { Uf = Uf -10; sprintf ( k [ i ] , " Setup U = % i mv " , Uf ) ;}
}
lcd_clear (); / / чистимо дисплей перед виведенням
lcd_puts ( k [ i ] ) ; / / виводимо сформованості рядок на дисплей
delay_ms (100); / / робимо затримку
} ;
}
Для повторення нам знадобиться:
Радіодеталь | Модель | Кількість |
Основна характеристика | Магазин |
Микроконтроллер | Atmega8 | 1 |
| Купити |
lcd | 16x2 | 1 |
знакосінтезірующіх | Купити |
Транзистор | польовий | 1 |
N-канальний | Купити |
Резистор | | 1 |
10 ком | Купити |
Резистор | | 1 |
0.1 Ом | Купити |
Резистор | | 1 |
100 Ом | Купити |
Операційний підсилювач | TL074CN або lm358 | 1 |
| Купити Купити |
Діод Шотткі | 10CTQ150PBF | 1 |
| Купити |
Принцип дії . Контролер у динамічному режимі перевіряє струм і напруга заряду батареї. Коли батарея розряджена , її опір мало , і тому при зарядці через неї може піти великий струм ( більше 1/10 ємності). Тому в початковому циклі зарядки батереї контролер стежить , щоб струм не перевищував 1/10 ємності батареі.По міру зарядки опір батереї увеличиватся , струм зменшується і починає зростати напруга на акб . Контролер стежить , щоб напруга не перевищувало 14.2 ст. Якщо струм або напруга перевищують встановлені норми , то шпаруватість ШІМ- сигналу на ніжці PB1 росте і зайва енергія скидається на баласт. Генератор виробляє трифазне змінну напругу , а нам для зарядки батареї треба постійна напруга . Для випрямлення використовується міст , зібраний за схемою трифазного випрямляча Ларіонова на трьох діодних напівміст ( на 6 діодах )
Для того , щоб схема управління працювала від генератора , коли є вітер і даремно нерозряджаються акумуляторну батарею , я в міст додав ще три діода , і таким чином розв'язав два плюси харчування.
Від одного плюса запитивается баласт і система управління , від іншого заряджається акб , таким чином енергія з акб не може потрапити на баласт і система управління працює безпосередньо від вітряка . Схема підключення контролера
До Входу трифазного моста підключаємо наш генератор , якщо генератор постійного струму то підключаємо до двох будь-яким виводам.По замовчуванням контролер налаштований на струм 4 ампера і напріженіе 14,2 вольта , якщо вам потрібні інші величини їх можна встановити кнопками установки напруги і тока.На РКІ екран виводиться струм і напріженія зярядкі акб , потужність яка йде у акб і шпаруватість шим сигналу ( 0 - максимальна шпаруватість 255- мінімальна шпаруватість ) . Схема в Proteus і програма для мікроконтролера знаходяться в архіві Wind Controller.rar Комментарии - (9) as9 говорит: Здравствуйте. Собираю ваш контроллер, есть пара вопросов.
1. У вас максимальный ток - котрорый может измерить микроконтроллер 10 ампер (судя про протеусу), что нужно сделать чтобы при входе в мк 5вольт с операционника максимальный ток был 25А где подправить программку. Шунт и резисторы коэффициента усиления я конечно переделаю.
2. Во втором пункте в вашей программе напряжение расчитывается по формуле
u=55*u+400. Мне не понятно что это за +400, откуда это взялось.
3. На какую частоту нужен кварц.
Спасибо за помощь as9 говорит: Во всем разобрался, спасибо вам за схему и прошивку, остался один вопрос, контроллер не сохраняет настройки при сбросе питания Admin говорит: Настройки не сохраняет. Нужно сохранять настройки в переменные eeeprom, а при запуске проверять если в них чтото сохранено грузим настройки с eeeprom переменных, иначе ставим настройки по умолчанию.
Imtoo3gpvc говорит: А почему схема представленная а скришоте и та что во вложенном файле отличаются и перечень элементов не полный
sanya говорит: добрый вечер) вы нашли достоверный проект?
sanya говорит: ответьте пожалуйста))) скачал я файл а ето не контроллер а ваттметр не могли б вы помочь с достоверными файлами етой статьи?) спасибо заранее))) Admin говорит: Разберитесь, там все верно, еще текст программы есть в статье
Vit1963 говорит: Как выставить фюзы в AVRDUDE
Добавить комментарийДля отправки комментария вы должны авторизоваться.
|