Опубликовано 2013-04-11 11:24:04 автором Ruslan

Контроллер ветрогенератора


После изготовления ветряка, встал вопрос о контроллере заряда акб.Задача:
  • Контроллер должен выводить значения тока и напряжения на lcd дисплей
  • Показывать мощность, которую вырабатывает Ветрогенератор в конкретный момент времени, считать количество выработанных киловатт/часов
  • Регулировать зарядку АКБ, не давая напряжению подняться больше, чем 14.2 вольта и току - больше 1/10 емкости АКБ
  • Всю лишнюю энергию, которую вырабатывает ветряк, контроллер скидывает на балласт (им может быть какой-нибудь тен вольт на 12, киловатт на 2-3) Важно: Баласт нужно подобрать так, чтобы при заряженной АКБ контроллер мог загрузить ветряк, иначе тот уйдет в разнос, и вам придется лопасти собирать по соседям.
Контроллер был изготовлен на микроконтроллере avr atmega8
Внутрености контроллераконтроллер ветрогенератора изнутриСхема контроллера схема контроллера ветрогенератора

Программа написана на c в CVAVR

#include <mega8.h> 
#include <delay.h> 
 
// Alphanumeric LCD Module functions 
#asm 
   .equ __lcd_port=0x12 ;PORTD 
#endasm 
#include <lcd.h> 
#include <stdio.h> //библиотека в которой лежыт функция 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      
    /* 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+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

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

  • as9 говорит:
    Здравствуйте. Собираю ваш контроллер, есть пара вопросов. 1. У вас максимальный ток - котрорый может измерить микроконтроллер 10 ампер (судя про протеусу), что нужно сделать чтобы при входе в мк 5вольт с операционника максимальный ток был 25А где подправить программку. Шунт и резисторы коэффициента усиления я конечно переделаю. 2. Во втором пункте в вашей программе напряжение расчитывается по формуле u=55*u+400. Мне не понятно что это за +400, откуда это взялось. 3. На какую частоту нужен кварц. Спасибо за помощь
  • as9 говорит:
    Во всем разобрался, спасибо вам за схему и прошивку, остался один вопрос, контроллер не сохраняет настройки при сбросе питания
    • AdminRu говорит:
      Настройки не сохраняет. Нужно сохранять настройки в переменные eeeprom, а при запуске проверять если в них чтото сохранено грузим настройки с eeeprom переменных, иначе ставим настройки по умолчанию.
  • Imtoo3gpvc говорит:
    А почему схема представленная а скришоте и та что во вложенном файле отличаются и перечень элементов не полный
  • sanya говорит:
    ответьте пожалуйста))) скачал я файл а ето не контроллер а ваттметр не могли б вы помочь с достоверными файлами етой статьи?) спасибо заранее)))

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

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