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


Ocena wątku:
  • 1 głosów - średnia: 1
  • 1
  • 2
  • 3
  • 4
  • 5
Odczyt wartości Timera1 - problem.
#41
Chyba już wiem skąd tak dziwne zachowanie układu. Wygląda na to że winowajcą jest AD9850.
To bardzo ciekawy układ, ale jak przystało na DDS syntetyzuje sygnał z przebiegów sinusoidalnych. Więc ten "prostokąt" nie jest do końca prostokątny, ale suma sinusów.

Okazało się że w szafie z przydasiami znalazłem moduł AD9850 Smile Podłączając do Arduino mam dokładnie takie same objawy, czyli reakcję na oba zbocza.
Z ciekawości podłączyłem oscyloskop:
   

Niby wszystko fajnie, ale widać że wyzwalanie wariuje, natomiast samo zbocze już idealne nie jest:
   
   

To chyba wyjaśnia dlaczego układ widzi dwa zbocza, a nie jedno.
 
Odpowiedź
#42
Łomatko z córką, no to faktycznie dramat.
Jak żyć ? !
 
Odpowiedź
#43
Problem rozwiązany, dzięki Elwis, pokombinowałem z kondensatorami, pojemnościami, równolegle szeregowo i jest rewelacja ! 
Oto wyniki, dla 200Hz
Kod:
Roznica: 5008
Roznica: 5004
Roznica: 5012
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5012
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004
Roznica: 5008
Roznica: 5004

No nic, działam dalej Smile
 
Odpowiedź
#44
No właśnie o to mi się rozchodziło co podglądnął elvis. Pisałem o tym w # 37 "Przyglądnij się czy na zboczach nie ma oscylacji."
 
Odpowiedź
#45
(10-03-2020, 21:56)Robson Kerman napisał(a): Napisałem kiedyś dla kolegi z forum taki prosty licznik.
Jest dosyć dokładny,
Jak może być dokładny licznik programowy w dodatku używający millis gdzie pewne wartości się nigdy nie pojawiają?
Jakie częstotliwości i z jaką dokładnością  można tak mierzyć?
Zacznę od niuansu czas wejścia w przerwanie. Gdy wykonuje się jakieś przerwanie, to z wejścia INT wykona się po nim. Na błędy rzędu nawet dziesiątek us trzeba liczyć. Tu to nie problem, bo bo licznikiem jest programowy millis. To oznacza, że teoretycznie co 1ms zmienia swoja wartość. Gdy w ten sposób trzeba zmierzyć 100Hz to licznik teoretycznie zliczy w okresie( 1/100Hz = 10ms) "aż" 10 impulsów. Zaiste, super dokładność, błąd 10%! Gdy dodać do tergo fakt, ze co jak pamiętam 125ms licznik jest korygowany o 8 to taki licznik nadaje się do liczenia czasów rzędu sekund gdy nie jest wymagana duża dokładność. Taki kod demo jak i to całe arduino. Ten kod do liczenia prędkości obrotowej silnika, nie nadaje się co najwyżej do jego zgrubnego oszacowania na zasadzie kręci się, nie kręci, wolno, szybko, bardzo szybko.



(11-03-2020, 21:16)m72 napisał(a): Chyba trzeba będzie poświęcić jedno arduino żeby tylko mierzyło impulsy i nic poza tym i przesyłać do drugiego np przeze SPI któro będzie się zajmować wyświetlaniem wyników. :/
Podejście naprawdę "profesjonalne" godne początkującego arduinowca a nie kogoś, kto podobno bez problemu pisze programy na STM32. W to pisanie i znajomość STM32 nie chce mi się wierzyć. Kto raz użył STM32 nie wraca do AVR tym bardziej do arduino. 
Naprawdę nie mogę uwierzyć jak nad takim banałem osoba biegle znająca AVR i STM32 może się męczyć 4 dni? Wystarczy, jak już pisałem, ICP ewentualnie filtr na wejściu (nie jestem pewny na 100% czy w AVR można włączyć w trybie ICP) jak nie to bramka Schmitta lub jak już było napisane, dolnoprzepustowy  RC.

