Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 17 maja 2025, o 04:59


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 
    Autor Wiadomość
    PostNapisane: 2 maja 2024, o 21:45 
    Offline
    Nowy

    Dołączył(a): 02 maja 2024
    Posty: 5
    Pomógł: 0

    Cześć wszystkim,

    Piszę kod do mojego urządzenia do pomiaru odległości przy pomocy ultradźwięków, napotkałem jednak problem, gdyż podczas wykonywania się poniższego kodu nie otrzymuję wypisu na ekranie w Serial Monitorze. Kod jest napisany pod MCU Atmega328P zawarty w Arduino UNO. Korzystam z ArduinoIDE.
    Sygnał 40 kHz jest generowany na pinie PB2, z kolei odbierany jest na pinie PB5. Zamysł jest taki, że gdy zmienna time1 będzie większa od 16 to ma być załączona obsługa przerwania PCINT5, w funkcji jego obsługi ma być podstawiona wartość time1 do zmiennej time_wait. Po wykonaniu tego podstawienia ma być wyłączone przerwanie PCINT5, wstawione 0 do zmiennej time1 tak żeby kolejny pomiar zacząć od 0 i ustawione pozwolenie perm_on = 0. Pozwolenie umieściłem po to, aby kolejny pomiar zaczął się dopiero po wypisaniu poprzedniego na ekranie.

    Proszę o pomoc, naprowadzenie co robię źle.
    Dzięki :)

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 maja 2024, o 15:12 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 26 sty 2016
    Posty: 1170
    Lokalizacja: Kraków
    Pomógł: 93

    Ech, jak używasz arduino ide, to pisz jak w arduino ide.
    To, co przed while(1) wrzuć do setup(), a loop to już jest pętla nieskończona.

    Podziel problem na mniejsze części. Jesteś pewien, że działają przerwania?
    PCINT0 masz na PB0, nie na PB5.
    Nie mam czasu, żeby dokładniej analizować kod. Co używasz do mierzenia odległości? Dobrze podłączyłeś?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 3 maja 2024, o 20:32 
    Offline
    Nowy

    Dołączył(a): 02 maja 2024
    Posty: 5
    Pomógł: 0

    Zmodyfikowałem kod tak że teraz przerwanie PCINT5 jest już konfigurowane w setup i nie jest ono później wyłączane po prostu wewnątrz ISR(PCINT0_vect) jest warunek if ((time1 > 82) && perm_on) który pozwala na wyłapanie tylko pierwszej zmiany na pinie PB5 i zapisaniu czasu który upłynął od nadania sygnału w zmiennej time_wait. 8-)


    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Temat do zamknięcia.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 4 maja 2024, o 22:03 
    Offline
    Nowy

    Dołączył(a): 02 maja 2024
    Posty: 5
    Pomógł: 0

    A jednak coś się wykrzaczyło :oops:

    Wynik pomiaru ma być przedstawiony na wyświetlaczu LCD 2x16 z którym komunikacja przebiega po magistrali I2C.
    Jeśli skorzystam z Serial Monitora żeby wyświetlić wyniki to działa to bez problemu i otrzymuję wyniki na w ArduinoIDE w Serial Monitorze.
    Jeśli jednak chcę wykorzystać wyświetlacz LCD to wyświetla się na nim tylko:
    "Czas: 8750.00"
    "Odleglosc: 301.0"
    Nic się wogóle nie zmienia na wyświetlaczu. Wyświetlacz jest sprawdzony odpalałem na nim inny program, żeby go sprawdzić i wszystko było okej.
    Przy próbie zmiany pierwszego wypisu:
    lcd.print("Czas:");
    na
    lcd.print("Time:");
    Nic się nie zmienia na ekranie.
    Poniżej kod programu:
    // jest to gotowy program ultradzwiekowego miernika odleglosci
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27,16,2);
    volatile uint16_t time1 = 0;
    volatile uint16_t time_wait = 0;
    volatile uint8_t perm_on = 0;
    double czas_us = 0;
    double odleglosc = 0;
    // ISR informujący o niepoprawnej nazwie wektora
    ISR(BADISR_vect)
    {
    time1 = 25;
    }
    // ISR sterujący generowaniem paczki w odpowiednich momentach
    ISR(TIMER1_COMPA_vect)
    {
    time1++;
    if (time1 == 52000) //48000 kolejna paczka po 600 ms ( w tym czasie trzeba się wyrobić z wypisaniem na ekranie)
    {
    // Po osiągnięciu 48000 razy wartości TOP przez timer zmień stan bitu podłączającego/odłączającego OC1B na przeciwny
    TCCR1A |= (1 << COM1B0);
    // wyzeruj zmienną timer1
    time1 = 0;
    }
    if (time1 == 8 ) // 4 * 25us = 100 us ( time1 * 25 / 2 = czas paczki impulsów)
    {
    // Po osiągnięciu 12 razy wartości TOP przez timer zmień stan bitu podłączającego/odłączającego OC1B na przeciwny
    TCCR1A &= ~(1 << COM1B0);
    }
    }
    ISR(PCINT0_vect) {
    if ((time1 > 82) && perm_on) // jeśli odbiornik na początku łapie jakieś zakłócenie można zwiększyć time1 > x, odbędzie się to jednak kosztem minimalnej zmierzone odległości
    {
    time_wait = time1;
    perm_on = 0;
    }
    }
    void setup() {
    _delay_ms(500);
    // Rozpoczęcie transmisji szeregowej
    Serial.begin(9600);
    // Ustawienie PB2 jako wyjście
    DDRB |= (1 << PB2);
    // Ustawienie PB5 jako wejście
    DDRB &= ~(0 << PB5);
    // Wyczyszczenie poprzedniej zawartości rejestrów
    PCICR = 0;
    PCMSK0 = 0;
    // Załączenie przerwań dla PCINT7..0
    PCICR |= (1 << PCIE0);
    // Załączenie przerwania na pinie PB5 (PCINT5)
    PCMSK0 |= (1 << PCINT5);
    // Wyczyszczenie poprzedniej zawartości rejestrów
    TCCR1B = 0;
    TCCR1A = 0;
    // Tryb CTC
    TCCR1A |= (1 << COM1B0);
    // Prescaler: CS11 --> 8, CS10 + CS11 --> 64, CS12 --> 256
    TCCR1B |= (1 << WGM12) | (1 << CS11);
    // Wartość TOP
    OCR1A = 24;
    TIMSK1 |= (1 << OCIE1A);
    perm_on = 1;
    // Globalne włączenie obsługi przerwań
    sei();
    }
    void loop() {
    _delay_ms(350);
    lcd.clear();
    czas_us = (double)time_wait * 25 / 2;
    odleglosc = 0.0344 * czas_us; // Odleglosc w centymetrach
    Serial.println("Czas: ");
    Serial.println(czas_us , 4); // Wypisanie czasu w mikrosekundach (4 cyfry po przecinku)
    Serial.println("Odleglosc: ");
    Serial.println(odleglosc , 2); // Wypisanie odleglosci w centymetrach (2 cyfry po przecinku)
    lcd.setCursor(0,0);
    lcd.print("Czas:");
    lcd.setCursor(6,0);
    lcd.print(czas_us, 4);
    lcd.setCursor(0,1);
    lcd.print("Odleglosc:");
    lcd.setCursor(11,1);
    lcd.print(odleglosc, 2);
    perm_on = 1;
    return(0);
    }
    Co może być przyczyną takiego zachowania programu? Gdzie szukać przyczyny? Proszę o pomoc w tym temacie.

    ------------------------ [ Dodano po: 5 minutach ]

    Czy byłoby możliwe, że przerwanie ISR(TIMER1_COMPA_vect) lub ISR(PCINT0_vect) przychodzi tak szybko, że dane nie zdążą być przesłane do wyświetlacza?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 maja 2024, o 10:46 
    Offline
    Nowy

    Dołączył(a): 02 maja 2024
    Posty: 5
    Pomógł: 0

    Używam biblioteki LiquidCrystal_I2C.h w wersji 1.1.2 do obsługi wyświetlacza po I2C:
    htps://github.com/johnrickman/LiquidCrystal_I2C
    Jako nowy użytkownik nie mogę wstawiać linków, powyżej trzeba zmienić htps na https.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 5 maja 2024, o 11:53 
    Offline
    Nowy

    Dołączył(a): 02 maja 2024
    Posty: 5
    Pomógł: 0

    Brakowało mi lcd.init() w setup(). Teraz działa.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 19 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO