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.

[ATmega8][Bascom]Ultradzwięki-Badanie odległości z INT i Tim

FastProject 23 Maj 2008 10:19 4843 7
  • #1 23 Maj 2008 10:19
    FastProject
    Poziom 28  

    Witam

    Postanowiłem zbudować miernik odległości wykorzystujący ultradźwięki. Zakupiłem 2 czujniki w TME http://www.tme.pl/przetwornik-ultradzwiekowy-...runkowy-40khz/arts/pl/a29/bpu-1640toah12.html
    http://www.tme.pl/dok/b14/100902_bpu-1640ioah12.pdf
    Jednego używam do wysłania fali a 2-go do odebrania.

    Po przejrzeniu postów na Elektrodzie i innych www zbudowałem poniższy układ w załączniku (PDF).

    Program napisałem a Bascomie ale NIESTETY NIE DZIAłA. Oto on

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 4000000                                          'kwarc 8MHz

    Config Timer0 = Timer , Prescale = 1                        'timer0 jako licznik do generowania 40kHz
    Config Timer1 = Timer , Prescale = 8                        'timer1 jako licznik do odliczania czasu powrotu fali
    Config Int1 = Falling                                       'przerwanie do sprawdzania odebrania odbitego impulsu
    '"0"-wejście "1"-wyjście
    Config Portb = &B111111                                     'wyświetlacz alfanumeryczny LCD
    Config Portd = &B11110111
    Portb = &B000000
    Portd = &B00001000

    Config Lcd = 16 * 1a                                        'wyświetlacz alfanumeryczny
    Config Lcdbus = 4                                           'podłączony przez szyne 4-ro bitową
    Config Lcdpin = Pin , Db4 = Portd.7 , Db5 = Portb.0 , Db6 = Portb.1 , Db7 = Portb.2 , E = Portd.6 , Rs = Portd.5
    Cursor On
    Cls

    Send Alias Portd.4
    Rec Alias Pind.3

    Dim L As Single
    Dim Period As Byte
    Dim Ok As Bit
    Dim Unit As String * 3
    Dim L_ok As String * 7

    Enable Interrupts
    Enable Timer0
    On Int1 Received
    On Timer0 Generate
    Stop Timer0
    Stop Timer1
    '**************************************************************
    Do
          Timer0 = 206
          Start Timer0                                          'w przerwaniach Timer 1 zmienaj stan na przetworniku czyli:





          Do
             If Period = 16 Then                                'wyslij impulsy o f=40kHz (8 okresów)
                Stop Timer0
                Period = 0
                Exit Do
             End If
          Loop

          Timer1 = 0                                            'wyczyść licznik odliczający czas i:
          Start Timer1                                          'zacznij odliczać do czasu wystąpienia przerwania z INT1(otrzymania impulsu odbitego)
          Waitms 5                                              'po wysłaniu czekaj czas nieczułości
          Enable Int1                                           'i sprawdzaj czy przyszedł odbity impuls

          Do
          Loop Until Ok = 1                                     'po odebranym impulsie...

          Ok = 0

          Wait 1                                                'poczekaj 1 sekundę
    Loop
    End                                                         'end program
    '**************************************************************
    Generate:                                                   'impulsy o f=40kHz
       Timer0 = 206
       Toggle Send
       Incr Period
    Return
    '**************************************************************
    Received:                                                   'po odebraniu odbitego impulsu, zmienna OK=1
       Disable Int1
       Stop Timer1
    '(
       L = Timer1 * 343                                         'czas odbicia razy prędkość dzwięku
          'L = L / 2                                             ' podzielić przez 2 bo fala biegnie do prszeszkody i spowrotem
       L = L / 1000000                                          'w metrach

       If L < 1 Then
          L = L * 100
          Unit = "cm "
       Else
          Unit = "m  "
       End If

       L_ok = Fusing(l , "#.##")                             
    ')
       Locate 1 , 1
       Lcd "Ultra  L"                                         
       Locate 2 , 1
       Lcd "=" ; Timer1 ; "   "                                 'L_ok ; Unit ; "  "

       Ok = 1
    Return
    '**************************************************************

    Na LCD ciągle wyświetlana jest stałą wartość z TIMER1, który odlicza czas powrotu odbitego impulsu. Impulsu generuje przez zmianę stanu na wyprowadzeniu PD.4 po każdym przerwaniu z Timer0(co 12,5µs, czyli pół okresu 40kHz).
    Czasami jak dotknę czujnika pracującego jako odbiornik wartość z Timer1 zmienia się.

    Odebrane impulsy wzmacniam w TL072 i wykrywam w komparatorze, który zmieniając stan wyjścia podaje zbocze opadające na wejście przerwania zewn. INT1 w obsłudze którego będę przeliczał odległość.

    W tej chwili nie jestem pewien czy to wina programu czy części analogowej. Proszę o podpowiedzi i uwagi co do tej konstrukcji. Z góry dziękuje.

    0 7
  • #2 23 Maj 2008 16:22
    elektrofil
    Poziom 17  

    będe zgadywał zupełnie na sucho, iz pomimo iz czekasz ileśtam czasu z zezwoleniem obsługi przerwania, to i tak występuje ono zawsze po zezwoleniu ponieważ Ty TYLKO ZEZWALASZ wtedy na obsługe a FLAGA jest USTAWIONA wcześniej.
    przed zezwoleniem na obsługe przerwania sugeruje zerowanie flagi wystapienia przerwania.
    ot taka mała sugestia związana z tym iż nie pamietam kiedy ostatnio pisałem jakikolwiek program który nie byłby na przerwaniach :)
    ps po obejrzeniu schematu według mnie to musi być przyczyną.

    0
  • #3 27 Maj 2008 20:53
    FastProject
    Poziom 28  

    Witam.
    Dzieki za podpowiedz, cos sie zmieniało po zerowaniu flagi ale nie zawiele. Ostatecznie program wyglada tak:

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 4000000                                          'kwarc 8MHz

    'Config Timer0 = Timer , Prescale = 1                        'timer0 jako licznik do generowania 40kHz
    Config Timer1 = Timer , Prescale = 8                        'timer1 jako licznik do odliczania czasu powrotu fali
    'Config Int1 = Falling                                       'przerwanie do sprawdzania odebrania odbitego impulsu
    '"0"-wejście "1"-wyjście
    Config Portb = &B111111                                     'wyświetlacz alfanumeryczny LCD
    Config Portc = &B0000
    Config Portd = &B11110111
    Portb = &B000000
    Portc = &B1100
    Portd = &B00001000

    Config Lcd = 16 * 1a                                        'wyświetlacz alfanumeryczny
    Config Lcdbus = 4                                           'podłączony przez szyne 4-ro bitową
    Config Lcdpin = Pin , Db4 = Portd.7 , Db5 = Portb.0 , Db6 = Portb.1 , Db7 = Portb.2 , E = Portd.6 , Rs = Portd.5
    Cursor On
    Cls

    Send Alias Portd.4
    Rec Alias Pind.3

    Dim L As Single
    Dim Period As Byte
    Dim Ok As Bit
    Dim Unit As String * 3
    Dim L_ok As String * 7

    Enable Interrupts
    'On Int1 Received
    Stop Timer1
    '**************************************************************
    Do
          'Timer0 = 206
          'Start Timer0                                          'w przerwaniach Timer0 zmienaj stan na przetworniku czyli:
          'Period = 0

          'Do
          For Period = 1 To 8                                   'wyslij impulsy o f=40kHz (8 okresów)
             Set Send
             Waitus 10
             Reset Send
             Waitus 10
          Next                                                  'Until Period > 15
          'Loop

          Timer1 = 0                                            'wyczyść licznik odliczający czas i:
          Start Timer1                                          'zacznij odliczać do czasu wystąpienia przerwania z INT1(otrzymania impulsu odbitego)
          Waitus 200                                            'po wysłaniu czekaj czas nieczułości
          'Gifr = 0
          'Ok = 0
          'Enable Int1                                           'i sprawdzaj czy przyszedł odbity impuls

          Do
             If Rec = 0 Then
                Stop Timer1
                Exit Do
             End If
          Loop                                                  'Until Ok = 1                                     'po odebranym impulsie...
          Gosub Received

          Wait 1                                                'poczekaj 1 sekundę
    Loop
    End                                                         'end program
    '**************************************************************
    Received:
          'Disable Int1
          'Stop Timer1

          L = Timer1 * 343                                      'czas odbicia razy prędkość dzwięku
          L = L / 1000000                                       'w metrach

          If L < 1 Then
             L = L * 100
             Unit = "cm "
          Else
             Unit = "m  "
          End If

          L_ok = Fusing(l , "#.##")
          Locate 1 , 1
          Lcd "Ultra L="
          Locate 2 , 1

          Lcd L_ok ; Unit
          'Ok = 1
          'Gifr = 0
    Return


    Okazalo sie ze z nieznanych mi powodów Timer0 nie mogł wygenerowac 40kHz. Fale nadawcza generuje dzieki Waitus a odbita wykrywam sprawdzajac stan pinu procesora.

    Z przebiegów na oscyloskopie niby wszysko sie zgadza fala zostaje wysłana i odebrana ale UKLAD REAGUJE TYLKO NA MAX 4CM OD CZUJNIKOW A POZNIEJ JUZ NIC NE GENERUJE I PROGRAM CHYBA STOI. Czasami jak nie ma przeszkody(jest saciana jakies 2m od czujnikow) TO UKLAD I TAK ODBIERA IMPULSY)

    Na obrazku
    [ATmega8][Bascom]Ultradzwięki-Badanie odległości z INT i Tim
    czerwony przebieg to fala wyslana a zołty to sygnal z kopmaratora podawany i wykrywany przez pin procesora.

    Co moze byc tego powodem? Podejrzewam ze zbyt male napięci na nadajniku (teraz jest okolo 23V-moe trzeba wiecej) juro to sprawdze.

    Prosze o wskazowki i porady-troszke mi sie spieszy...
    Dziekuje Pozdrawiam

    0
  • #4 27 Maj 2008 22:31
    elektrofil
    Poziom 17  

    -podaj proszę czas pomiędzy pierwszym zboczem nadawania a zboczem odbioru.]
    -czy czas odbioru sprawdzany na oscylu zależy od odległości przeszkody? <-najważniejsze.
    -odlutuj odbiornik i upewnij się że nie ma zboczu na odbiorze, czyli ze nie przechodzi po zasilaniu.

    jeżeli to jest ok, to dopiero sprawdzę program.

    0
  • #5 28 Maj 2008 17:14
    FastProject
    Poziom 28  

    Czas odbioru zależy od odległości ale niestety tylko w zakresie kilku centymetrów(około 4cm). Co dziwne prawie tylko jak mam podlączone sondy.Bez sond układ pokazuje 'zerową odległość' albo jakies pojedyncze losowe zmiany odleglosci,a co się dzieje to nie wiem. Podłączenie sond poprawia (ta na 4cm) odbiór.
    Bardzo możliwe ze to ma związek za zasialaniem.
    Dodam ze w procesorze wykorzystuje przetwornik ADC do pomiaru napięcia. Ale nie wiem czy to ma cos do siebie.

    Moze to wina zasilania i powadzenia masy(mam na całej płytce mase otaczającą scieżki jak na obrazku niżej.
    [ATmega8][Bascom]Ultradzwięki-Badanie odległości z INT i Tim

    Po odlutowaniu odbiornika zerowa odleglosc:( albo jakies losowe wartosci !!!

    0
  • #6 29 Maj 2008 13:05
    elektrofil
    Poziom 17  

    Code:

    $crystal = 4000000                                          'kwarc 8MHz

    4000000 to nie 8mhz popraw na 8000000

    druga drobna rzecz:
    Code:

    L = Timer1 * 343                                      'czas odbicia razy prędkość dzwięku
          L = L / 1000000                                       'w metrach

    trzeba podzielić przez 2 poniewaz to jest droga sygnału do przeszkody i z powrotem

    lecz najważniejsze pozbyć się powstawania sygnału bez podłączonego odbiornika.

    0
  • #7 29 Maj 2008 22:11
    FastProject
    Poziom 28  

    Witam kwarc jest 4 MHz i taki jest i dla niego sa wykonywane kalkulacje(to jest tylko komentarz z jakiegos innego programu).

    A co do wzoru to skoro Timer1 (dla kwarcu 4Mhz i podziału prescalera=8) jest zwiększany co 2us to juz nie muszę dzielić przez 2, a tylko wynik mnoże razy milion(1000000) aby miec gotowy wynik w metrach.Jak się myle to popraw mnie.

    0
  • #8 03 Lip 2008 20:56
    FastProject
    Poziom 28  

    udało mi się to wreszcie uruchomić. Na moim schemacie zabrakło diody która wyłączałaby komparator podczas i zaraz po wysyłaniu impulsów z nadajnika. Swój schemat odległościomierza oparłem na schemacie z strony http://www.interq.or.jp/japan/se-inoue/e_sonic1_1.htm . Jest tam dioda D3, której nie dodałem w swojej aplikacji. Teraz juz wszztko jest ok. Zasięg jaki udało mi się uzyskać to 20cm- do 3m. Pewnie da się wiecej ale nie sprawdzałem tego bo nie potrzebowałem więcej.

    Dzięki za pomoc. Temat uważam za zamknięty.

    0