Na STM32 sam odczyt okresu to banał
Kod:
Okres = TIM2->CCR1;

Można sprawdzić czy pomiar skończył się:
Kod:
    if( TIM2->SR & TIM_IT_TRIGGER ) {        // Czy flaga wyzwolenia ustawiona ?
        TIM2->SR &= ~TIM_IT_TRIGGER;        // Kasuj flagę
        Okres = TIM2->CCR1;

inicjalizacja samego timera
Kod:
    TIM2->ARR = UINT32_MAX;
    TIM2->PSC = 0;
    TIM2->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1;
    TIM2->CCER = TIM_CCER_CC2P | TIM_CCER_CC1E | TIM_CCER_CC2E;
    TIM2->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2;
    TIM2->CR1 = TIM_CR1_CEN;

Dla AVR wygląda to jeszcze prościej ale AVR ma liczniki 16 a często tylko 8-bit, dlatego wolę STM32, który w wielu uC posiada liczniki 32-bit co pozwala mi mierzyć czasy od 10ns (taktowanie timerów 100MHz) do ponad 42 sekund bez kombinowania z preskalerami czy przerwaniami.

Zakładając, że raczej więcej niż 10tysś obr/min nie będzie, co daje ok 160Hz czyli mierzysz okres ok 6ms. W AVR timer 16-bit taktowany 8MHz w 6ms zliczy 48000 impulsów więc mieścisz się w 16-bit. Na Elektrodzie swego czasu @niveasoft pokazał prosty program w Bascom liczący okres. Ni używał funkcji Bascom do liczenia czasu bo on takowych nie posiada, wszystko robił na rejestrach. Poszukaj sobie kodu i będziesz miał praktycznie gotowca a nie bezsensowana walka z góry skazana na niepowodzenie albo kilka uC do realizacji banalnego zadania.

(11-03-2020, 21:16)m72 napisał(a): do tak pierdółkowatych projektów jak obrotomierz + jakaś temperatura itp nie będę się męczył z AS i ansi C
Czyli pierdółki na kilku uC są ok, a użycie C bez wykorzystania beznadziejnych arduinowych bibliotek czy lepszego uC już nie?
Wolisz napisać kilku kB kodu używając tego co oferuje arduino, kombinować z uśredniamiem wyniku niż zrobić to dosłownie kilkoma linijkami kodu?
Nie pisz, że zaśmiecam wątek, bo dostałeś praktycznie gotowy kod na STM32.

(11-03-2020, 21:16)m72 napisał(a): Kolega jak taki mądry to niech pomoże.
No to pomogłem więc "rączką w górę".


(11-03-2020, 22:30)elvis napisał(a): Okazało się że w szafie z przydasiami znalazłem moduł AD9850 Smile Podłączając do Arduino mam dokładnie takie same objawy, czyli reakcję na oba zbocza.
Z ciekawości podłączyłem oscyloskop:
Niby wszystko fajnie, ale widać że wyzwalanie wariuje, natomiast samo zbocze już idealne nie jest:
Brak lub zły filtr na wyjściu AD9850.
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
#46
Chłopcze rumiany weź już zmilknij bo się powtarzasz.
Choć nie, sory w profilu masz napisane żeś kobita.
 
Odpowiedź
#47
Chłopcze, weź się za naukę bo narzeźbiłeś kodu, kodu, który działa po japońsku (jako tako). Zachwycasz się nim a mierzy niedokładnie. Dodasz kilka innych funkcji odchyłki będą jeszcze większe bo arduinowe biblioteki uwielbiają na długo blokować przerwania. Programowe łatki jak software serial też zwiększą błędy pomiaru a większość AVR nie ma wielopoziomowego systemu przerwań (wiesz do czego to służy?). Zamiast kombinowania wystarczą dwa wpisy do rejestrów konfiguracji timera i jedna max dwie linijki do odczytu wyniku pomiaru.

Możliwości sprzętowe uC trzeba wykorzystywać a nie "machać" GPIO. w tym przypadku programowo mierzyć czas.
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
#48
Zapomniałeś dopisać kilka zdań o wyższości stm nad avr.
Start Smile
ps. jest tu jakiś moderator ?
 
Odpowiedź
#49
Panie meraserwis, na pierwszej stronie w drugim poście napisałem gotowca na rejestrach, więc na próżno twe napinanie się.
Dalsza dyskusja była tylko i wyłącznie poto aby rozwiązać całkiem inny problem, jak się okazało, sprzętowy.
Nie będę moderował bo z telefonu jest niewygodnie.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#50
(13-03-2020, 16:42)Robson Kerman napisał(a): Panie meraserwis, na pierwszej stronie w drugim poście napisałem gotowca na rejestrach, więc na próżno twe napinanie się.
A co ten kod ma wspólnego z trybem przechwytywania timera?
To nadal programowa rzeźba. Inne przerwania będą powodować błędne odczyty.

Kto nie wierzy niech sam sprawdzi. Wystarczy uruchomić UART i nadawać czy odbierać większe ilości danych z duża prędkością. To samo z I2C. Urzycie 1-Wire czy WS2812 to dopiero będzie porażka.

Program, który pokazałeś w drugim poście
Kod:
EICRA = (1 << ISC01) | (0 << ISC00);
    EIMSK = (1 << INT0);
       sei();

ISR(INT0_vect)
{
    timer_val=TCNT1;
    TCNT1=0;
}
będzie działał po japońsku (jako-tako) jak pozostaną tylko przerwania od timera0, każde zadanie używające lub blokujące przerwania spowoduje mniejsze lub większe błędy. Obsługa WS2812 może doprowadzić do błędów odczytu czasu do 30ms! Przy pomiarze 100Hz to błąd 30%! Inne przerwania dadzą bardzo nieprzewidywalne błędy takie, że nawet uśrednianie wyniku pomiaru nic nie da albo trzeba będzie uśredniać kilkaset pomiarów, co wydłuży czas pomiaru do nieakceptowalnego.
Tego typu programowe rozwiązanie zadziałało by w miarę dobrze (ale nie idealnie) gdyby przerwanie od timera1 miało najwyższy priorytet tyle, ze większość AVR nie ma wielopoziomowego systemu przerwań. Może go lepiej lub gorzej zasymulować ale problemem będą przerwania odbiorcze UART i wejścia INT od poziomu niskiego. Nawet jak jest system wielopoziomowy to czas wejścia w przerwanie o najwyższym prirytecie nie jest stały. Na "dzień dobry" rozkazy wykonują się w różnej liczbie cykli a przerwanie może wykonać się dopiero gdy rozkaz zostanie wykonany a sytuację komplikuje przerwanie w przerwaniu.
Dlatego istnieją rozwiązania sprzętowe, które jak napisałem, działają precyzyjnie a kod jest krótszy.
Naprawdę nie mogę pojąć, dlaczego kombinować z programowymi łatkami zamiast wykorzystać sprzęt? To jest chyba cecha Arduino, wystarczy popatrzeć na softSerial, softi2c, softSpi, dlaczego więc nie zrobić softICP? Dołączam to softICP do długiej biblioteki arduinowych absurdów.

AVR czy Arduino samo w sobie nie jest złe, problemem jest używane w zły sposób ze złymi bibliotekami.


Cała "filozofia" pomiaru okresu to po skonfigurowaniu rejestru TCCR1B. Można włączyć filtrowanie sygnału na wejściu (bit ICNC1) z czym jest problem w temacie. Pozostaje odczyt rejestru ICR1 gdy ustawiona jest flaga ICF1 i naturalnie późniejsze jej skasowanie. Aby nie wprowadzać dodatkowych błędów nie należy kasować TCNT1 przed pomiarem tylko obliczać różnice wartości pomiędzy kolejnymi odczytami dlatego warto skorzystać z przerwania
Kod:
ISR( TIMER1_CAPT_vect )
Trudne?
Prostsze niz programowe łatki?
Pomiar precyzyjny?

Nie jest tak, że arduinowcy są amatorami, oni chcą nimi być, bo o ICP, naturalnym rozwiązaniu w tym przypadku, nie tylko ja pisałem a @Robson Kerman i @elvis brniecie w programowe łatki.
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości