Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

pseudolosowosc w (win)avr - funkcje

planim 09 Lip 2007 13:17 3716 20
  • #1 09 Lip 2007 13:17
    planim
    Poziom 2  

    Z jakich funkcji należy skorzystać, aby otrzymać pseudolosowość?
    Do generacji liczb używam rand(), ale liczby są generowane zawsze takie same. Szukam odpowiednika funkcji Randomize() z pascala. Z tego co czytałem to trzeba skorzystać z srand() - przy czym w moim wypadku funkcja ta powoduje że układ w ogóle przestaje działać. :|
    Jeżeli można to proszę o przykładowy kod.

    Z góry dziękuję za odpowiedź.

  • #2 09 Lip 2007 14:17
    Ch.M.
    Poziom 27  

    Jeśli masz wolny port ADC to podłącz go do zmiennego źródła lub pozostaw w powietrzu i napisz odpowiedni algorytm korzystający z niego i z licznika.
    Pozdrawiam

  • #3 09 Lip 2007 15:44
    planim
    Poziom 2  

    A nie da się tylko programowo? Po co byłyby w tym wypadku w ogóle funkcje (s)rand i (s)random skoro nie da się ich wykorzystać do generowania pseudolosowych liczb?

  • Pomocny post
    #4 10 Lip 2007 10:29
    Ch.M.
    Poziom 27  

    Programowo to zawsze będziesz miał uzalezniony wynik od cyklu zegara. To nie Pentium III ze masz oddzielny układ generatora pseudolosowego :) (notabene sprzętowy)
    Pozdrawiam

  • Pomocny post
    #5 10 Lip 2007 10:32
    szelus
    Specjalista - Mikrokontrolery

    planim napisał:
    Po co byłyby w tym wypadku w ogóle funkcje (s)rand i (s)random skoro nie da się ich wykorzystać do generowania pseudolosowych liczb?


    Jak to się nie da? Jak najbardziej się da, tylko trzeba pamiętać jak one działają.

    1. Po pierwsze, dla AVR libc funkcja rand() zwraca wynik 16 bitowy, (bo taki jest int). Aby uzyskać dłuższy ciąg należy korzystać z funkcji random()/srandom().

    2. Aby uzyskać za każdym razem inny ciąg pseudolosowy należy za każdym razem zinicjować generator inną wartością (funcja srand()/srandom()). Na PC-cie zwykle używa się do tego zegara czasu rzeczyswistego, tzn:
    Code:

    srand(time(NULL));

    AVR standardowo nie ma takiego zegara. Jeżeli na płytce mamy dodatkowy RTC, to można go wykorzystać. Jeżeli nie, to trzeba sobie radzić inaczej, np. tak, jak napisał Ch.M. lub np. mierząc bardzo szybkim zegarem czas wciśnięcia jakiegoś przycisku przez operatora itp.

  • #6 10 Lip 2007 12:20
    planim
    Poziom 2  

    Ok, wielkie dzięki.

  • #7 22 Kwi 2011 15:43
    syntetyczn dran
    Poziom 11  

    Trochę odświeżę temat (trochę to wykopaliska:P)

    Chciałem za pomocą timera wygenerować wartość pseudolosową. Płytka będzie działać tak, że przycisk na resecie resetuje uc i zczytuję wartość na timerze, którą później wyświetlam na wyświetlaczu( taka tam kostka do gry). Czy tak się da?Czy może się mylę. Timer, jak już w temacie jest, będzie b.szybki.

  • #9 22 Kwi 2011 17:58
    janbernat
    Poziom 38  

    Dwa przyciśnięcia mikroprzełącznikiem.
    Start/stop timera.

  • #10 22 Kwi 2011 19:22
    krru
    Poziom 32  

    Wystarczy raz i zmierzyć czas naciśniecia przycisku, oczywiście z dużą rozdzielczością.

  • #11 22 Kwi 2011 19:47
    syntetyczn dran
    Poziom 11  

    ok, więc zmierzę w us czas naciśnięcia przycisku.Ale czy da się akurat zmierzyć czas wciśnięcia resetu?Gdyż płytkę (zbyt pochopnie) już wykonałem i polutowałem. Jeszcze myślałem, że można by przy starcie zrobić timer liczący czas trwania pętli for dla np. 50iteracji. Czy jest to dobry pomysł?

  • #12 22 Kwi 2011 20:15
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie jest. Procesor jest z natury układem deterministycznym, taka pętla zawsze wykonuje się taką samą liczbę taktów zegara. Czasu resetu też nie da się zmierzyć, bo jak to reset - wszystko wraca do ustalonego stanu początkowego. Natomiast masz ADC i być może np. wewnętrzną diodę na jednym z kanałów umożliwiającą pomiar temperatury. Wykorzystaj szum z ADC lub z tej diody jeśli jest. Przy jednym odczycie dostaniesz co najmniej jeden bit losowy (szum).

  • #13 22 Kwi 2011 21:43
    syntetyczn dran
    Poziom 11  

    Czyli wystarczy użyć np. ADC0 do sczytywania szumów i użyć ich do generacji. Dopiero się uczę więc, mam pytanie, czy zachowam wtedy działanie resetu?
    pseudolosowosc w (win)avr - funkcje

  • #14 22 Kwi 2011 21:49
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie, jeśli wyłączysz reset. Ale nie musisz tego robić, możesz też wykorzystać inny kanał ADC. To, że masz do niego coś podłączone nie przeszkadza.

  • #15 22 Kwi 2011 22:09
    syntetyczn dran
    Poziom 11  

    Czyli struktura programu będzie taka:
    - ustawiam np.PB4 żebym mógł nim sczytywać szumy
    - sczytuję szum, włączam generację liczb pseudolosowych
    - generuję liczbę
    - ustawiam PB4 jako zwykłe wyjście
    - wyświetlam cyfrę
    ?

  • #16 22 Kwi 2011 22:47
    krru
    Poziom 32  

    Wykorzystanie ADC ma tę wadę, że trudno ocenić jaki charakter będzie miała wylosowana liczba. Jaki rozkład prawdopodobieństwa itp. Może się okazać, że niektóre wyniki będą padały częsciej, a inne rzadziej. Wymaga to zbadania.

  • #17 23 Kwi 2011 10:29
    nsvinc
    Poziom 35  

    Wykorzystanie ADC nie ma żadnej wady - nie powinno się przetwarzać całych liczb zwróconych przez ADC, niezależnie od źródła pomiaru. Trzeba wykorzystać kilka najmłodszych bitów, i sklejać te bity w jakiś strumień bitów. Następnie trzeba te bity przetwarzać w specjalny sposób, aby strumień losowych bitów nie miał składowej stałej (tj. musi być podobna ilość zer i jedynek). Wynik tych operacji da gotowy strumień bitów który sobie można dzielić na dowolne kawałki po 4, 8 czy 32 bity (wszystko jedno).

  • #18 05 Maj 2011 18:51
    syntetyczn dran
    Poziom 11  

    Witam po przerwie,

    Napisałem kod, który generuje liczby pseudolosowe. Nie jest to może kod, najwyższych lotów, jednakże prosiłbym o pomoc w jego ulepszeniu.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Próbowałem uzyskać coś przy pomocy ADC, ale niestety nic mi się nie udało uzyskać lepszego od tego.

    Nie wiem, może coś źle inicjalozowałem?? Wybrałem największą rozdzielczość
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Oczywiście, w pierwszym kodzie nie korzystam z ADC.
    Proszę o pomoc,

  • #19 05 Maj 2011 19:19
    tmf
    Moderator Mikrokontrolery Projektowanie

    Odczytując ADC musisz brać pod uwagę tylko najmłodsze 1-2 bity, bo tylko one zawierają szum. Czyli żeby poskładać 8-bitową próbkę potrzebujesz co najmniej 8 odczytów ADC z których składasz wynik. Jeśli potrzebujesz więcej liczb losowych to gromadź te próbki w pamięci - szum ADC wprowadzi potrzebną ci entropię, niezbędną do generowania liczb losowych.

  • #20 05 Maj 2011 21:23
    nsvinc
    Poziom 35  

    No i jak pisałem wyżej - musi zostać zaimplementowana funkcja wycinająca składową stałą. Najprostszy algorytm jest opisany na stronie random.org, przy czym powoduje utratę połowy zebranych próbek. (czyli z 1024 bitów zsamplowanych masz 512 bitów uzytecznych)

    Jeśli tego nie zrobisz, to suma wszystkich bitów będzie dążyć do + lub - nieskończoności.

  • #21 05 Maj 2011 23:11
    syntetyczn dran
    Poziom 11  

    Dzięki panowie, zostało mi gdzieś ok 25-15% pamięci małego attiny13, ale mam nadzieję, że sobie z tym poradzę. Jeszcze raz dzięki!

TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo