• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Niedokładność pomiarowa - problem z odczytywaniem impulsow
#41
Ostatecznie zadecydowałem, ze napisze program od nowa bo sam się już trochę w tym gubiłem (co chwile dodawałem coś nowego). Pomiary będę robił za pomocą przerwań, zarówno pomiar prędkości jak i czasu działania wtrysków.
Udało mi się tez uruchomić sprzętowy timer, którym co pół sekundy będę wywoływał funkcje wykonujące najważniejsze obliczenia. Ich wyniki będę zapisywał do zmiennych globalnych, wyświetlanie ich odkoduje w pętli głównej Smile

Praca nad tym zajmę się za tydzien, ponieważ wyjezdzam teraz na kilka dni. Wieczorem zamieszczę jeszcze kawałek kodu bo cześć odpowiedzialna za pomiar prędkości już mam.
 
Odpowiedź
#42
(20-08-2018, 11:27)qbic napisał(a): Ostatecznie zadecydowałem, ze napisze program od nowa bo sam się już trochę w tym gubiłem (co chwile dodawałem coś nowego). Pomiary będę robił za pomocą przerwań, zarówno pomiar prędkości jak i czasu działania wtrysków.
Udało mi się tez uruchomić sprzętowy timer, którym co pół sekundy będę wywoływał funkcje wykonujące najważniejsze obliczenia. Ich wyniki będę zapisywał do zmiennych globalnych, wyświetlanie ich odkoduje w pętli głównej

Słuszny kierunek. Jeszcze trochę i dojdziesz do tego, że Arduino do niczego sensownego się nie nadaje i zaczniesz używać "normalnych" narzedzi.

Zrób pseudo wielopoziomowy system przerwań. Przerwania liczące prędkość i czas wtrysku deklaruj jako SIGNAL lub ISR bez atrybutów. Przerwanie od timera co pół sekundy, w którym wykonujesz obliczenia, deklaruj jako INTERRUPT lub ISR z atrybutem ISR_NO_BLOCK czy jakoś tak
 
Odpowiedź
#43
Wróciłem z wyjazdu i wracam do projektu.

Co do części odpowiedzialnej za pomiar prędkości, o ktorej wspominałem - zmienna przechowujaca chwilową prędkość ma coś na kształt overflow przy wartosci 38. Nie mam pojęcia dlaczego się tak dzieje, a blokuje to dalsza pracę.

Kod dodaje za posrednictwem zewnetrznego portalu, mam nadzieje, że poprawi to komfort czytania go.
 
Odpowiedź
#44
(26-08-2018, 12:34)qbic napisał(a): Kod dodaje za posrednictwem zewnetrznego portalu, mam nadzieje, że poprawi to komfort czytania go.

Tyle, że link nie działa. Nic dziwnego, źródło strony pokazuje
Kod:
czytania go.]Kod[/url] dodaje z
 
Odpowiedź
#45
Rzeczywiście, edytowałem post, link powinien działać.
 
Odpowiedź
#46
Użyj trybu CTC dla timera 1.
Jak już używasz (co nie jest rozsądne) zliczania od okeślonej wartości do przepełnienia, to licznik powinieneś ładować w przerwaniu na jego początku a nie końcu. Przy małym podzielniku trzeba by jednak uwzględnić czas jaki minie zanim wejdziesz w przerwania (czas ten jest nieznany. bo może akurat obsługiwane jest inne przerwanie) i czas jaki jest poświęcony na odłożenie rejestrów na stos (ten czas mozna obliczyć). Można tez dać wstawkę ASM i załadować rejestr TCNT1 zaraz po wejściu w przerwanie (niestety musisz w ASM odłożyć co nieco na stos).
Po co więc kombinować, użyj CTC.
W przerwaniu zmieniaj sobie jakieś GPIO i sprawdź czy masz przerwanie dokładnie co 500ms.
Z obliczeń w przerwaniu zrób tylko coś w rodzaju:
Kod:
zliczne impulsy = speedImpulseCounter;
speedImpulseCounter = 0;

Resztę obliczeń rób w petli głównej.
 
Odpowiedź
#47
Wiem, że w poprzednich postach była mowa o pomiarze prędkości, jednak od czasu ostatniej odpowiedzi pracowałem nad zwiększeniem dokładności pomiaru długości impulsów wtryskiwaczy. Udało mi się osiągnąć dokładność 1us (mógłbym więcej ale nie wiem czy jest sens). Użyłem inputCaptureMode Timera3, długo walczyłem z rejestrami i wszystkim co z nimi związane ale udało się (mam nadzieje!) Smile

https://pastebin.com/b4AjmyKn

Kod ten to jedynie obsługa inputCaptureMode, koncowy wynik czasu jednego impulsu jest przesyłany do loop'a.
Prosiłbym o zerknięcie na ten kod, wydaje mi się, że wszystko działa jednak brak mi doświadczenia więc pewny być nie moge.
 
Odpowiedź
#48
(05-09-2018, 20:40)qbic napisał(a): Udało mi się osiągnąć dokładność 1us (mógłbym więcej ale nie wiem czy jest sens). Użyłem inputCaptureMode Timera3, długo walczyłem z rejestrami i wszystkim co z nimi związane ale udało się (mam nadzieje!) Smile

Nie dokładność 1us ale rozdzielczość. Max na Arduino z AVR to 62,5ns, zmieniając taktowanie na 20MHz to 50ns.

Przewiduję, że niedługo przestaniesz bawić się Arduino, bo jak widzisz, aby zrbić cokolwiek sensownego, trzeba poznać architekturę uC i działać na rejestrach bo nie ma możliwości korzystania z "dobrodziejstw" Arduino. To samo jest w Bascom, który "umiera", Arduino, też kiedyś umrze i dobrze, bo założenia Arduino były inne a wszystko poszło w innym kierunku. Nie Arduino, daje możliwość debugowania kodu, a to przyspiesza prace kilka a nawet kilkanaście razy. W małym projekcie, czy robisz tydzień czy miesiąc nie ma znaczenia, w większym, różnica miesiąc a rok już jest zauważalna. Jak to jest praca zarobkowa, to bez debugera na chleb nie zarobisz.

W kodzie masz:
Kod:
(startOverflowCounter * 65536)
Zastąp to przez mniej pamięciożerne i dziesiątki jak nie setki razy szybsze:
Kod:
(startOverflowCounter << 16)
Sprawdź jednak czy działa. W AVR GCC (G++) przesuwanie w lewo działało poprawnie tylko w granicy 16 bitów, nie było przeniesienia z bitu 15 na 16, w konsekwencji, starsze słowo było obcinane. Jeśli nadal tak jest, mogę dać Ci kod omijający ten problem. GCC dla AVR ma jeszcze bardzo dużo takich "kwiatków". To było głównym powodem, dla którego przeszedłem na ARM i Tobie też to radzę. Trzeba być dobrym ekspertem, aby na AVR pisać bardziej skomplikowane programy, na ARM jest dużo łatwiej.
 
Odpowiedź
#49
Zapewne jest tak jak mowisz, im dalej z szlifowaniem umiejętności operacji na rejestrach i bitach tym bardziej to doceniam. Musisz jednak przyznać ze nie jest to tak oczywiste jak arduino, dzięki któremu zainteresowałem się wogole tematem mikrokontrolerow - i za to cenie idee całego projektu arduino.

Powracając do tematu kodu, zrobię tak jak napisałeś. Widzisz jeszcze jakieś miejsca w których mógłbym odciążyć kod?
 
Odpowiedź
#50
(05-09-2018, 21:53)qbic napisał(a): Widzisz jeszcze jakieś miejsca w których mógłbym odciążyć kod?

Wymagało by to dokładnej analizy kodu. Na szybko to:
Kod:
int result = timer3Clocks / 16;
zastąp przez:
Kod:
int result = timer3Clocks << 4;
Sprawdź jednak wcześniej, w rozwinięciu ASM (tu Arduino jest wyjątkowo nieprzyjazne), czy kompilator nie użył przesuwania zamiast mnozenia.

Zamiast
Kod:
1 << ICES3
wygodniejsze może byc macro
Kod:
_BV(ICES3)
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości