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

Układ z buzzerem na AtMega, będzie działał?

elektrodom 30 Sie 2010 12:34 3921 18
  • #1 30 Sie 2010 12:34
    elektrodom
    Poziom 20  

    Witam. Chcę zbudować sobie odstraszacz kun (strasznie denerwuje jak biegają po dachu/strychu i budzą człowieka w środku nocy), trochę na ten temat czytałem i wyczytałem, że dźwięki powinny być z zakresu ultradźwięku (ponad 20kHz) a długość ich trwania oraz częstotliwość dźwięku powinny być losowe- wtedy na pewno nie przyzwyczają się do jakiegoś powtarzalnego układu częstotliwości.
    Całość chciałem oprzeć o jakiś programowalny mikrokontroler, na stronie http://hobby.abxyz.bplaced.net/index.php?pid=4&aid=7
    znalazłem gotowy program dla AtMegi w układzie pozytywki- trochę go pozmieniałem dla swoich potrzeb, ale nie jestem do końca zadowolony- wpisałem konkretne wartości zarówno dla częstotliwości jak i czasu trwania dźwięku, a chciałbym żeby były to wartości losowe z danego zakresu. I tu jest moje pierwsze pytanie: co trzeba podstawić w tablicy w miejsce częstotliwości i długości dźwięku żeby były one losowe?
    Drugim moim pytaniem jest, czy program o kodzie jak poniżej będzie współpracował z układem jak na załączonym schemacie?
    Trzecie pytanie: jaki AVR najlepiej zastosować? Na stronie na której znalazłem pierwowzór mojego kodu była AtMega16, ale w tym wypadku chyba nie będzie potrzebna aż 16...

    Z góry dziękuję za wszelką pomoc i przepraszam za schemat- brak praktyki...
    Pozdrawiam

    Układ z buzzerem na AtMega, będzie działał?

    Code:

    układ atmega 1MHz
    PB0 -> R(330Ohm) -> BUZZER -> PB1
    */

    #define F_CPU 1000000L
    #include <avr/io.h>
    #include <util/delay.h>

    /**** ZMIENNE GLOBALNE ****/
    /*
    Tablica dzwięków:
    częstotliwść(Hz), czas_trwania(ms)
    */
    int kuna[][2]={
                        33230,125,
                        35870,125,
                        66590,250,
                        31980,125,
                        16590,125,
                        25870,250,
                        35230,250,
                        44047,250,
                        30840,250,




                        35230,250,
                        23047,250,
                        24840,250,
                        25230,250,
                        25647,250,
                        32840,1000 };

    /**** DEFINICJE WŁASNYCH FUNKCJI ****/

    /* Konfiguruje porty we/wy uC */
    void init(void)
    {
      /* PB0,PB1 - wyścia */
      DDRB  = 0x03;
      PORTB = 0x00;
    }

    /*
    Funkcja generuje sygnał prostokątny na wyprowadzeniach PB0 i PB1,
    gdzie przyłączony jest  buzzer. Funkcja przyjmuje argumenty:
    częstotliwość(Hz) sygnału i długość czasu trwania sygnału (ms).
    */
    void beep(unsigned int frequency, unsigned int duration)

      unsigned int i,t,n; 
      t = 125000/frequency; 
      n = (250UL*duration)/t;

      PORTB |= 0x01;
      PORTB &= ~0x02;
      for(i=0; i < n; i++)
      {
        PORTB ^= 0x01; 
        PORTB ^= 0X02; 
        _delay_loop_2(t);
      }
    }
    /*
    Odgrywa melodyjkę dzwięk po dzwięku. Jako argumentów funkcja
    oczekuje tablicy dzwięków oraz numerów pierwszego i ostatniego
    dzwięku. Elementami tablicy dźwięków  są tablice o dwóch elementach
    typu int (częstotliwość w Hz i długość trwania dzwięku w ms).
    */
    void play(int nots[][2], unsigned int start, unsigned int stop)
    {
       int n;
       
       for(n=start; n <= stop; n++)
            beep(nots[n][0], nots[n][1]);
    }           

    /**** POCZĄTEK PROGRAMU ****/           

    /* Definicja głównej funkcji */
    int main(void)
    {
       /* Konfiguracja sprzętu */
       init();

       /* Nieskończona pętla */
       while (1)
       {   
          /* Gra "melodyjkę" kuna wcześniej zdefiniowaną */
          play(kuna,0,15);
           
          /*  Chwila spokoju :) */   
          _delay_ms(6000);
       }
       return 0;
    }

    0 18
  • #2 30 Sie 2010 17:42
    Krauser
    Poziom 26  

    Możesz użyć Attiny25/45/85V w obudowie DIP8. Schemat też należy przerobić i wyrzucić stabilizator a całość zasilić z 3 baterii 1,5V.
    Najprostszym sposobem na losowość uruchamiania jest umieszczenie obrobionego wyniku funkcji rand() jako argument _delay_ms(period). Poczytaj o rand() i srand(). Pamiętać należy, żeby odpowiednio ograniczyć wyniki by mieściły się w oczekiwanym zakresie. Są przykłady w sieci. Jeśli chodzi o losową "melodię" to należy przed każdym wywołaniem funkcji play() wpisać do tablicy losowe wartości z zastrzeżeniem jak powyżej. Jeśli chcesz usłyszeć czy działa możesz tymczasowo zmienić zakres losowanych częstotliwości na słyszalne dla człowieka. Innym sposobem na losowe liczby jest uruchomienie timera(bez obsługi przerwań) i odczyt jego wartości w pętli głównej co pewien czas.
    Jeśli chcesz by układ długo pochodził na bateriach to warto wprowadzić procesor w tryb idle i budzić z każdym przerwaniem od timera, ale to wymaga rezygnacji z _delay_ms() i konfiguracji timera z obsługą przerwań (obniżenie częstotliwości taktowania to kolejna oszczędność). Chcąc jeszcze bardziej zaoszczędzić można wprowadzić mikrokontroler w tryb powerdown, a wybudzać przerwaniem od układu watchdog.

    0
  • #3 30 Sie 2010 17:58
    elektrodom
    Poziom 20  

    Jeśli chodzi o zasilanie to zależy mi na tym żeby wejściowe było 12V- może zamontuję w aucie.
    Czy wystarczy w tablicy zmienić konkretne wartości na :

    Code:

    rand() % 21000 + 40000;

    a w nagłówku dodać:
    Code:

    #include <stdio.h>
    #include <stdlib.h>
    ?

    W jaki sposób wywołać reset tablicy?

    0
  • #4 30 Sie 2010 18:38
    gaskoin
    Poziom 38  

    Krauser napisał:

    Najprostszym sposobem na losowość uruchamiania jest umieszczenie obrobionego wyniku funkcji rand() jako argument _delay_ms(period). Poczytaj o rand() i srand()


    wtedy 70% procesora będzie robiło tylko to i nic więcej.


    Co oznacza - reset tablicy ? :P

    0
  • #5 30 Sie 2010 18:43
    elektrodom
    Poziom 20  

    Użycie procesora nie ma znaczenia- cały scalak ma tylko generować losowe dźwięki w zakresie ultradźwięku o losowym czasie trwania.
    Reset tablicy- chodziło mi o wygenerowanie nowych liczb pseudolosowych.

    0
  • #6 30 Sie 2010 19:00
    gaskoin
    Poziom 38  

    Code:
    int main(){
    
            srand(time(0));
           
            while(1){
                    //generacja nowych liczb pseudolosowych
                    for(int i = 0 ; i < vec_length; i++) vec[i] = rand()%324234+4397134;

                    //cośtam w kodzie dalej
            }

    }


    a opóźnienia zależne od zmiennej lepiej zrobić tak:

    Code:

    void delay_ms(uint16_t delay){
            while(--delay){
                    _delay_ms(1);
            }
    }


    lub na timerze

    0
  • #7 30 Sie 2010 21:01
    elektrodom
    Poziom 20  

    Tylko- nie wiem czy dobrze myślę- gdzieś wyczytałem że to są liczby pseudolosowe- za każdym razem w pętli "wylosują" tą samą liczbę... Dobrze kombinuję?
    Mógłbym mieć do kolegów prośbę? Prosiłbym o wstawianie ich propozycji do fragmentów kodu który podałem na górze? Bo szczerze mówiąc to C dopiero mam zamiar się nauczyć...
    Pozdrawiam i dziękuję za już udzielone porady

    0
  • #8 30 Sie 2010 21:22
    gaskoin
    Poziom 38  

    po to dałem srand(time(0))l żeby nie wylosowywały ciągle tej samej liczby

    I wcale nie dlatego się nazywają pseudolosowymi bo losują w kółko tą samą liczbę tylko z innego :)

    0
  • #9 30 Sie 2010 21:43
    elektrodom
    Poziom 20  

    Rozumiem. A w tablicy jak by to wyglądało? Bo rozumiem zastosowanie Twojej propozycji zmieniłoby form skryptu.

    0
  • Pomocny post
    #10 30 Sie 2010 22:10
    gaskoin
    Poziom 38  

    funkcję srand() wystarczy wywołać raz. Potem do wylosowania jednej liczby używa się już rand

    0
  • #11 30 Sie 2010 22:31
    elektrodom
    Poziom 20  

    Mógłbyś to "wmontować" w mój kod? Bo mówiąc wprost- nie mam pojęcia gdzie to dać. Rozumiem mniej-więcej o co chodzi i jak to działa, ale nie wiem gdzie to wstawić...:/

    0
  • #12 30 Sie 2010 22:37
    gaskoin
    Poziom 38  

    skoro ma być wywołane tylko raz, tzn, że ma być przed pętlą główną programu. Z resztą już napisałem przykład, razem z generowaniem liczb do tablicy

    Cytat:
    Code:
    int main(){
    
            srand(time(0));
           
            while(1){
                    //generacja nowych liczb pseudolosowych
                    for(int i = 0 ; i < vec_length; i++) vec[i] = rand()%324234+4397134;

                    //cośtam w kodzie dalej
            }

    }

    0
  • #13 30 Sie 2010 22:53
    elektrodom
    Poziom 20  

    Zgadza się, to MOŻE być w pętli głównej, ale nie musi.
    Generowane mają być pary liczb losowych z dwóch różnych przedziałów, żeby było czytelnie zależy mi na tym, żeby te pary mieściły się w tablicy (w kodzie na początku są w tym miejscu dwie liczby- chciałbym, żeby tam były dwie funkcje generujące dwie losowe liczby. Da się tak?

    0
  • #14 30 Sie 2010 23:00
    gaskoin
    Poziom 38  

    no przecież randoma możesz wstawić byle gdzie i może generować on dowolne liczby więc czemu miało by się nie dać :)

    Chyba, że Tobie chodzi o wpisanie tam losowych liczb podczas kompilacji programu ?

    0
  • #15 31 Sie 2010 11:33
    elektrodom
    Poziom 20  

    Czyli tablica wyglądałaby tak:

    Code:

    int kuna[][2]={
                   rand()%28000+439713;, rand()%1+5000;
                   •
                   •
                   •
    ?

    Nie. Losowa ma być generowana każdorazowo w samym uC.
    Tylko czy ona będzie w tablicach generowana tylko raz, czy za każdym wywołaniem play(kuna, 0, 15)?

    0
  • #16 31 Sie 2010 12:26
    gaskoin
    Poziom 38  

    to się nie skompiluje. Musisz ją uzupełnić w jakiejś funkcji najlepiej :)

    0
  • #17 31 Sie 2010 12:39
    elektrodom
    Poziom 20  

    Nie rozumiem:(.
    Czyli co muszę wstawić konkretnie w tablicy żeby grało i losowało liczby?

    0
  • Pomocny post
    #18 31 Sie 2010 13:41
    gaskoin
    Poziom 38  

    albo w pętli ją na nowo uzupełniać, albo w ogóle jej nie tworzyć, tylko wywoływać funkcję beep z parametrami, które będą funkcją random:

    Code:
    beep(rand()%costam + costam2, rand()%costam3 + costam4)

    0
  • #19 31 Sie 2010 13:58
    elektrodom
    Poziom 20  

    Czyli usunąć tablicę i wstawić Twoją linijkę zamiast istniejącej beep, tak?
    Jeszcze jakieś zmiany będą konieczne? Zasilanie uC jest ok?

    0