eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
Ilość wypowiedzi w tym wątku: 11

  • 1. Data: 2012-10-09 01:43:37
    Temat: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: "Robbo" <n...@g...com>

    Witam,

    Używam mikrokontrolera ATmega128. W moim programie użytkownik ustawia
    wartość prądu (liczba całkowita od 0 do 1000) oraz czas (od 1 do 40 sekund).
    Prąd ma narosnąć od 0 do wartości ustawionej w ustawionym czasie. Funkcja
    służąca do obliczania aktualnej wartości prądu podczas jego narastania jest
    wywoływana z pewną częstotliwością (od 10 do 60Hz, zależnie od ustawienia w
    parametrach programu). Zatem narastanie prądu odbywa się w liczbie kroków
    wyrażonej wzorem: K = czas[s] * częstotliwość[Hz].
    Żeby uniknąć obliczeń zmiennoprzecinkowych, zastosowałem algorytm Bresenhama
    do kreślenia odcinków. Zapowiada się, że będzie to działać bardzo szybko,
    gdy K >= wartość prądu.
    Gdy K < wartość prądu, to algorytm Bresenhama normalnie kreśli odcinek w
    pętli "idąc po zmiennej Y". Tymczasem ja działam w osi odciętych, czyli X (u
    mnie jest to liczba kroków, w których prąd ma narosnąć). Bez większych
    problemów przerobiłem ten algorytm tak, aby dla K < wartość prądu, "szedł on
    po zmiennej X". Przy czym po tej przeróbce uzyskałem podpętlę (while), która
    niekiedy będzie wykonywać się wiele razy (dla pojedynczego kroku w osi X),
    co spowolni algorytm. Inną metodą, zamiast tej podpętli, byłoby zastosowanie
    dzielenia, co też nie jest rozwiązaniem, gdyż dzielenie realizowane jest
    przez kompilator także w pętli.
    Poniżej przedstawiłem algorytm, który stosuję -- na razie to jest wersja
    kreśląca grafikę (tak łatwiej mi obserwować działanie tego algorytmu), a nie
    funkcja wywoływana z pewną częstotliwością i sterująca prądem.
    Algorytm działa prawidłowo. Przy czym może działać niekiedy wolno (pętla
    while może wykonywać się wiele razy) dla K < wartość prądu -- no i to jest
    mój problem.
    Mam pytanie do Was, jak przyspieszyć ten algorytm?
    A jeśli się nie da, to byłbym wdzięczny za naprowadzenie na jakiś inny
    sposób zaprogramowania opisanego problemu (narastania wartości w pewnej
    liczbie kroków).

    Ilustracja graficzna działania poniżej zaprezentowanego algorytmu:
    http://imageshack.us/a/img341/925/74439722.png

    K = czas * czestotliwosc;

    if (K >= wartoscPradu) {
    for (t = 0; t <= K; t++) {
    drawPixel(px, py);
    y += wartoscPradu + 1;
    if (y >= K + 1)
    y -= K + 1, py++;
    px++;
    }
    } else {
    for (t = 0; t <= K; t++) {
    while (1) {
    x += K + 1;
    if (x >= wartoscPradu + 1) {
    drawPixel(px, py);
    x -= wartoscPradu + 1, px++;
    py++;
    break;
    }
    py++;
    }
    }
    }


    Pozdrawiam i z góry dziękuję za pomoc,
    Robbo


  • 2. Data: 2012-10-09 04:12:09
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: Dondu <m...@g...com>

    cyt:

    "Algorytm może działać zarówno na liczbach zmiennoprzecinkowych jak i całkowitych,
    ale ze względów wydajnościowych wykorzystuje się najczęściej realizacje
    całkowitoliczbowe. Zatem jeżeli początkowa wartość zmiennej decyzyjnej d lub jej
    przyrosty wychodzą nam ułamkowe, to mnożymy zarówno zmienną decyzyjną d jak i jej
    przyrosty tak by uzyskać liczby całkowite. Możemy tak zrobić gdyż do decyzji bierzemy
    pod uwagę jedynie znak zmiennej decyzyjnej d."

    źródło: http://www.algorytm.org/podstawy-grafiki/algorytm-br
    esenhama.html


  • 3. Data: 2012-10-09 09:29:35
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: Michoo <m...@v...pl>

    On 09.10.2012 01:43, Robbo wrote:
    > Witam,
    >
    > Używam mikrokontrolera ATmega128. W moim programie użytkownik ustawia
    > wartość prądu (liczba całkowita od 0 do 1000) oraz czas (od 1 do 40
    > sekund). Prąd ma narosnąć od 0 do wartości ustawionej w ustawionym
    > czasie. Funkcja służąca do obliczania aktualnej wartości prądu podczas
    > jego narastania jest wywoływana z pewną częstotliwością (od 10 do 60Hz,
    > zależnie od ustawienia w parametrach programu). Zatem narastanie prądu
    > odbywa się w liczbie kroków wyrażonej wzorem: K = czas[s] *
    > częstotliwość[Hz].
    Albo czegoś nie zrozumiałem, albo to jest zwykła proporcja:
    I(s)=I(S0)+(I(Se)-I(S0))*((s-S0)/(Se-S0))
    I(s)=I(S0)+(I(Se)-I(S0))/(Se-S0) * (s-S0)
    gdzie s - czas, S0 - czas początkowy, Se - czas końcowy

    Przekształcasz to sobie na:
    I(t)=I(T0)+t*dI
    I(t)=I(t-1)+dI

    Raz wyliczasz iloraz różnicowy dI, potem masz w każdym cyklu jedno
    dodawanie i jeden shift.


    --
    Pozdrawiam
    Michoo


  • 4. Data: 2012-10-09 10:06:39
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: Piotr Gałka <p...@C...pl>


    Użytkownik "Robbo" <n...@g...com> napisał w wiadomości
    news:5073652e$0$26682$65785112@news.neostrada.pl...
    > Mam pytanie do Was, jak przyspieszyć ten algorytm?
    > A jeśli się nie da, to byłbym wdzięczny za naprowadzenie na jakiś inny
    > sposób zaprogramowania opisanego problemu (narastania wartości w pewnej
    > liczbie kroków).
    >
    Jestem lepszy w EMC niż algorytmach ale zaproponuję to, co mi się nasunęło.

    Może w przypadku K<I podzielić I/n (n=2,4,8,...) aż będzie K>I, a potem
    pętla już jak dla przypadku K>I, tylko py++ zastąpić py+=n.
    "Schodki" wyjdą większe niż z twojej części else, ale jeśli dzielenie przed
    pętlą nie byłoby problemem to może być n=2,3,4,5,.... i wtedy to chyba już
    wyjdzie prawie to samo.
    P.G.


  • 5. Data: 2012-10-09 10:18:07
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: Piotr Gałka <p...@C...pl>


    Użytkownik "Piotr Gałka" <p...@C...pl> napisał w
    wiadomości news:5073db09$1@news.home.net.pl...
    >
    > Użytkownik "Robbo" <n...@g...com> napisał w wiadomości
    > news:5073652e$0$26682$65785112@news.neostrada.pl...
    >> Mam pytanie do Was, jak przyspieszyć ten algorytm?
    >> A jeśli się nie da, to byłbym wdzięczny za naprowadzenie na jakiś inny
    >> sposób zaprogramowania opisanego problemu (narastania wartości w pewnej
    >> liczbie kroków).
    >>
    > Jestem lepszy w EMC niż algorytmach ale zaproponuję to, co mi się
    > nasunęło.
    >
    > Może w przypadku K<I podzielić I/n (n=2,4,8,...) aż będzie K>I, a potem
    > pętla już jak dla przypadku K>I, tylko py++ zastąpić py+=n.
    > "Schodki" wyjdą większe niż z twojej części else, ale jeśli dzielenie
    > przed pętlą nie byłoby problemem to może być n=2,3,4,5,.... i wtedy to
    > chyba już wyjdzie prawie to samo.

    Poprawka.
    Jednak nie prawie to samo bo będą stałe przyrosty a czasem brak przyrostu.
    Przyrosty zmienne są jednak bliższe ideału.
    P.G.


  • 6. Data: 2012-10-09 12:19:48
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: "Robbo" <n...@g...com>

    Witam,

    Dziękuję za odpowiedź, która mam nadzieję naprowadzi mnie na właściwe tory.

    > Albo czegoś nie zrozumiałem, albo to jest zwykła proporcja:

    Tak. Prąd ma przyrastać w K krokach o wartość maxPrąd/K w każdym kroku.

    > I(s)=I(S0)+(I(Se)-I(S0))*((s-S0)/(Se-S0))
    > I(s)=I(S0)+(I(Se)-I(S0))/(Se-S0) * (s-S0)
    > gdzie s - czas, S0 - czas początkowy, Se - czas końcowy

    Czas będzie zawsze liczony od zera. Prąd początkowy także będzie narastać od
    zera.
    Więc jeśli I(S0) = 0, S0 = 0. Zatem powyższe formuły można uprościć do:
    I(s) = I(Se) * (s/Se)
    I(s) = I(Se)/Se*s

    > Przekształcasz to sobie na:
    > I(t)=I(T0)+t*dI
    > I(t)=I(t-1)+dI
    >
    > Raz wyliczasz iloraz różnicowy dI, potem masz w każdym cyklu jedno
    > dodawanie i jeden shift.

    Tu bym prosił o wyjaśnienie. Mało spałem i chyba nie do końca myślę, dlatego
    proszę o wybaczenie.

    Czy dI będzie wartością zmiennoprzecinkową?
    W jaki sposób będzie użyty shift?

    Czy chodzi o to, że przy wyliczaniu dI robimy shift w lewo, aby nie tracić
    precyzji, a działać na liczbach całkowitych. Potem działamy na dużych
    wartościach dI, a tuż przed użyciem wartości I robimy shift w prawo?

    Robbo



  • 7. Data: 2012-10-09 12:50:29
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: Michoo <m...@v...pl>

    On 09.10.2012 12:19, Robbo wrote:
    > Czas będzie zawsze liczony od zera. Prąd początkowy także będzie
    > narastać od zera.
    > Więc jeśli I(S0) = 0, S0 = 0. Zatem powyższe formuły można uprościć do:
    > I(s) = I(Se) * (s/Se)
    > I(s) = I(Se)/Se*s
    Dokładnie. Ale tak długo jak zmiany są liniowe to wystarcza raz policzyć
    iloraz różnicowy.

    >
    >> Przekształcasz to sobie na:
    >> I(t)=I(T0)+t*dI
    >> I(t)=I(t-1)+dI
    >>
    >> Raz wyliczasz iloraz różnicowy dI, potem masz w każdym cyklu jedno
    >> dodawanie i jeden shift.
    >
    > Tu bym prosił o wyjaśnienie. Mało spałem i chyba nie do końca myślę,
    > dlatego proszę o wybaczenie.
    >
    > Czy dI będzie wartością zmiennoprzecinkową?
    Stałoprzecinkową, np. o 16 bitach części całkowitej i 16 po przecinku:

    uint16_t I=0;
    uint32_t I_accu=0;
    uint32_t dI;
    time_t last_time=0;

    void new_setting(/**/){
    dI=(I_target<<16)/time_slices;
    }
    void calc(time_t t){
    I_accu+=dI*(t-last_time);
    I=I_accu>>16;
    last_time=t;
    }

    --
    Pozdrawiam
    Michoo


  • 8. Data: 2012-10-09 16:49:30
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: "Robbo" <n...@g...com>

    Serdeczne Bóg zapłać. Wszystko ładnie działa.

    Robbo


  • 9. Data: 2012-10-10 00:40:36
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: AlexY <a...@i...pl>

    Użytkownik Robbo napisał:
    > Serdeczne Bóg zapłać. Wszystko ładnie działa.

    Jakie bóg zapłać? Chłopaki piwa by się napili ;)

    --
    AlexY
    http://nadzieja.pl/inne/spam.html
    http://www.pg.gda.pl/~agatek/netq.html


  • 10. Data: 2012-10-10 12:03:17
    Temat: Re: ATmega, jak zaprogramować narastanie wartości sygnału, bez użycia operacji zmiennoprzecinkowych?
    Od: "Robbo" <n...@g...com>

    Nie ma problemu. Chętnie wyślę pocztą dobre piwo z małego browaru, a nie
    sikacz z koncernu.

    R.

strony : [ 1 ] . 2


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: