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

[ATMEGA328p-pu] - Błędny pomiar ADC

16 Lis 2014 18:09 1656 17
  • Poziom 11  
    Korzystam w swoim projekcie z przetwornika ADC. Jednak mam taki problem że źle mierzy wartości. Przekręcę potencjometr maksymalnie w lewo program wskazuje wartość 255, gdy przekręcę na połowę zakresu - 248. Przy kręceniu maksymalnie w prawo wartości spadają lawinowo do zera.
    Natomiast w innym programie wszystko działa poprawnie. Kopiowałem te same linijki kodu więc nie wiem co jest źle.
    Poprawne działanie w programie ADC238p, natomiast nie poprawne w BLDC_mega328p. W tym drugim pomiar jest przeprowadzony w bldc.c w przerwaniu.
  • Poziom 28  
    Witam.
    Czy ten potencjometr jest liniowy ?
  • Poziom 11  
    Cytat:
    Natomiast w innym programie wszystko działa poprawnie.

    Napisałem wyżej, tzn. jest linowy a zachowuje się jak logarytmiczny w tym właśnie programie BLCD. W programie ADC zachowuję się jak liniowy.
  • Poziom 11  
    Konkretnie co?
    Bo cały projekt opiera się właśnie o tę stronę, ale sam potencjometr to już moja inwencja.
  • Poziom 11  
    Dobra. Kod prezentuje się następująco:

    to jest program w którym wszystko działa jak potrzeba:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Teraz drugi program i w nim jest problem z działaniem potencjometru. Tutaj program główny:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    tutaj program bldc.c gdzie wykonuje pomiar ADC (w przerwaniu na samym końcu - case komut_7)
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    no i biblioteka do programu
    Kod: cpp
    Zaloguj się, aby zobaczyć kod
  • Poziom 9  
    Witam

    Spróbuj zmienić volatile int wynik=0 na volatile uint16_t wynik=0 w pliku bldc.c.
  • Poziom 11  
    Poprawiłem, niestety nie w tym błąd.

    Czy na taki niepoprawny błąd pomiaru wpływa to że pomiar jest realizowany w przerwaniu?
  • Moderator Mikrokontrolery Projektowanie
    W przerwaniu dodałeś funkcję:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    która zmienia ustawienia ADC, którego multiplekser używany jest do sterowania silnikiem. W którym miejscu kodu zadbałeś o ponowne przywrócenie właściwego ustawienia miltipleksera?

    To ma być to?:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Pomijam już uart_putlong() w przerwaniu, która zapewne ma pętle oczekujące itp.
    Uporządkuj kod i pokaż go po poprawkach. Monitoring wykonuj w pętli głównej, a w przerwaniu ustawiaj tylko jakąś zmienną globalną, którą monitoring wyśle uartem.

    Dopiero wtedy możemy próbować rozwiązać Twój problem.
  • Poziom 11  
    Funkcja
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    zapewnia jednokkrotny pomiar ADC.
    ponowne przywrócenie multipleksera było zrealizowane za pomocą
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    silnik się kręcił dalej, więc przerwania działały dobrze.

    No dobrze, poprawiłem kod i zmieniłem trochę koncepcję. Teraz pomiar nie będzie realizowany w przerwaniu, ale w pętli głównej, zaraz po tym jak nastąpi przerwanie od pierwszej komutacji o czym inforumuje
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Tera program main w którym odbywa się pomiar:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Program bldc.c gdzie są przerwania
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    i biblioteka bldc.h
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Bibliotek do UARTA nie wrzucam do są na pewno dobrze, robione ze stronki mirekk36.blogspot.com, tam wszystko działa.
    No i na koniec program o który się opierwałem z pomiarem ADC który DZIAŁA
    Kod: cpp
    Zaloguj się, aby zobaczyć kod
  • Poziom 11  
    coś znalazłem:
    zamieniłem te dwie linijki:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    na te:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    i pomiar jest ok. Pod PC5 mam potencjomert właśnie.
    Ale pojawił się inny. Silnik działa dobrze pomiędzy wartościami 130-255, poniżej takich się nie kręci, ale uwaga ! nawet jak nie używam zmiennej wynik jako wypełnienie PWM (!)
    Do tego jest teraz nieco głośniejszy - troszkę piszczy, można temu zaradzić?
  • Specjalista - Mikrokontrolery
    apollo1412 napisał:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Chyba nie panujesz nad tym co robisz.

    W pierwszej linii zerujesz bit PC5
    Druga linia powoduje, że tylko PC4 jest wyjściem i kompletnie zamazuje wszystkie wcześniejsze ustawienia rejestru DDRC.

    Doczytaj dobrze o operacjach bitowych w C i operatorach &=, |=, ~.
  • Poziom 11  
    Pin PC5 ustawiam jako wejście bez podciągniętego rezystora, a PC4 jako wyjście z podciągniętym z rezystorem.
    Może się nie zrozumięliśmy - PC5 ma być wyjściem dla potencjometru, ale wejściem do uC
  • Specjalista - Mikrokontrolery
    apollo1412 napisał:
    Może się nie zrozumięliśmy - PC5 ma być wyjściem dla potencjometru, ale wejściem do uC

    Ja wiem dobrze co chcesz osiągnąć.
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Jeszcze raz zastanów się nad poprawnością tych 4 linijek kodu! Zwłaszcza linii 2 i 4, przy takim zastosowaniu tych linii, linie 1 i 3 są zbędne i jeśli gdzieś wcześniej w programie już używałeś tego portu to ten zapis wszystko niszczy.

    W liniach 2 i 4 zwróć uwagę na znak "=" powinno być "|="
  • Poziom 11  
    Aha, tu widzisz problem, na razie tego wyjścia nie używam, korzystam z niego jako synlalizacyjne, ale nie w tej chwili, w takim razie napiszę po prostu
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    ale silnik dalej przestaje się kręcić przy małych wartościach adc, np. przy 50, ale kiedy podam sztywno wartość PWM_akt=50 to działa.
  • Poziom 11  
    Silnik przestaje się kręcić jeżeli skręcę potencjometr do zera
  • Moderator Mikrokontrolery Projektowanie
    apollo1412 napisał:
    Silnik przestaje się kręcić jeżeli skręcę potencjometr do zera

    A jak powinien zareagować?
  • Poziom 11  
    Przepraszam, źle się wyraziłem. Silnik przestaję się kręcić przy poniżej wypełnienia 150 przy pomiarze z potencjometru, natomiast przy ustawieniu na sztywno PWM_akt = 30 kręci się. Dodatkowo jeżeli wyniki pomiarów podzielę np. nie na 4 jak tu:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    a na 16 tak aby wynik był z przedziału 0-63 to silnik przestaje działać przy wartości 12.
    Może sposób pomiaru jest jednak nie właściwy? Nie zależnie jak ustawię skalowanie wyniku potencjometru, silnik przestaje się kręcić jeżeli skręcę potencjometr mniej więcej od 1/3 zakresu w dół.