logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMEGA8][C] Ograniczenie prądowe

Faber33 14 Cze 2010 19:53 7741 77
  • #1 8190300
    Faber33
    Poziom 16  
    Witam. Mógłby mi ktoś doradzić na jakiej zasadzie działa wyświetlane aktualnie ustawionego ograniczenia prądowego w zasilaczu???...Chciałbym dopisać taką funkcje do takiego miernika

    [ATMEGA8][C] Ograniczenie prądowe

    Na jakiej zasadzie wyświetlanie ograniczenie prądowego działa...gdzie jest ono mierzone i jak miernik ma je zapamiętywać????

    Dodatkowo zamieszczam zawartość pliku main.c

    
    #define Uref 		2.65			// Napiecie referencyjne
    #define Rpom 		0.1			    // Rezystor pomiarowy
    #define R1			100000			// Dzielnik napieciowy - R1 100k ohm
    #define R2			7665			// Dzielnik napieciowy - R2 7k5  ohm
    #define Temp_wl		60				// Temp wlaczenia wiatraka
    #define Temp_wy		50				// Temp wylaczenia wiatraka
    #define Temp_max    80              // Temp wylaczenia przekaznika
    #define Temp_min    70              // Temp wlaczenia przekaznika
    
    #include <avr/io.h>
    //#include <math.h> 
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "naglowkowy.h"
     
    void lcd_U_I(void);
    void lcd_P_R(void);
    void lcd_T_FAN(void);
    void lcd_TON_TOFF(void); 
    
    char data0[8] = {0x0E, 0x11, 0x11, 0x11, 0x0A, 0x0A, 0x1B, 0x00}; //ohm		numer 0
    char data1[8] = {0x02, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; //stopien numer 1
    char data2[8] = {0x00, 0x04, 0x15, 0x0E, 0x15, 0x04, 0x00, 0x00}; // gwiazdka
    char x;
    
    	int i, ADC_H, ADC_L;
    	float prad, napiecie, temperatura;
    	long ADC_temp, ADC_temp_sr;
    	float Uin;
    	int napiecie_int , napiecie_float;
    	int prad_int , prad_float;
    	char menu = 0;
    	char setup;
    
    int main(void)
    {
    
    	Ust_Portow();
    	LCD_init();
    	ADC_init();
    
    	lcd_def_char(data0,0);
    	lcd_def_char(data1,1);
    	lcd_def_char(data2,2);
    
    	pierwsza();
    	write_char(0b00000010);
    	write_text("Zas.30V");
    		
    	druga();
    	write_text("3.15A");
    	write_char(0b00000010);	
    
    	Waitms(100);		
    	
    	PORTB|= _BV(PB1);
    	Waitms(500);	
    	
    	PORTB &= ~_BV(PB1);
    
    	czysc();
    	
    	while(1)
    	{
    
    		prad = 0;
    		napiecie = 0;
    		temperatura = 0;				
    		ADC_temp = 0;
    		ADC_temp_sr = 0;
    		Uin = 0;
    
       		// pomiar wartosci ADC0 - napiecie
       		for(i = 0 ; i < 20 ; i++)
    		{
    			ADCSRA|= _BV(ADSC); 			//start pojedynczej konwersji
       			while(bit_is_set(ADCSRA,ADSC)){};   
       			ADC_L = ADCL;
       			ADC_H = ADCH;
    			ADC_temp  = ADC_H*256+ADC_L;
    			ADC_temp_sr = ADC_temp_sr + ADC_temp;	
    			if(i==19)			
    			{
    				ADC_temp = ADC_temp_sr/20;
    				Uin = (Uref/1024)*ADC_temp;
    				napiecie = ((R1+R2)/R2)*Uin;
    				
    				napiecie_int = napiecie;
    				napiecie_float = (napiecie*100)-(napiecie_int*100);
    					
    			}
      		}
    
    		temperatura = 0;				
    		ADC_temp = 0;
    		ADC_temp_sr = 0;
    		Uin = 0;
    		//prad = 0;
    
       		// pomiar wartosci ADC1
       		ADMUX |= _BV(PC0); 			
       		for(i = 0 ; i < 20 ; i++)
    		{
    			ADCSRA|= _BV(ADSC); 			//start pojedynczej konwersji
       			while(bit_is_set(ADCSRA,ADSC)){};   
       			ADC_L = ADCL;
       			ADC_H = ADCH;
    			ADC_temp  = ADC_H*256+ADC_L;
    			ADC_temp_sr = ADC_temp_sr + ADC_temp;	
    			if(i==19)			
    			{
    				ADC_temp = ADC_temp_sr/20;
    				Uin = (Uref/1024)*ADC_temp;
    				prad = Uin/Rpom;
    				
    				prad_int = prad;
    				prad_float = (prad*1000)-(prad_int*1000);
    			}
      		}
    
    
    		temperatura = 0;				
    		ADC_temp = 0;
    		ADC_temp_sr = 0;
    		Uin = 0;
    
      		ADMUX &= ~_BV(PC0);
    
       		// pomiar wartosci ADC2
       		ADMUX |= _BV(PC1); 			
       		for(i = 0 ; i < 20 ; i++)
    		{
    			ADCSRA|= _BV(ADSC); 			//start pojedynczej konwersji
       			while(bit_is_set(ADCSRA,ADSC)){};   
       			ADC_L = ADCL;
       			ADC_H = ADCH;
    			ADC_temp  = ADC_H*256+ADC_L;
    			ADC_temp_sr = ADC_temp_sr + ADC_temp;	
    			if(i==19)			
    			{
    				ADC_temp = ADC_temp_sr/20;
    				Uin = (Uref/1024)*ADC_temp;
    				temperatura = Uin*90;
    			}
      		}
    		ADMUX &= ~_BV(PC1);
    
    		
    		if(temperatura >= Temp_wl)
    		{
    			PORTB|= _BV(PB1);
    		}
    
    		if(temperatura <= Temp_wy)
    		{
    			PORTB &= ~_BV(PB1);
    		}
    
            if(temperatura >= Temp_max)
    		{
    		    PORTD &= ~_BV(PD0);
            }
    
    		if(temperatura <= Temp_min)
    		{
    		   PORTD|= _BV(PD0);
            }
    				
    		if(bit_is_clear(PINB,PB2))
    		{
    			
    //		while(bit_is_clear(PINB,PB2)){}
    
    				Waitms(100);
    				menu=menu+1;
    				if(menu > 3)
    					{
    					menu=0;
    					}
    		}
    
    	
    		
    		if(menu==0) // prad napiecie
    			{
    			lcd_U_I();					
    			}
    
    		if(menu==1) /// moc rezystancja
    			{
    			lcd_P_R();		
    			}
    
    		if(menu==2) // temp fan
    			{
    			lcd_T_FAN();
    			}
    					
    		if(menu==3) // temp on off
    			{
    			lcd_TON_TOFF();
    			}
    		
    				
    	//	if(bit_is_set(PINB,PB1))
    	//	{
    	//	czysc();
    	//	write_text("Fan ON  ");
    	//	}
    
    	}
    	return 0;
    
    }
    
    void lcd_U_I(void)
    {
    				pierwsza(); 
    				write_text(" ");
    				write_data(napiecie_int);
    				write_text(".");
    				if(napiecie_float<10)
    				{
    				write_text("0");
    				}
    				write_data(napiecie_float);				
    				write_text("V  ");					
    
    				druga();
    
    				write_text(" ");
    				write_data(prad_int);
    				write_text(".");
    				if(prad_float<10)
    				{
    				write_text("0");
    				}
    				
    				if(prad_float<100)
    				{
    				write_text("0");
    				}		
    						
    				
    				
    				write_data(prad_float);				
    				write_text("A  ");
    }
    void lcd_P_R(void)
    {
    				pierwsza();
    				write_text(" ");
    				
    				if((napiecie*prad)<1)
    				{
    				write_data(napiecie*prad*1000);
    				write_text("mW     ");
    				}
    				else
    				{
    				write_data(napiecie*prad);
    				write_text("W     ");				
    				}
    				
    				
    				druga();
    				if(((napiecie/prad)>=1000000)||(napiecie==0)||(prad==0))
    					{
    					write_text("R > 1M");
    					write_char(0b00000000);
    					write_text("   ");
    					}
    				else
    					{
    				
    					write_text("  ");
    					write_data(napiecie/prad);
    					write_char(0b00000000);
    					write_text("      ");	
    					
    					}
    }
    void lcd_T_FAN(void)
    {
    				
    				
    				pierwsza();
    				write_text(" ");
    				write_data(temperatura);
    				
    				write_char(0b00000001);
    				write_text("C   ");			
    				
    				druga();
    				if(bit_is_set(PINB,PB1))
    				write_text("Fan ON  ");
    				if(bit_is_clear(PINB,PB1))	
    				write_text("Fan OFF  ");
    }
    void lcd_TON_TOFF(void)
    {
    		druga();
    		write_text(" ON ");					
    		write_data(Temp_wl);
    		write_char(0b00000001);		
    		write_text("C    ");		
    
    		pierwsza();	
    		write_text("OFF ");		
    		write_data(Temp_wy);
    		write_char(0b00000001);		
    		write_text("C    ");
    }
    
    


    Z góry dziękuje za pomoc :)
  • #2 8190374
    dominon
    Poziom 18  
    Napięcie jest mierzone po dzielniku napięciowym którego wartość jest dobierana według najwyższego napięcia jakie będzie mierzyć miernik. Potem po dzielniku jest ono porównywane do napięcia Vref na porcie przetwornika analogowo cyfrowego (ADC). Natężenie za to jest mierzone jako spadek napięcia na rezystorze 0.1Ohm z tego co widzę w komentarzu w kodzie.
  • #3 8190410
    Faber33
    Poziom 16  
    to rozumiem...tylko ograniczenie prądu ustawia się na zwarciu zasilacza...i jak zrobić aby było ono wyświetlane obok obecnego natężenia prądu gdy będzie podpięty po zasilacz jakiś układ :)????
  • #4 8193545
    PO.
    Poziom 20  
    To już musisz sobie dopisać do obsługi wyświetlacza i wrzucać na niego co chcesz. W ogóle sobie całą przepisz :) bo te procedury pierwsza/druga to żywcem z bascoma, jakby nie można było do konkretnego znaku skoczyć od razu ;) .

    PS: to była uwaga estetyczna z procedurami. Działa to działa ;) .
  • #5 8193658
    Faber33
    Poziom 16  
    kolega byzio zaprezentował kiedyś na elektrodzie zasilacz...w którym miernik był zbudowany na Attinie2313 i jeszcze dodatkowym układzie ADS7828 i tam znajduje się tam obok wartości aktualnego natężenia wartość ograniczenia prądowego...tyle że program do tego jest napisany w assemblerze...i nie potrafię z niego wyciągnąć części kodu która odpowiada za ograniczenie prądowe...a aktualnie nie mogę się do niego dopisać. Tutaj jest link do tego tematu:

    https://www.elektroda.pl/rtvforum/topic1560889-0.html

    Może by ktoś potrafił to napisać tylko że w języku C?????:)
  • #6 8193692
    PO.
    Poziom 20  
    Napisz co w ogóle działasz i jak chcesz tym sterować, i co jeszcze robić.
    W kodzie nie widzę w ogóle sterowania, tylko same pomiary i wyświetlanie. A jak masz sztukować kilka cudzych to lepiej zacząć z własnym od początku. Albo w całości czyjś gotowiec skopiować.
  • #7 8193699
    Faber33
    Poziom 16  
    właśnie tak wyszło że miernik zrobiłem inny a zasilacz by byzio :/ wrzucić całość tego programu????
  • #8 8193732
    PO.
    Poziom 20  
    I chcesz scalić jedno z drugim? A na jednym procesorze chociaż jest :) ?

    Wrzucaj, może ktoś Ci poprawi. Ja dziś raczej wymiękam. Czekaj, jak zrobiłeś to i pisałeś sam?
  • #9 8193754
    Faber33
    Poziom 16  
    mirnik pochodzi z innego tematu też z elektrody...ja tylko tam kilka rzeczy sobie dopisałem z biedą...jest na atmegdze8...pomiary sobie w miarę ustawiłem że pokazuje dokładnie...tylko w tym programie brakuje tego wyświetlania ograniczenia. Tutaj jest całość programu:
  • #10 8193821
    janbernat
    Poziom 38  
    Ogranicznik prądu ustawiasz przełącznikiem i ew. jakimś potencjometrem.
    Zwierasz wyjście zasilacza.
    Procesor mierzy i pokazuje jaki jest ten prąd- w zwykłej procedurze pomiaru prądu.
    Teraz można dopisać procedurę która ten prąd- czyli to ustawienie zapamięta i będzie wyświetlać jako trzeci parametr na wyświetlaczu.
    Oczywiście procesor musi "wiedzieć" że teraz jest to proces ustawiania ogranicznika prądu- czyli jakiś dodatkowy przycisk.
    Naciskasz- i ten prąd jest zapamiętany i się wyświetla.
    Cały ten pomysł nadaje się do "chrzanu tarcia"- bo jeśli nie naciśniesz przycisku "zapamiętaj" albo w trakcie pracy pokręcisz potencjometrem regulującym ogranicznik albo zmienisz zakres- to na wyświetlaczu będą nieprawdziwe dane.
    Oczywiście można to zrobić- przełączanie zakresów podaje sygnał na odpowiednie piny procesora-przełącznik dwusekcyjny- a do potencjometru dodajemy enkoder albo dajemy precyzyjny potencjometr podwójny i pośrednio odczytujemy jaki prąd ograniczający jest ustawiony.
    Jeśli ogranicznik prądowy ma "podciętą" charakterystykę- to zabawa nieco się komplikuje.
    Sporo zależy od układu zasilacza.
    No i ATmega8 nie ma wejść różnicowych do ADC- tak że te pomiary które już robi- są mocno przybliżone.
  • #11 8193886
    Faber33
    Poziom 16  
    janbernat a mógłbyś spróbować coś takiego napisać???:) a co do atmegi...to czy da się do niej podpiąć taki przetwornik jak ten ADS7828...on zwiększy dokładność pomiarów????

    A tak pozatym jaką komendę zastosować aby w jednej linii obok wyświetlała się w tym samym trybie np. rezystancja...bo obecnie połowa każdego z trybów jest nie wykorzystana...a chciałbym zmniejszyć ich ilość przez dodanie poszczególnych rzeczy które są wyświetlane obok tych z poprzedniego trybu... :)
  • #12 8194012
    janbernat
    Poziom 38  
    Jasne że mógłbym.
    Swój pierwszy program w C napisałem w zeszłym tygodniu.
    Całe 21 linijek.
    Tak że za parę miesięcy mógłbyś spodziewać się pierwszych wyników.
    P.S.
    Zastosowanie ADS- którego można ustawić w tryb różnicowy- zwiększy dokładność.
    Ale zastosowanie ATtiny26 zamiast ATMega8 należy rozważyć.
    A schemat by bynio jest tak strasznie narysowany że nie będę tego analizował.
    Narysuj własny- łącznie z tranzystorami wykonawczymi i podłączeniem potencjometrów.
  • #13 8194092
    Faber33
    Poziom 16  
    aha...spoko...mógłby się ktoś wypowiedzieć kto bardziej siedzi w temacie???? :)
  • #14 8194262
    landy13
    Poziom 31  
    Kolego Faber33. Od 13 lutego molestujesz forum problemami z tym zasilaczem. Założyłeś w związku z tym pięć albo sześć tematów. W każdym żądasz albo przerobienia, albo napisania od nowa, albo połączenia dwóch programów w jeden. Początkowo nie wiedziałeś nawet w jakim języku są napisane! Minęły cztery miesiące i już wiesz że to C. Zaiste kolosalny postęp. Żadnego wkładu własnego nie przedstawiłeś. A powinno Ci być wiadomo, że przynajmniej w tym dziale nie upoważnia to do otrzymania pomocy w postaci gotowca. Ci co "bardziej siedzą w temacie" zamiast mozolnie łączyć obce kody wolą napisać własny. Czego i Tobie życzę.
    PS Zmniejsz schemat, bo rozciąga stronę.
  • #15 8194370
    Faber33
    Poziom 16  
    Kolego landy13 dziękuje za przypomnienie...ale łaski nie robisz że zbędnie przy pijasz do mnie i moich postępów...w końcu ktoś odpowiedział i coś mi wyjaśnił :)...nie potrzebuje gotowca...tylko małą cześć programu...chyba to nie jest taki problem aby wyjaśnić na jakiej zasadzie to działa...

    PS nie jest tak łatwo znaleźć jakieś proste wyjaśnienie pisania programów do uC w jezyku C
  • #16 8194407
    janbernat
    Poziom 38  
    No to może tak:
    "w temacie" jak działa zasilacz, ogranicznik prądowy, regulacja napięcia, charakterystyka krzyżowa albo podcięta itp. to znam od jakichś 40 lat.
    "w temacie" jak działa mikroprocesor- no to może kilka lat- to jest zresztą najlepsze.
    "w temacie"- jak zaprogramować- to ze 2 lata- Bascom.
    A jak w C- to od tygodnia.
    No, uwzględniając ksiązki- to parę lat.
    I są ludzie którzy programują w C nie znając zasad działania procesorów i elektroniki- i jak patrzę na te programy- to zęby bolą.
    No i są ludzie- tacy jak ja- którzy nie znają składni i możliwości programowania w C.
    Każde "odkrycie" co ten język i kompilator potrafi- to jest czysta radość.
    No ale jest też ta trzecia grupa...
    "PS nie jest tak łatwo znaleźć jakieś proste wyjaśnienie pisania programów do uC w jezyku C."
    A pewnie- nie ma żadnej sensownej ksziążki- ale kto powiedział że życie ma być łatwe.
  • #17 8194509
    Faber33
    Poziom 16  
    z książkami to wiem...bo szukałem troche na necie...prędzej w jakiś krótkich notkach można coś znaleźć...ja dopiero zaczynam swoją przygodę z programowaniem...najciężej mi zrozumieć co z czym połączyć aby dało oczekiwany efekt...bo takie wytłumaczenie książkowe bez przykładów to mało mówi
  • #18 8239706
    Faber33
    Poziom 16  
    to może inaczej...mógłby ktoś powiedzieć jak zmienić sposób przeliczania ADC(H i L) aby wyliczało zamiast prądu....ograniczenie prądowe??? Dodam że : włączyłem między masę i AVCC potencjometr (druga sekcja potencjometru od ograniczenia prądowego) a napięcie z jego suwaka podałem na ADC3.

    jak teraz zmienić przeliczanie ADC(H i L) aby z tego wyliczało wartość ograniczenia???? :)
  • #19 8239779
    szelus
    Poziom 34  
    Jeżeli zamieścisz schemat części analogowej Twojego zasilacza, to się to da zrobić. Skąd mamy wiedzieć bez schematu, jak działa zabezpieczenie nadprądowe w Twoim zasilaczu?
    Schemat z tamtego wątku, do którego umieściłeś link jest niekompletny i dla mnie na tyle nieczytelny, że nie mam ochoty tracić czasu na "reverse engineering". Jeżeli udało Ci się z tego zbudować działający zasilacz, to wrzuć poprawiony schemat.

    Inna sprawa, że obciążanie wyjścia AVCC potencjometrem, z uwagi na jego wysoka impedancję, to może być kiepski pomysł - pomiary "popłyną".
    Ponieważ nie zależy Ci na jakiejś super dokładności w przypadku wskazań ograniczenia, to lepiej daj go przez odpowiednio dobrany rezystor do +5V.
  • #20 8239919
    Faber33
    Poziom 16  
    Kolega z innego forum doradził mi aby AVCC podłączyć do plusa przez dławik (tak jak pisze w nocie katalogowej do atmegi8) i ustawić AVCC jako napięcie referencyjne. Oprócz tego na regulacji prądu zastosować potencjometr stereo, jego drugą sekcję wpiąć między masę a AVCC a suwak podłączyć do wejścia pomiarowego atmegi8 - ADC3.

    PS. Schemat

    [ATMEGA8][C] Ograniczenie prądowe
  • #21 8239969
    szelus
    Poziom 34  
    Ups, sorry - miałem jakiś moment zaćmienia - czytałem i pisałem AVCC a docierało do mnie i miałem na myśli AREF. Do AVCC jest ok.
    Z narysowanymi podłączeniami zewnętrznymi już łatwiej się połapać. Podaj jeszcze parametry potencjometru regulacji prądu.
  • #22 8239980
    Faber33
    Poziom 16  
    Potencjometr od prądu 2 x 1 K
  • #23 8240024
    szelus
    Poziom 34  
    Zakładając, że potencjometr liniowy, wychodzi mi prawie (pomijając to 10 omów) liniowa zależność:

    Iogr = Uadc / 5V * Imax

    czyli

    IOGR = ADC * IMAX / 1024

    zakładając, że do tego pomiaru Aref masz ustawione na 5V i 10 bitową rozdzielczość. Imax/IMAX to maksymalna wartość prądu ograniczenia, jaką ustawiasz sobie tą PR-ką.
  • #24 8240055
    Faber33
    Poziom 16  
    Skopiowałem część kodu która odpowiada za pomiar prądu:
    
     // pomiar wartosci ADC3
               ADMUX |= _BV(PC2);           
               for(i = 0 ; i < 20 ; i++)
            {
                ADCSRA|= _BV(ADSC);             //start pojedynczej konwersji
                   while(bit_is_set(ADCSRA,ADSC)){};   
                   ADC_L = ADCL;
                   ADC_H = ADCH;
                ADC_temp  = ADC_H*256+ADC_L;
                ADC_temp_sr = ADC_temp_sr + ADC_temp;   
                if(i==19)           
                {
                    ADC_temp = ADC_temp_sr/20;
                    Uin = (Uref/1024)*ADC_temp;
                    prad = Uin/Rpom;
                   
                    prad_int = prad;
                    prad_float = (prad*1000)-(prad_int*1000);
                }
              } 


    zmieniłem tylko na odczyt z ADC3. Czy kolega mógłby to zmienić w tej części kodu????:)
  • #25 8240138
    szelus
    Poziom 34  
    Teraz spojrzałem do góry i widzę, że u Ciebie jest zawsze używane wewnętrzne źródło napięcia odniesienia. Jeżeli tego nie będziesz przełączał, to musisz podłączyć potencjometr do plusa przez rezystor - wychodzi mi z obliczeń 890 omów przy założeniu AVCC=5.0V. Masz stabilizowane?
    Wtedy:
    
                    ADC_temp = ADC_temp_sr/20;
                    prad_ogr = (Imax/1024)*ADC_temp;
    
  • #26 8240167
    Faber33
    Poziom 16  
    zmieniłem ADMUX tak ( AVCC z zewnętrznym kondensatorem na wyprowadzeniu AREF ) wtedy Uref= AVCC
  • #27 8240174
    szelus
    Poziom 34  
    No to ok, wtedy bez rezystora i dokładność lepsza. Wzór, który podałem wyżej, bez zmian.
  • #28 8243170
    Faber33
    Poziom 16  
    Nie wiem za które linie wstawić ten kod
    czy tu???:
    ADC_temp = ADC_temp_sr/20;
    Uin = (Uref/1024)*ADC_temp; 

    Czy to co jest poniżej tego to bez zmian???

    a jak wynik tego pomiaru wyświetlić na wyświetlaczu? Bo tam pod tą częścią jeszcze dwie linijki są a z tego co widzą to według jednej z nich wyświetla to na LCD
  • #29 8243203
    szelus
    Poziom 34  
    Miejsce dobre. A z wyświetlaniem to zależy, jak chcesz to wyświetlać na LCD. Program z początku nie przewiduje, więc nie wiem, co chcesz zrobić. Dołożyć kolejną pozycję w menu?
    Jeżeli tak, to dopisz sobie kolejny wariant funkcji wyświetlającej, w rodzaju lcd_LIMIT(), dołóż zmienne np. ograniczenie i ograniczenie_float i kolejny numerek do menu.
    Przeanalizuj sobie, jak działa ten program - naprawdę nie jest skomplikowany.
  • #30 8243342
    Faber33
    Poziom 16  
    Chciałbym żeby ograniczenie było wyświetlane równocześnie z aktualnym prądem w tej samej linii

    [ATMEGA8][C] Ograniczenie prądowe
REKLAMA