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

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

FastProject 23 Maj 2008 10:19 5161 7
REKLAMA
  • #1 5171068
    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
    $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.
  • REKLAMA
  • #2 5172295
    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ą.
  • REKLAMA
  • #3 5188033
    FastProject
    Poziom 28  
    Witam.
    Dzieki za podpowiedz, cos sie zmieniało po zerowaniu flagi ale nie zawiele. Ostatecznie program wyglada tak:

    $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
  • #4 5188601
    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.
  • REKLAMA
  • #5 5190998
    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 !!!
  • #6 5193759
    elektrofil
    Poziom 17  
    
    $crystal = 4000000                                          'kwarc 8MHz
    

    4000000 to nie 8mhz popraw na 8000000

    druga drobna rzecz:
    
    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.
  • REKLAMA
  • #7 5195721
    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.
  • #8 5309002
    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.
REKLAMA