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

Atmega88 - [Code:blocks] Uniwersalizacja funkcji programu w języku C

Staanleyt 30 Sty 2015 09:47 876 6
REKLAMA
  • #1 14382732
    Staanleyt
    Poziom 2  
    Cześć.
    Robię projekt polegający na podzieleniu trasy kolejki piko na odcinki punktami pomiarowymi w celu zliczania ilości osi pociągów znajdujących się na poszczególnych odcinków. Każdy punkt pomiarowy składa się z dwóch czujników odbiciowych (CNY70), podłączonych do Mikrokontrolera Atmega88.
    Napisałem program, który liczy osie przejeżdżające pomiędzy dwoma sąsiednimi odcinkami. Poniżej zamieszczam kod funkcji LicznikOsi_XX, którą chciałbym zuniwersalizować (nie wklejam całego programu ponieważ problem dotyczy ww. funkcji, a cały program składa się z 5 modułów i w sumie jest sporo kodu, a nie chce zaśmiecać forum :). Oczywiście jeżeli będzie taka potrzeba to wkleję cały program)

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


    Tak napisany program działa prawidłowo, jednak kolejne punkty pomiarowe wymagają zastosowania kolejnych funkcji, cyklicznie wywoływanych w pętli while, właściwie identycznych, wymagających tylko zmiany zmiennych (np. PP_AB na PP_BC, Odc_A na Odc_B, Odc_B na Odc_C itd.). Jest to jednak rozwiązanie pracochłonne (konieczność ręcznej zmiany zmiennych we wszystkich liniach programu), mało funkcjonalne (przy zmianie układu odcinków ponownie konieczność ręcznej zmiany zmiennych w całym programie) i do tego mało ekonomiczne (powstaje spora ilość kodu, zajmująca sporą ilość pamięci.
    Podjąłem nieudaną próbę stworzenia uniwersalnej funkcji, w której cyklicznie, w odpowiednie miejsca programu, wprowadzane by były zmienne dotyczące kolejnych punktów pomiarowych:

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


    Szybko stało się jasne, że metoda z wprowadzeniem tablic nie ma szans powodzenia, jednak wstawiłem tutaj nieudany kod, aby było bardziej jasne jaki efekt chciałbym osiągnąć.
    Proszę o informacje, podpowiedzi, sugestie od bardziej doświadczonych programistów jak (jakimi narzędziami) napisać uniwersalną funkcję dla opisanego wyżej programu (i czy gra jest warto świeczki - tzn. czy napisanie uniwersalnej funkcji nie skomplikuje bardziej programu niż da korzyści).

    Ponieważ jestem na początku mojej przygody z programowaniem, a powyższy post to pierwszy mój post na forum programistycznym, jeżeli mój post został napisany w sposób, który zniechęca do odpowiadania na niego, proszę o komentarz wyjaśniający, co należy w nim zmienić, aby była szansa uzyskania konstruktywnej odpowiedzi.

    Moderowany przez piotrva:

    Poprawiam znaczniki syntax

  • REKLAMA
  • #2 14382749
    BlueDraco
    Specjalista - Mikrokontrolery
    Metoda z tablicami jest całkiem dobra, cała reszta jest błędna. Po pierwsze - nie da się wiarygodnie zliczać osi przy użyciu transoptora. Po drugie, czegokolwiek byś nie użył w zamian (np. rezystory na osiach i czujniki prądowe) - trzeba filtrować odczyty z czujników, a to robi się na bazie przerwania timera, a nie w pętli kręcącej się z nieznaną i niemożliwą do określenia częstotliwością.
  • REKLAMA
  • #3 14383318
    Staanleyt
    Poziom 2  
    Dziękuję za odpowiedź.
    Mi też metoda z tablicami wydawała się dobra, ale nie działa. I mam wątpliwości czy może działać, ponieważ z tego co udało mi się wyczytać, zmienne w tablicy muszą mieć stałą wartość w czasie wykonywania programu.
    Dla przykładu weźmy tablicę
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W kolejnych cyklach wykorzystywana ma być kolejna zmienna (gdy i == 0 -PP_AB, gdy i == 1 -PP_BC itd.), przy czym każda ze zmiennych może przyjąć wartość 0,1,2 lub 3 (w zależności od stanu czujników w danym punkcie pomiarowym). Cały problem polega na tym, żeby zmienna np. PP_Stan[0] (czyli PP_AB), dynamicznie zmieniała swoją wartość w zależności od wyniku działania funkcji w poprzednim cyklu w którym i ==0.
    Z tego co udało mi się wyczytać zwykłe tablice nie dają takich możliwości i wartość zmiennej PP_AB w przypadku pobierania jej z tablicy PP_Stan[] ma cały czas wartość nadaną podczas definiowania zmiennej PP_AB, czyli 0.
    Pytanie jak to zrobić, żeby wartość zmiennych w tablicy dynamicznie zmieniała się w czasie trwania programu?
    Coś czytałem o tablicach dynamicznych, które, jeśli dobrze zrozumiałem, wymagają zastosowania wskaźników.
    Jak myślicie, jaka jest najlepsza metoda na rozwiązanie problemu?

    Natomiast jeśli chodzi o stosowanie trasoptora, filtrowania oraz timera pozwolę sobie na wyjaśnienie:
    - mój model poprawnie zlicza osie z wykorzystaniem transoptora,
    - filtrowanie odbywa się programowo z wykorzystaniem 4 możliwych stanów każdego punktu pomiarowego, tak, że zakłócenia nie wpływają na poprawność zliczania osi na poszczególnych odcinkach,
    - czas występowania każdego ze stanu punku pomiarowego, przy przewidywanych dla kolejki piko prędkościach, jest na tyle długi, że nie ma możliwości, żeby któryś ze stanów punktu pomiarowego był pominięty przy zastosowanej w programie pętli.
    Moderowany przez piotrva:

    Poprawiam znaczniki syntax - nie wiem co się Koledze przyplątało z tym, żeby dwa razy otwierać i zamykać - proszę w edycji wiadomości zobacz jak powinny wyglądać poprawnie użyte znaczniki syntax.
    Pozdrawiam

  • REKLAMA
  • #4 14384028
    BlueDraco
    Specjalista - Mikrokontrolery
    Tablica zmiennych jest tablicą zmiennych i oczywiście może zmieniać wartość. Prawdopodobnie chodzi Ci o tablicę wskaźników na zmienne - też możesz to zastosować.

    A wszelkie uwagi do rozwiązania podtrzymuję, włącznie z testowaniem w pętli o nieznanym czasie obiegu. Nie wiesz nic o charakterystyce czasowej Twojego procesu próbkowania, anie nie uwzględniłeś zakłóceń (drżenia) sygnału z transoptorów. To czasami będzie działać i czasami policzy poprawnie. Na ogół będą błędy.
  • #5 14399328
    Staanleyt
    Poziom 2  
    No właśnie i tu dochodzimy do meritum mojego problemu.
    Jak zrobić, żeby tablica była tablicą zmiennych, a nie tablicą stałych. Czy do tego konieczne jest zastosowanie wskaźników na zmienne?

    Odnośnie rozwiązania dziękuję za uwagi, każdą konstruktywną krytykę uważam za wartościową i doceniam. W pierwszej kolejności chciałbym jednak skupić się na znalezieniu metody uniwersalizacji funkcji liczącej osie w poszczególnych punktach pomiarowych, szczególnie, że układ działa dobrze, zlicza osie bez pomyłek, wystarczająco do treningowo - hobbystycznych potrzeb do jakich został stworzony.
  • #6 14399416
    BlueDraco
    Specjalista - Mikrokontrolery
    Tablica zadeklarowana bez słowa const zawiera zmienne. Tobie prawdopodobnie chodzi o to, że chcesz mieć w tablicy adresy zmiennych, czyli wskaźniki na zmienne. Proste - przeczytaj odpowiedni fragment odpowiedniej książki o programowaniu w C, zrozum wskaźniki, a potem pisz.

    Z drugiej strony - na atmega niekoniecznie to będzie sensowne. Równie dobrze możesz w tablicy trzymać indeksy do drugiej tablicy, np. coś takiego:

    uint8_t liczniki[10];

    const uint8_t sekcje[] = {1, 2, 5, 7};

    i gdzieś w kodzie:

    licznik[sekcje[3]] ++;
  • REKLAMA
  • #7 14406757
    Staanleyt
    Poziom 2  
    Dzięki za pomoc.
REKLAMA