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

ATtiny 2313 - Czujnik odległości HC-SR04 - błąd w programie

bednarus3 08 Sty 2014 23:49 3618 12
  • #1 13155299
    bednarus3
    Poziom 17  
    Dzień dobry.
    Zbudowałem miernik odległości w oparciu o ATtiny2313, czujnik HC-SR04 i wyświetlacz LED 7 segmentowy 4 cyfrowy, wspólna katoda. Program napisany w języku C w Atmel Studio.
    Problem polega na tym, że układ działa poprawnie tylko do odległości 70 cm. Powyżej zaczynają migać segmenty, na cyfrze jedności i dziesiątek, które nie powinny się zapalać. Do tego na cyfrze setek w tym samym czasie miga 1. Od 100 do 106 cm znów liczyło poprawnie. Dalej znowu migały inne segmenty. Odległość jednak można odczytać, ale tylko do około 170 cm. Powyżej tylko od czasu widać poprawną odległość. Jak wyświetlam po kolei 0000, 1111, ... , 9999, to wszystko wyświetla się poprawnie.
    Cały kod jest pisany przeze mnie. Gdzie popełniam błąd?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Dziękuję
    Michał
  • #2 13155416
    Konto nie istnieje
    Poziom 1  
  • #3 13159348
    bednarus3
    Poziom 17  
    Poprawiłem obsługę wyświetlacza. Mam nadzieję, że teraz jest poprawnie. Niestety pomiar odległości dalej nie działa jak należy. Do 50cm jest w porządku. Powyżej zaczynają skakać segmenty wyświetlacza, ale wynik jest prawidłowy. Po przekroczeniu 100 cm na wyświetlaczu robi się dyskoteka oraz odległość jest nie do odczytania. Od dłuższego czasu z tym walczę i nie mogę dojść w czym rzecz.

    Plik main.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Plik led_dsp.c - obsługa wyświetlacza
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Plik led_dsp.h
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Plik sensor.c - obsługa czujnika HC-SR04
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Plik sensor.h
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #4 13160823
    Konto nie istnieje
    Poziom 1  
  • #5 13171618
    bednarus3
    Poziom 17  
    Przeniosłem to dzielenie modulo do pętli głównej. Nad optymalizacją myślę, ale jeszcze nic nie przyszło do głowy. Niestety brak zmiany w działaniu układu. Ewidentnie mikrokontroler idzie w buraki, bo migają nawet kropki, które nigdzie w kodzie nie są używane. Przeniosłem również funkcję trigger do pętli głównej. Dodatkowo zmieniłem obsługę wyświetlacza. Zamiast 4 x if() jest:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a w pętli głównej.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Przeniosę jeszcze funkcję abs z procedury obsługującej przerwanie od ICP do pętli głównej.
  • #6 13171699
    Konto nie istnieje
    Poziom 1  
  • #7 13174543
    bednarus3
    Poziom 17  
    ATtiny 2313 - Czujnik odległości HC-SR04 - błąd w programie ATtiny 2313 - Czujnik odległości HC-SR04 - błąd w programie

    Pracuję na "żywym układzie" wytrawianym i polutowanym w domu. Istotne jest to, że na płytce stykowej tak samo się zachowywał. Myślałem, że to wina słabych połączeń tych kabelków z płytką, ale po wykonaniu obwodu drukowanego, niestety nic się nie zmieniło. Z symulatorem pracowałem, ale nie radzę sobie, jeżeli chodzi o przerwania. Muszę się dokształcić.

    Kod:
    main.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    led_dsp.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    led_dsp.h
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    sensor.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    sensor.h
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 13175094
    kicajbas
    Poziom 32  
    Witam
    Może mało istotny szczegół: brak rezystora Vcc/RESET a do stabilizatora dodałbym jakieś małe elektrolity

    Pozdr.
  • #9 13175244
    bednarus3
    Poziom 17  
    Nie dałem rezystora podciągającego na reset świadomie, bo ponoć ATTiny ma wewnętrzny rezystor podciągający na tej nóżce.
  • #10 13175272
    kicajbas
    Poziom 32  
    Witam
    Szczerze; nie wiedziałem o tym rezystorze, ale jak go ustawiasz jeśli jest to "ostateczne" WE/WY i też jest w pełni konfigurowalne? A z drugiej strony oszczędność jednego rezystora w oparciu o "ponoć" w zamian za głupiejący reset?.
    Pomyśl też o tej filtracji zasilania.
    Pozdr.
  • #11 13177545
    bednarus3
    Poziom 17  
    Nie rozumiem jednej rzeczy. T0 ma preskaler ustawiony na 64 co daje częstotliwość taktowania 62500Hz, czyli T0 zwiększa swoją wartość co 0,000016s = 16us. Chcę mieć przerwanie CTC co 2ms = 0,002s. Czyli licznik musi doliczyć do 125 (0,002 / 0,000016 = 125). Według powyższego dla testu zrobiłem tak:
    W przerwaniu CTC inkrementuję wartość zmiennej sample. W pętli głównej wyświetlam wartość zmiennej test. W momencie kiedy sample osiągnie 500 to inkrementuję zmienną test. Spodziewałem się, że wyświetlana liczba będzie się zwiększać o 1 co 1 sekundę, a tym czasem zwiększa się co około 2 sekundy. Gdzie tkwi błąd?
  • #12 13178008
    Konto nie istnieje
    Poziom 1  
  • #13 13178350
    bednarus3
    Poziom 17  
    adn. 0. Masa to jest pozostałość po pierwotnym pomyśle na realizację wyświetlacza. Miał być sterownik wyświetlacza LED z kodu BCD do 7-segmentowego. Teraz tak naprawdę jest to pin wolny, bo żadna nóżka, jakiegokolwiek elementu nie jest podłączona do masy. Dlatego nie było potrzeby łączyć tego pinu do masy na schemacie ATtiny. Struktura złącza nie jest taka sama, przez niechlujstwo, ale logiczne połączenia pomiędzy mikrokontrolerem a wyświetlaczem są zachowane nóżka PB0 --> segment A ... PB6 --> segment G.
    adn. 1. Dziękuję, godzinami bym szukał tego błędu. Już poprawione.
    adn. 2. Funkcja trigger została przeniesiona do pętli głównej w main.c. i wykonywana jest gdy sample osiągnie 50. W tym samym warunku do sample wpisywane jest 0.
    adn. 5. Dla przetestowania, co 100ms wyświetlam losowe cyfry na wyświetlaczu. Wszystko prawidłowo, żadne kropki nie mrugają. Ale to mi dało do myślenia. Zadeklarowałem uint16_t test i wykorzystałem w kodzie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Natomiast tablica digits_to_display jest uint8_t, czyli próbowałem wepchnąć int do char. W efekcie migały kropki i wyświetlacz zgłupiał. Po zmianie wyświetlało prawidłowo. W wolnej chwili sprawdzę kod pod tym kątem. Może gdzieś, w pewnej sytuacji, program próbuje wcisnąć do zmiennej więcej bitów niż zostało jej przydzielonych.

    Edit:
    Dodałem do programu zerowanie licznika T1 przed wywołaniem funkcji triger. Miganie niepożądanych segmentów wyświetlacza ustało. Gdy zeruję licznik przed pomiarem on się nigdy nie przepełnia. Domyślam się, że przyczyną jest, po przepełnieniu, wpisywanie do zmiennych wartości przekraczających ich zdefiniowany w typie zakres. Tylko jeszcze nie wiem, czy chodzi o rozmiar, czy o znak.
REKLAMA