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

[atmega32][C]System zarzadzania i monitorowania

margas4542 04 Lip 2011 10:53 4158 23
  • #1 9680069
    margas4542
    Poziom 16  
    Jestem elektronikiem i choć od prawie roku (z przerwami ) powoli zagłębiam się w temat programowania na własne potrzeby AVR-ów nadal nie potrafię zastosować wielu pożytecznych funkcji co powoduje że napisanie programu do zarządzania i monitorowania napięć i prądów w układzie zasilacz,akumulator 12V,oświetlenie LED oraz sterowanie przez nastawny dwukanałowy zegar czterech obwodów 230V sprawia mi dużo kłopotów natury funkcjonalnej i programowej.
    Chciałby prosić kolegów o prostą analizę kodu i dotyczące jego uwagi lub przykłady jak zmodyfikować ten program.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #2 9681412
    cadavre
    Poziom 10  
    Pierwszą dobrą wskazówką byłby podział kodu na elementy składowe - stworzenie paru inkludowanych plików zawierających posortowane funkcje (już chciałem napisać "metody" ; p). Krótko - rozbicie kody na pliki .c i .h.

    Ciężko przeanalizować tyle kodu na raz.
  • #4 9681881
    tomekgl
    Poziom 16  
    Podobnie jak wyżej, proponowałbym porozdzielać program na bloki funkcjonalne, przeanalizowanie jednej dużej pętli głównej może sprawiać problemy nawet autorowi w trakcie pisania kodu.
    Moje propozycje poniżej.
    1) Obsługa "interfejsu użytkownika" realizowana jest w jednym szeregu z obsługą głównej funkcjonalności. Biorąc pod uwagę, że cała obsługa magistrali TWI oparta jest na oczekiwaniu na zmianę flagi (wszechobecne while ( ! ...)), jakiś problem z odczytem/peryferiami może spowodować zawieszenie programu. Przy dużej liczbie długotrwałych operacji I/O może to odbić się też na opóźnieniach widocznych dla użytkownika.
    1.5)OIDP ATMega32 ma sprzętową obsługę TWI z przerwaniami, możnaby to wykorzystać.
    2)Poza tym, wszystkie komunikaty, które deklarujesz trzymane są w RAMie. Proponuję przerzucić je do FLASHa (w gcc istnieje dyrektywa __attribute__ ((progmem)) ).
  • #5 9682241
    janbernat
    Poziom 38  
    No to skoro już taką kobyłę spłodziłeś to rozbij to na kawałki czyli- od tyłu.
    Nie jest to dobra metoda- ale jakoś Cię trzeba odzwyczaić od takich konstrukcji.
    W lewym okienku AVRStudio utwórz dwa nowe pliki- np. TWI.h i TWI.c
    W Header Files prawym klawiszem myszki create new header file.
    W source files- prawy klawisz i utwórz new source file.
    Nazwy takie jak wyżej albo jakie chcesz.
    Te pliki na początek mogą być puste.
    A na początku main dopisz #include "TWI.h"
    Skompiluj i pomyślimy co dalej.
    A książkę Mirka przeczytałeś nieuważnie.
  • #6 9716554
    gayetan
    Poziom 18  
    z takich praktycznych-kosmetycznych porad to np. warto trzymać się jednego sposobu zapisu bitowego:
    (1<<x) to to samo co _BV(x) - tyle samo znaków a 'szybciej działa' - nie potrzeba wykorzystywać makra i istnieją uzasadnione przesłanki, że w kolejnych wersjach C - _BV będzie 'obsolete'.
    ..ale może się czepiam..
  • #7 9728117
    margas4542
    Poziom 16  
    Nie było mnie trochę czasu dlatego dopiero dzisiaj odpisuje. Jest faktem że można rozbić ten program na mniejsze pliki zawierające bloki funkcjonalne ale już próbowałem tak robić i pogubiłem się. Całość łatwiej mi przeglądać i modyfikować. Projekt może zbyt duży jak na moją wiedzę co przekłada się na korzystanie z prostych funkcji bo z zastosowaniem tych bardziej zaawansowanych idzie opornie bo nie ma mi kto wytłumaczyć jak to zrobić a książka niestety niemowa. Była prośba o schemat mojego urządzenia co czynie dokładając wykonany obwód drukowany.

    [atmega32][C]System zarzadzania i monitorowania

    [atmega32][C]System zarzadzania i monitorowania[/img]
  • #10 9729408
    margas4542
    Poziom 16  
    Co do książki to mam niedawno zakupione wydanie Mirosława Kardasia .... a co do porad to za każda jestem wdzięczny tylko z praktycznym zastosowaniem bywa różnie..
  • #11 9729578
    sulfur
    Poziom 24  
    margas4542 napisał:
    Chciałby prosić kolegów o prostą analizę kodu i dotyczące jego uwagi lub przykłady jak zmodyfikować ten program.
    Nie wiemy, co chciałbym autor zmodyfikować, w jakim stopniu lub co poprzez modyfikację osiągnąć. Pomoc na tak zadane problemy jest praktycznie niemożliwa. Polecam ściślej określić problem z układem lub programem, będzie łatwiej. Wszystkim.
  • #12 9730226
    margas4542
    Poziom 16  
    Witam. Mam instalację niskonapięciową 12V do której poprzez wyłączniki podłączam zestawy diod LED służące do oświetlenia kuchni, pokoju, przedpokoju i łazienki. Oświetlenie podstawowe oparte jest na normalnych żarówkach energooszczędnych załączanych poprzez moduły na optotriakach. W obwodzie zasilania 12V są dwa zasilacze 10A i ogniwo fotogalwaniczne (jeszcze go nie mam) przyłączane do modułu stabilizatora-ładowaki z akumulatorem.
    Zadania pisanego programu;
    -podstawowy zegar czasu rzeczywistego.
    -pomiar napięcia ogniwa fotogalwanicznego i dołaczanie go do modułu gdy napięcie osiągnie 14V odłączając jeżeli aktywny któryś z zasilaczy.
    -pomiar napięcia akumulatora i załączenie zasilacza z1 lub z2 oby go naładować jeżeli nie jest aktywny obwód ogniwa foto
    (w przypadku braku fazy na z1 załączany jest z2)
    -pomiar prądu wejściowego oraz prądu pobieranego przez obciążenie (LED)
    -zegar sterujący umożliwiający ustawienie czasu zał/wył czterech obwodów gniazdek 230V o określonej godzinie z rozróżnieniem dnia tygodnia.
    Pierwsze cztery punkty zostały zrealizowane ale po wyłączeniu zasilania i ponownym włączeniu nieprawidłowo jest odczytywana data.
    Moim problemem jest zegar sterujący. Ustawiam i zapisuje czas do PCF-a i odczytuje go ale nie potrafię napisać funkcji porównującej go z aktualnym czasem oraz umożliwiającej zmianę trybu ze sterowania automatycznego na sterowanie manualne czterema klawiszami umieszczonymi obok LCD.
  • #13 9733231
    sulfur
    Poziom 24  
    margas4542 napisał:
    LCD_GoTo(20,0); LCD_WriteText(dzien[t_dzien]);

    A to w ogóle działa ?
    margas4542 napisał:
    dzien=(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;//wyliczenie numeru dnia tygodnia
    To jest duża przesada. Operator dodawania i przypisania w operatorze trójargumentowym to proszenie się o kłopoty. Innymi słowy zbędna błyskotliwość.

    Co do porównywania czasów to zależy od pewnych założeń. Sugerując się kodem przyjmuję, że tydzień podzielono na dni robocze pon-pt oraz dni wolne sob-nd. Sprawdzamy wtedy czy zmienna dzien wskazana zresztą wyżej jest większa od 5 (wtedy mamy dni wolne), w przeciwnym wypadku robocze.Jeśli chodzi o sam czas, ja bym zrobił tak, że trzymałbym czas(y) załączenia i wyłączenia w tablicy struktury w kolejności posortowanej od najwcześniej do najpóźniej. Wtedy mamy jeden warunek i ewentualne wykonanie akcji po czym przejście do następnej pozycji, jeśli istnieje. Struktura musiałaby przechowywać czas i rodzaj akcji, jaką należy wykonać. Jeśli konieczne byłoby rozbicie tygodnia na realne 7 dni, użyłbym zamiast jednego warunku tablicy wskaźników na funkcje, a dalej to samo.

    Z odczytem zegara nie pomogę. Nie mam doświadczenia.

    Zmianom ze sterowania automatycznego na ręczne przyjrzę się jutro, jeśli nikt mnie nie uprzedzi. Dzisiaj już mam dosyć.

    P.S. bieżąco
  • #14 9734876
    margas4542
    Poziom 16  
    Ta linijka kodu wyliczającego dnień tygodnia nie jet mojego autorstwa a zaczerpnięta chyba z Wikipedii bo moje próby napisania podobnej definicji utknęły na dobre ale ta funkcja działa. Ten zegar sterujący pisałem już kilka razy zmieniając diametralnie strukturę kodu ale to ciągle nie działa możliwe że z powodu błędnie przyjętej koncepcji działania ale nie potrafię wymyślić innej..
  • #15 9736367
    sulfur
    Poziom 24  
    Nie czyta kolega uważnie. Ten zapis dzien[t_dzien] jest zły i prawdopodobnie autor miał na myśli t_dzien[dzien]. No ale w zasadzie to jest szczegół.

    Co do tego zegara. Rozumiem, że zasilanie jest podtrzymywane przez baterię. Czy zły czas jest odczytywany tylko przy pierwszym odczycie, czy po uruchomieniu mikrokontrolera do ponownego ustawienia poprawnej daty i godziny odczyt jest błędny cały czas ? Czy błędny odczyt zmienia się prawidłowo w czasie ?
  • #16 9754681
    margas4542
    Poziom 16  
    PCF8583 ma własne zasilanie [akumulatorek] do podtrzymania pamięci , błędny odczyt następuje po zmianie wartości dni np; 19-07-2011 na 20-27-2011 .. 20-47-2011 . Co jest powodem nie wiem choć przeczytałem polskiego datasheta PCF-a.
    Przepisałem program ale z porównywaniem czasu to jest masakra i do tego jak na złość nie działa , czy można to zrobić prościej ? proszę pomóżcie mi z tym programem....
    Kod: C#
    Zaloguj się, aby zobaczyć kod

    Niestety SYNTAX ERROR nic na to nie poradzę....
  • #17 9768703
    INTOUCH
    Poziom 30  
    Witam.
    Osobiście morduję się z podobnym tematem.
    Podrzuć biblioteki do HD44780 oraz i2c_twi bo nie wiem z których korzystasz.
    Wątpię żeby były twojego autorstwa.

    Podziel program na wiele plików, tylko nie rób tego hurtem ale stopniowo. Najpierw sprawdź czy działają ci funkcję obsługi klawiatury, wyświetlacz, potem czy działa ci przetwornik ADC , inne.
    Jeżeli będziesz miał błędy programu, który jest podzielony na wiele plików to pisz co nie działa.
    Z programem wielowiekowym też miałem problemy ale po dwóch tygodniach czasu i przeczytaniu paru mądrych książek (w których nie wszystko jest podane kawa na ławę) poradziłem sobie z problemem.
    Pokaż komunikaty błędów, w której lini kodu.
    Pomiar wartości analogowych, obliczanie czasu oraz wiele innych rzeczy mógłbyś wykonać w procedurze obsługi przerwania. Twój procesor jest niepotrzebnie obciążony i zajmuje się zbędnymi sprawami.
    Dużą cześć kodu programu powinieneś napisać w funkcjach.


    Pytania:
    czy do pomiaru bierzesz wartość chwilową czy średnią?
    Dla czego sterujesz podświetlaniem LCD na mikro kontrolerze? Tracisz 1 nóżkę.
    Czemu nie używasz przerwań.
  • #18 9768744
    LordBlick
    VIP Zasłużony dla elektroda
    INTOUCH napisał:
    Dla czego sterujesz podświetlaniem LCD na mikro kontrolerze? Tracisz 1 nóżkę.
    Też tak uważałem, dopóki po upływie 100 ms (aby wykluczyć chwilowe zaniki napięcia) zaniku zasilania na istniejącym zapasie energii w zasilaczu program nie musiał zapamiętać ustawień w zewnętrznej pamięci. Wyłączenie podświetlenia w takiej sytuacji jest jak zbawienie... Oczywiście w tym konkretnym zastosowaniu może to być zbędne...
  • #19 9768792
    INTOUCH
    Poziom 30  
    Źle używasz funkcji itoa()

    u ciebie jest
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    funkcja itoa nie zamieni ci tablicy znaków na tablicę znaków.

    powinno być:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dodano po 3 [minuty]:

    Jeśli chodzi o zegar czasu rzeczywistego sprawdź tu.
    https://www.elektroda.pl/rtvforum/topic2042998.html

    To już lepiej nie używać podświetlania, no chyba że układ będzie pracował w pomieszczeniu gdzie jest brak światła.
  • #20 9769325
    LordBlick
    VIP Zasłużony dla elektroda
    INTOUCH napisał:
    To już lepiej nie używać podświetlania, no chyba że układ będzie pracował w pomieszczeniu gdzie jest brak światła.
    Skoro w danej konstrukcji, która jest powielana w wielu egzemplarzach jest wyświetlacz z podświetleniem, to raczej jest logiczne, że jest to zasadne, bo wyświetlacz bez podświetlenia jet raczej tańszy...
  • #21 9775962
    margas4542
    Poziom 16  
    INTOUCH posyłam ci całość - co potrzebujesz to wyłuskaj.
    A gdyby ci się chciało poprawić moje bazgroły i odesłać do mnie będę bardzo wdzięczny.
  • #22 9776662
    INTOUCH
    Poziom 30  
    W najbliższym czasie mogę ci sprawdzić błędy.

    Jak się obronię z końcem września to bardzo chętnie ci pomogę w napisaniu kodu.

    Pytania na dzień dzisiejszy.

    Czy mierzysz wartość chwilową średnią czy skuteczną napięcia.
  • #23 9777355
    margas4542
    Poziom 16  
    Cały program poza zegarem sterującym [ kwestia porównywania czasu ] działa i napięcia oraz prądy są odczytywane poprawnie a co za tym idzie sterowanie dwoma zasilaczami oraz monitorowanie ogniwa foto galwanicznego [na razie brak - symulacja] działa również poprawnie.Mierzone napięcie jest napięciem skutecznym. Nadal próbuje dociec dlaczego mam błędny odczyt wartości miesięcy po zmianie wartości dni np;lipiec czyli 07 następnego dnia wyświetlany jest jako 27 a następnego 47.
    Zmieniłem funkcje odczytu czasu z pcf-a i napisałem na próbę funkcje porównywania czasu bieżącego z odczytana z pamięci pcf-a nastawa i przy "okazji" przestał działać klawisz 3 w trybie ustawiania godzin czasu...
    Kod: C#
    Zaloguj się, aby zobaczyć kod

    //==========================================================================================
    // ODCZYT ZEGARA CZASU RZECZYWISTEGO RTC
    //==========================================================================================
    int licznik;
    for(licznik=0;licznik<5;licznik++)
    {
    buffer_t[licznik] = TWI_read(pcf8583,rtc_adres[licznik]);
    sekundy = bcd_na_dec(buffer_t[0]);
    minuty = bcd_na_dec(buffer_t[1]);
    godziny = bcd_na_dec(buffer_t[2]);
    dni = bcd_na_dec(buffer_t[3]);
    miesiace = bcd_na_dec(buffer_t[4]);
    }
    //brak odczytu dnia tygodnia nie wim jak to ugryść.
    //==========================================================================================
    // ODCZYT CZASU NASTAW CZASU DLA ZEGARA STERUJĄCEGO OBWODAMI ZEWNĘTRZNYMI
    //==========================================================================================
    // if(sekundy==50) //odczyt nastaw timera co 1 minutę
    {
    for(licznik=10;licznik<27;licznik++)
    {
    buffer_t[licznik] = TWI_read(pcf8583,rtc_adres[licznik]);
    tc1[1] = bcd_na_dec(buffer_t[10]); //w dni robocze dla kanału 1
    tc1[2] = bcd_na_dec(buffer_t[11]);
    tc1[3] = bcd_na_dec(buffer_t[12]);
    tc1[4] = bcd_na_dec(buffer_t[13]);
    tc2[1] = bcd_na_dec(buffer_t[14]); //w dni robocze dla kanału 2
    tc2[2] = bcd_na_dec(buffer_t[15]);
    tc2[3] = bcd_na_dec(buffer_t[16]);
    tc2[4] = bcd_na_dec(buffer_t[17]);
    //==========================================================================================
    tc1[5] = bcd_na_dec(buffer_t[20]); //w dni wolne dla kanału 1
    tc1[6] = bcd_na_dec(buffer_t[21]);
    tc1[7] = bcd_na_dec(buffer_t[22]);
    tc1[8] = bcd_na_dec(buffer_t[23]);
    tc2[5] = bcd_na_dec(buffer_t[24]); //w dni wolne dla kanału 2
    tc2[6] = bcd_na_dec(buffer_t[25]);
    tc2[7] = bcd_na_dec(buffer_t[26]);
    tc2[8] = bcd_na_dec(buffer_t[27]);
    }
    }
    //==========================================================================================
    // FUNKCJE PORÓWNYWANIA CZASU BIERZĄCEGO Z CZASEM NASTAW pcf8583A STERUJĄCEGO
    //==========================================================================================
    // przykładowe działanie
    if(dzien_tygodnia > 5)//jeżeli od poniedziałku do piatku
    { //czas bieżący 13:00 jest większy niż nastawa 13:00
    if(time(godziny,minuty)>(tc1[1],tc1[2])) //załączenie obwodu na kanale 1
    {
    if(tryb[1]==0) { PORTC &=~ 0x10; } // to załacz optotriak obwodu nr.1
    if(tryb[2]==0) { PORTC &=~ 0x20; } // to załacz optotriak obwodu nr.2
    if(tryb[3]==0) { PORTC &=~ 0x40; } // to załacz optotriak obwodu nr.3
    if(tryb[4]==0) { PORTC &=~ 0x80; } // to załacz optotriak obwodu nr.4
    }
    if(time(godziny,minuty)>(tc1[3],tc1[4])) //wyłączenie obwodu na kanale 1
    { //czas bieżący 20:00 jest większy niż nastawa 20:00
    if(tryb[1]==0) { PORTC |= 0x10; } // to wyłacz optotriak obwodu nr.1
    if(tryb[2]==0) { PORTC |= 0x20; } // to wyłacz optotriak obwodu nr.2
    if(tryb[3]==0) { PORTC |= 0x40; } // to wyłacz optotriak obwodu nr.3
    if(tryb[4]==0) { PORTC |= 0x80; } // to wyłacz optotriak obwodu nr.4
    }
    //tutaj dla kanału 2
    {
    }
    }
    else //jeżeli w sobote oraz niedziele
    {
    //analogicznie jak wyżej
    }
    }
    }
    return;
    }
    //******************************************************************************************
    //************************************ END MAIN ********************************************

    a tu cały kod
    Załączniki:
  • #24 13871003
    margas4542
    Poziom 16  
    Zamykam definitywnie
REKLAMA