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



Teraz jest 5 gru 2024, o 04:11


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 12 ] 
Autor Wiadomość
PostNapisane: 17 lip 2014, o 10:57 
Offline
Nowy

Dołączył(a): 15 sty 2014
Posty: 11
Pomógł: 0

Witam,

Buduję rejestrator ADC z zapisem/odczytem na kartę SD.Układ oparty jest na procesorze Atmega 1284P. Taktowany jest zewnętrznym kwarcem 16MHz. Cały układ pracuje na napięciu 5V poza kartą SD (zasilanie 3.3V + 74LCV125D). Od strony elektronicznej-hardware'owej wszystko pracuje prawidłowo, problemem jest oprogramowanie.

Urządzenie składa się z wyświetlacza, potencjometrów (ADC), przycisków zrobionych na drabince rezystorów oraz podświetlania przycisków za pomocą diód led.
Wyświetlacz 4x40 i podświetlanie przycisków mam zrobione na 3 rejestrach przesuwnych. Dane wysyłam za pomocą sprzętowego SPI.

Na sprzętowym SPI mam również podłączoną kartę SD, na którą chciałbym zapisywać dane.
Na karcie SD chciałbym rejestrować sygnał z 5 kanałów ADC w krótkich odstępach czasowych( np. co 1ms – zależy mi na dokładności) i zapisywać je na karcie SD w formacie .csv. Później chciałbym te dane odtwarzać i sterować wypełnieniem wyjść PWM z taką samą prędkością jak zapis nie zakłócając tym samym pracy wyświetlacza, czy też podświetlania klawiszy.

Udało mi się zainicjować bibliotekę FatFS od Elm-chana. Przetestowałem ją i działa mi zapis na kartę, jak również odtwarzanie na przykładzie ze strony elm-chana z konsolą po RS232.

Poradziłem sobie z odpaleniem wszystkiego razem, działającym przełączaniem kanałów SPI, LCD przyciski itp.
Wszystko działa poza poprawnością zapisu z buforów na kartę.

Szczegółowe założenia jakimi się kierowałem:
Chciałbym zapisywać wartości poszczególnych kanałów adc w przerywaniach ADC do buforów. Gdy skończy się zapis danych z kanałów adc do bufora 1 rozpoczyna się zapis na kartę SD z bufora 1 i w trakcie zapisu na kartę wykonywany jest zapis wartości adc do bufora 2. Gdy skończy się zapis na kartę SD z bufora 1 następuje zapis na kartę z bufora 2 oraz zapis wartości z adc do bufora 1. No i tak w kółko dzięki ustawianiu odpowiednich flag o przepełnieniu bądź o zezwoleniu na zapełnianie się poszczególnych buforów.
W tym celu stworzyłem przykładową ramkę danych buforów o rozmiarze 512 w których zapisywane mają być wiersze/pomiary - (493 komórki) wyglądające w następujący sposób:

Obrazek

Aktualnie zapis działa jednak w taki sposób, że gdy kręcę potencjometrem wartości adc zmieniają się w zapisie co 17 wierszy (czyli co bufor) skokowo choć czasem zdarzy się zapis różnych wartrości w 17 pomiarach w buforze 1 lub 2 . Chciałbym uzyskać w poszczególnych wierszach bufora również wartości pomiędzy tymi skokami. Poniżej przykład zapisywanych danych obecnie:

Obrazek

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

Pomiędzy kanałami ADC przełączam się po przez funkcję switch(channel) w przerywaniach od ADC. Przełączanie i zapisywanie do zmiennych adc0,adc1,adc2...itd działa poprawnie.

Mam wrażenie, że przerywania (od ADC) za szybko zapełniają bufory.
Zależy mi na zapisie ok 1000 wierszy danych na sekundę lub więcej nie tracąc wartości pośrednich tak jak dzieje mi się teraz.

Proszę Was o odpowiedz na pytania:
Kiedy zapisywać dane do buforów i gdzie najlepiej to wykonywać czy w przerywaniach czy w pętli głównej?
Jeśli w przerywaniach to: Czy zapełnianie bufora 1 i 2 mam wykonywać w przerywaniach od ADC czy np od Timera?
Czy przetwornik ADC powinien być ustawiony w tryb Free Running Mode?(gdzieś na forach znalazłem taką podpowiedź)
Myślałem również nad buforami kołowymi i kolejkach FIFO....ale nie wiem czy w moim przypadku jest to konieczne.


Bardzo proszę o wskazówki i pomoc.
P.S.
Przeglądałem projekt Pana Mirka - Wav recordera i wiem, że prędkość z częstotliwością 1kHz jest jak najbardziej osiągalna.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 lip 2014, o 20:12 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

Payfer napisał(a):
Mam wrażenie, że przerywania (od ADC) za szybko zapełniają bufory.

Atmega 1284 ma 16KB pamięci RAM możesz zwiększyć liczbę buforów. Problemem może być długi zapis bufora na kartę. Nie chodzi mi tutaj o sam fakt wysłania przez SPI, ale o fizyczny zapis w pamięci Flash karty SD: http://elm-chan.org/docs/mmc/mmc_e.html

Payfer napisał(a):
Kiedy zapisywać dane do buforów i gdzie najlepiej to wykonywać czy w przerywaniach czy w pętli głównej?
W przerwaniach. To krótka operacja.
Payfer napisał(a):
Jeśli w przerywaniach to: Czy zapełnianie bufora 1 i 2 mam wykonywać w przerywaniach od ADC czy np od Timera?
W przerwaniu ADC. Skoro wynik jest gotowy to należy go skopiować.
Payfer napisał(a):
Czy przetwornik ADC powinien być ustawiony w tryb Free Running Mode?(gdzieś na forach znalazłem taką podpowiedź)
W trybie Free Running osiągniesz najwyższe prędkości, ale nie masz wtedy dokładnego sterowania co ile zrobić pomiar. Można wykorzystać tryb CTC timera, który będzie wyzwalał pomiar. Przykładowy kod niezwiązany z tematem takiego ustawienia:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Payfer napisał(a):
Myślałem również nad buforami kołowymi i kolejkach FIFO....ale nie wiem czy w moim przypadku jest to konieczne.
To się tutaj nie nadaje. Do zapisu na kartę potrzebujesz blok danych i bufory to dobre rozwiązanie. FIFO mógłbyś wykorzystać do ciągłego wysyłania tych pomiarów na port szeregowy.


Autor postu otrzymał pochwałę

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 wrz 2014, o 18:40 
Offline
Nowy

Dołączył(a): 15 sty 2014
Posty: 11
Pomógł: 0

Po Twoich wskazówkach próbowałem samodzielnie udoskonalić działanie programu. Jednak mimo moich usilnych prób nic z tego nie wychodzi. Dalej zapisuje skokowo.

Główny problem najprawdopodobniej polega na traceniu się wyników pomiędzy przełączaniem się na kolejny bufor. Kolejnym problemem może być choć nie musi sposób wysyłania danych przez SPI. Na jednym sprzętowym SPI jest Karta SD + bufor 74LCV125D oraz 3 rejestry przesuwne 74HC595, do których podłączone są diody oraz wyświetlacz 4x40. Zatrzask dla rejestrów przesuwnych jest na pinie PA7 natomiast CS dla karty jest na pinie PB4.

W moim miasteczku nie ma raczej osoby, która interesowałaby się programowaniem mikrokontrolerów w C. Stąd moja ogromna prośba o zdalną pomoc.

Poniżej program główny:
Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Bardzo proszę o pomoc w przeanalizowaniu problemu.
Z góry bardzo dziękuję za chęć pomocy i poświęcony czas.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 wrz 2014, o 12:22 
Offline
Nowy

Dołączył(a): 15 sty 2014
Posty: 11
Pomógł: 0

Proszę o odpowiedz lub wskazówki.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 wrz 2014, o 20:47 
Offline
Użytkownik

Dołączył(a): 05 lut 2013
Posty: 302
Pomógł: 19

Nie umiem Ci pomoc techniczne. Dam tylko rade, skoro podejrzewasz ze problemem jest "przeciazenie SPI" to moze zbuduj prototyp gdzie SPI bedzie wykorzystywane tylko do zapisu na karte.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 wrz 2014, o 09:45 
Offline
Nowy

Dołączył(a): 15 sty 2014
Posty: 11
Pomógł: 0

Jeśli SPI wykorzystuje jedynie na transmisję z kartą SD, problem dokładnie ten sam. Także mogę podejrzewać, że SPI jest dobrze skonfigurowane i problem może tkwić gdzieś indziej.

------------------------ [ Dodano po: 4 minutach ]

Odnośnie programu, który zawarłem w poście powyżej to chodziło mi o sprawdzenie tylko paru funkcji odnośnie zapisu.

Czy mam poprawną konfigurację ADC?
Czy funkcje "adcinttostr_buf..." zapełniania poszczególnych buforów jest poprawna? Czy konwersja z int na string ma odbywać się tak często?
Czy funkcja "zapis" służąca do przełączania pomiędzy kolejno zapychającymi się buforami jest poprawnie napisana?
Czy funkcja "FatFS_Write" wywoływana jest w odpowiednim miejscu?
Czy funkcja switch do przełączenia się kanałów ADC w przerywaniu od ADC jest poprawna oraz czy warunek (while(ADCSRA & (1<<ADSC));) o zakończonej konwersji Analog Cyfra jest poprawny?
Czy konfiguracja timerów i innych peryferiów jest poprawna?

Między innymi na te pytania chciałem otrzymać odpowiedź....
A wkleiłem cały program żeby nie wklejać osobno poszczególnych funkcji.

Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 wrz 2014, o 10:11 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

Payfer napisał(a):
Jeśli SPI wykorzystuje jedynie na transmisję z kartą SD, problem dokładnie ten sam. Także mogę podejrzewać, że SPI jest dobrze skonfigurowane i problem może tkwić gdzieś indziej.

Wydawało mi się, że napisałeś gdzieś, że zapis na kartę uruchomiłeś i wszystko działa...
To jak to w końcu jest?
Dlatego właśnie sugerowałem, żebyś podzielił projekt i kod "na kawałki".
Najpierw sama komunikacja z kartą.
Potem dopiero cała reszta. I to też nie wszystko na raz. Tylko stopniowo coraz więcej.

Powtórzę jeszcze raz:
Trudno jest analizować czyjś liczący ponad 1000 linii kod.

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 wrz 2014, o 11:43 
Offline
Nowy

Dołączył(a): 15 sty 2014
Posty: 11
Pomógł: 0

Wszystko razem działa ale nie tak jak należy, bardziej chodziło mi o sam fakt, że udało się to odpalić razem.
Jeśli próbuję tylko sam zapis na kartę SD (przy wyłączonym LCD i rejestrami przesuwnymi) sytuacja jest identyczna - skokowy zapis.
A co do podziału projektu na części...To w taki sposób budowałem ten program. Najpierw chciałem, żeby to odpaliło wszystko razem a później dopiero zauważyłem, że coś jest nie tak z płynnym zapisem, przełączaniem się buforów. Pisałem to na różne sposoby ale to nie przynosiło rezultatu...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 wrz 2014, o 12:45 
Offline
Użytkownik

Dołączył(a): 24 sty 2012
Posty: 1469
Pomógł: 56

Skoro nie "dotestowałeś klocków" to sam widzisz, że trzeba znów rozłożyć problem
na części składowe i od początku zacząć testować poszczególne elementy.
A nie tak jak teraz chcesz zrobić, że cały program. I tłumaczenie, że Ty chcesz tylko
żeby Ci w tym kodzie malutkie fragmenciki sprawdzić :(
No niestety nie ma innej drogi ;)

_________________
Jestem początkujący i moje porady mogą być błędne



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 wrz 2014, o 14:42 
Offline
Użytkownik

Dołączył(a): 05 lut 2013
Posty: 302
Pomógł: 19

zaraz zaraz, czy ty przypadkiem nie mieszasz dwoch sposobow obslugi ADC?

ISR(ADC_vect) - zazwyczaj uzywane we free runing
while(ADCSRA & (1<<ADSC)) - zazwyczaj uzywane w single conversion

kolejna i chyba wazniejsza sprawa, w jaki sposob kontrolujesz zeby odczyt ADC do kolejnego bufora byl co 10ms?
Czytalem kod pobieznie (sorry, ale formatowanie kodu, ilosc zbednych funkcji, flag, nie ulatwia tego zadania) i nic nie wskazalo zebys pilnowal czasu odczytu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 wrz 2014, o 08:49 
Offline
Nowy

Dołączył(a): 15 sty 2014
Posty: 11
Pomógł: 0

Rozumiem, że dokładniejsze będzie wykonywanie pomiarów ADC w trybie "ręcznym".
Czy Timer 0 powinien więc być skonfigurowany więc w następujący sposób:?
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


A inicjalizacje ADC konfigurować w taki sposób?:

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


Czy w przerywaniu ISR(ADC_vect) wykonywać kopiowanie wyników konwersji do poszczególnych buforów?
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czy w przerywaniach od Timera0 powinna być funkcja switch przełączająca pomiędzy poszczególnymi kanałami ADC?
Czy ustawienie w rejestrach ADC powoduje automatyczne rozpoczęcie i zakończenie konwersji?

Czy ma o wyglądać tak?:
Składnia: [ Pobierz ] [ Ukryj ]
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: 24 wrz 2014, o 11:35 
Offline
Użytkownik

Dołączył(a): 05 lut 2013
Posty: 302
Pomógł: 19

i dalej to samo. po co ci przerwanie ADC?!?!?! jak rownoczenie chcesz czekac na zakonczenie konwersji uzywajac:
while(ADCSRA & (1<<ADSC)); ?

czytales moj post w ogole?

zrob tak:
- wywal z ADC obsluge przerwan
- zrob timer 10 ms (czy co ile potrzebujesz odczytywac, dla bezpieczenstwa na poczatek proponuje wieksza wartosc, np 100ms)
- w timerze zrob:
1) wybierz bufor do ktorej zapisujesz
2) przelec przez wszystkie kanaly admuxa ktore chcesz odczytac uzywac recznego odczytywania*
3) zaznacz ze bufor jest gotowy do zapisywania.

flaguj tez sobie (moze robisz, nie wiem) czy dany bufor zostal juz zapisany na karte SD i dopiero wtedy go 'zwalniaj do zapisywania'.

*reczne odczytywanie:
ustawienie kanalu
start konwersji
while(czekaj_az_skonczy_sie_konwersja).

ps. disk_timerproc();//do obsługi karty SD - zalecane jest co 10ms a wedlug komentarza masz timer ustawiony na 1ms.



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: 12 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

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


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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO