Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[atmega32][C]System zarzadzania i monitorowania

margas4542 04 Lip 2011 10:53 3810 23
  • #1 04 Lip 2011 10:53
    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
    Zaloguj się, aby zobaczyć kod

    0 23
  • #2 04 Lip 2011 17:15
    cadavre
    Poziom 9  

    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.

    0
  • #4 04 Lip 2011 19:12
    tomekgl
    Poziom 15  

    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)) ).

    0
  • #5 04 Lip 2011 20:24
    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.

    0
  • #6 14 Lip 2011 10:50
    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..

    0
  • #7 17 Lip 2011 14:55
    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]

    0
  • #10 17 Lip 2011 21:46
    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..

    0
  • #11 17 Lip 2011 22:25
    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.

    0
  • #12 18 Lip 2011 08:50
    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.

    0
  • #13 18 Lip 2011 22:49
    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

    0
  • #14 19 Lip 2011 14:38
    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..

    0
  • #15 19 Lip 2011 21:11
    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 ?

    0
  • #16 24 Lip 2011 22:00
    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: csharp
    Zaloguj się, aby zobaczyć kod

    Niestety SYNTAX ERROR nic na to nie poradzę....

    0
  • #17 28 Lip 2011 18:08
    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ń.

    0
  • #18 28 Lip 2011 18:23
    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...

    0
  • #19 28 Lip 2011 18:43
    INTOUCH
    Poziom 30  

    Źle używasz funkcji itoa()

    u ciebie jest

    Kod: c
    Zaloguj się, aby zobaczyć kod



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

    powinno być:

    Kod: 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.

    0
  • #20 28 Lip 2011 20:54
    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...

    0
  • #21 30 Lip 2011 19:56
    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.

    0
  • #22 30 Lip 2011 22:47
    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.

    0
  • #23 31 Lip 2011 10:22
    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: csharp
    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

    0
    Załączniki:
  • #24 12 Sie 2014 10:50
    margas4542
    Poziom 16  

    Zamykam definitywnie

    0