• 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
#31
Tak na prawdę bez tego timer można to poukładać lepiej. Np. jeśli wtrysk trwa 20-30ms, a wyświetlenie 15ms to można odpalić start pomiaru, wysłać ekran, odczytać koniec wtrysku. W tym czasie oczywiście sprzętowym przerwaniem dalej zbierać impulsy drogi.
Można też korzystając z millis robić coś tylko w parzystych lub nieparzystych, dziesiątkach, setkach, tysiącach ms. Tak samo tylko w trzecich czy siódmych.
Jeszcze raz, timers z tym attach nie są sprzętowymi przerwaniami, przerwaniami w ogóle ( no niczym innym niż if przerywający pętle loop by wykonać polecenie gdy warunek jest spełniony, a przecież nikt ifa przerwaniem nie nazywa), wykonują się w rytm pętli głównej bo oparte są o millis - jeszcze raz, lody jabłkowe to nie jabłko. Wszystkie czasy funkcji mogą wpływać na ilość wywołań, bo to jest po prostu inaczej zapisana pętla loop, ładniej, ale z dodatkowymi skokami do innych funkcji.
Mogłoby to działać lepiej choćby z głową to poukładać tak jak jest, wątpię by było konieczne sprawdzanie licznika impulsów drogi co 1ms, a w niej jeszcze zmieniać interwał?
Nie wydaje mi się, by softowy timer oparty o takt 1ms powinien być wywoływany częściej niż co 10ms, a najlepiej 100ms.
Można też wszystkie zbieranie danych i obliczenia robić przez 480ms, przeliczyć to przecież nie problem, a te 20ms poświęcić na wysyłanie na ekran i UART. Potem od nowa.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#32
(18-08-2018, 15:36)kaczakat napisał(a): Jeszcze raz, timers z tym attach nie są sprzętowymi przerwaniami, przerwaniami w ogóle
Jeśli tak, to najlepiej zrobić swoje przerwania co równiutką 1ms czy nawet 100us co da większu rozdzielczość pomiaru.

(18-08-2018, 15:36)kaczakat napisał(a): Można też wszystkie zbieranie danych i obliczenia robić przez 480ms, przeliczyć to przecież nie problem, a te 20ms poświęcić na wysyłanie na ekran i UART. Potem od nowa.
To nie jest dobra droga do sukcesu. W razie zmian taki program może przestać poprawnie działać. Wystarczy, że nowsza biblioteka będzie obsługiwać LCD nie 10 a np 15ms, albo zostanie zmieniony wyświetlacz na inny typ. Takie pisanie programu to amatorszczyzna. Procedurę pomiaru należy napisać raz a dobrze z użyciem przerwań. Co by się w programie głównym nie kombinowało (zgodnie ze sztuką) procedura liczenia będzie działać poprawnie.
Oczywiście, użycie źle napisanych funkcji, zawieszających przerwania na długo, rozłoży każdy najlepszy program a tak działa 1-Wire na Arduino (na Raspberry Pi też). Na Arduino, na czas transmisji bitu, zawieszane są przerwania (nawet ok70us) biblioteki, które widziałem, zawieszają też na czas sygnału reset i presence (ok 600us) i już jest problem, gdy użyjemy przerwań od timera co 100us. Rozwiązanie jest banalnie proste, sprzętowy USART i nie trzeba zawieszać przerwań, ale Arduino to zabawka i 99% użytych uC ma jeden USART. Przez to Arduino działa (pisałem to już kiedyś) jak Windows - chcesz aby realizowało kilka zadań, użyj kilku komputerów (kilka płytek Arduino). To nie jest wina uC, bo na AVR można naprawdę cuda robić ale nie używając bibliotek Arduino.

PS
Pogrzebię w timer.h i sprawdzę jak te attach jest zrobione.
 
Odpowiedź
#33
Lepiej mieć 100% danych w znanym okresie czasu niż niewiadomy procent w niewiadomym okresie. Zmiana biblioteki nie miałaby wpływu na jakość danych.  Kolejna porcja obliczeń/zbierania danych po prostu rozpoczęłaby się o ten czas później, zmieniłoby to tylko częstotliwość prezentowania danych.  
Bibliotek timers.h pewnie jest kilka, ja zerknąłem do środka tej od Wojtk: https://forum.arduinopolska.pl/watek-bib...iwym-delay i działa to przykładowo tak:

Kod:
#include "Timers.h"

Timers <6> timer;

uint32_t zm0,zm1, zm2, zm3, zm4,zm5;

void setup() {
Serial.begin(115200);

timer.attach(0,1,f0);
timer.attach(1,1,f1);
timer.attach(2,1,f2);
 timer.attach(2,1,f3);
  timer.attach(2,1,f4);
timer.attach(3,1000,f5);
}

 

void f0( ) {
zm0++;
}

void f1( ) {
zm1++;
delay(2);
}

void f2( ) {
zm2++;
}

void f3( ) {
zm3++;
}

void f4( ) {
zm4++;
delay(10);
}

void f5( ) {
 
  Serial.print("zm1: ");
 Serial.print(zm1);
    Serial.print("  zm1: ");
 Serial.print(zm1);
    Serial.print("  zm1: ");
 Serial.print(zm1);
    Serial.print("  zm1: ");
 Serial.print(zm1);
    Serial.print("  zm1: ");
 Serial.print(zm1);
    Serial.print("  zm1: ");
 Serial.println(zm1);
 delay(20);
 zm0=zm1=zm2=zm3=zm4=0;
}



//loop method
void loop() {
timer.process();

}
A wynik pokaże, że zmienne nie są inkrementowane co 1ms, czyli o tysiąc co wydruk:

Kod:
zm1: 84  zm1: 84  zm1: 84  zm1: 84  zm1: 84  zm1: 84
zm1: 82  zm1: 82  zm1: 82  zm1: 82  zm1: 82  zm1: 82
zm1: 82  zm1: 82  zm1: 82  zm1: 82  zm1: 82  zm1: 82
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#34
Faktycznie tą bibliotekę można sobie w du.... wsadzić. Jak  funkcja
Kod:
timer.process();
nie będzie wywoływana odpowiedni często  to wszystko się posypie. Kolejny dowód, że Arduino to zabawka.

Wystarczy skonfigurować timer na przerwania co np 1ms:
Kod:
    TCCR0 = (1<<WGM01);                // tryb CTC
    TCCR0 |= 0x5;                    // Preskaler na 1024
    OCR0 = 1 * F_CPU/1000 / 1024;    // 1ms * F_CPU/1000 / PRESKALER
    TIMSK |= ( 1<<OCIE0 );                // Zezwolenie na IRQ od porównania timera

oraz wektor obsługi przerwania:
Kod:
INTERRUPT( TIMER0_COMP_vect )
{
W przerwaniu możemy sobie wywoływać funkcje co 100ms, np tak:
Kod:
INTERRUPT( TIMER0_COMP_vect ) // INTERRUPT lub SIGNAL zależy co lepsze
{
uint8_t static d100=100;
    
if( !d100-- ){
  d100=100;
  call_co_100_ms();
  }
}
Dodając inne dzielniki, np 10, 300ms mamy inne interwały czasowe.

Program jest banalny, prostszy niż te czary mary w timer.h, itp.


PS
Pokazałem na T0 ale on jest używany przez Arduino, dlatego trzeba wybrać inny. Ponadto kod jest na archaiczny Meag16 ale na nim ostatnio pracowałem reanimując jakiś stary projekt klientowi.
 
Odpowiedź
#35
Biblioteka działa prawidłowo, to użycie dobre nie jest. Przy wywoływaniu co 1ms w moim przejaskrawionym przykładzie wykonuje się 8% zadań w ciągu 1s, przy interwale 10ms wykonuje się 85%, a przy 100ms 100%.
Równie dobrze można mieć pretensje do wiertła od drewna, że się popsuło na pierwszym otworze w wielkiej płycie.
Jak ktoś chce może użyć biblioteki ze sprzętowym timerem to jest TimerOne.h, działa w oparciu o timer1. Pewnie jest analogiczna dla timera 2.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#36
(18-08-2018, 17:40)kaczakat napisał(a): Biblioteka działa prawidłowo, to użycie dobre nie jest.

Nigdzie w opisie biblioteki nie znalazłem informacji, że min czas wywołań to 100ms.
 
Odpowiedź
#37
Napisałem, że mój przykład jest przejaskrawiony. Z funkcjami o długości kilkadziesiąt us działby może i dla 1ms.
Nie ma napisane, bo biblioteka nie ma opisu. Jest darmowa, to chce bierze i używa wg własnego uznania. Parę razy napisałem, że nie jest hardwarowym timerem, w końcu dotarło. W bibliotece timerone na timerze sprzętowym można sobie ustawić interwał w us, jak ktoś chce co tyle wyświetlać coś na LCD co 5us to też nie zadziała, z odpowiednimi funkcjami zadziała OK.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#38
(18-08-2018, 22:38)kaczakat napisał(a): W bibliotece timerone na timerze sprzętowym można sobie ustawić interwał w us, jak ktoś chce co tyle wyświetlać coś na LCD co 5us to też nie zadziała.
5us - 200kHz na AVR. Nie rozśmieszaj mnie.
Fakt, że na AVR można wyciągnąć 300 i więcej ale obciążenie uC 80..90% choć procedura bardzo krótka (kilkanaście rozkazów). LCD musiałby pracowac w trybie 8-bit a uC mieć kontroler zewnętrznej magistrali.
Tak częstych przerwań nie robi się nawet na ARM, są inne rozwiązania. Generalnie, tak częste przerwania oznaczają, że uC albo programista jest za słaby bo do realizacji takiego zadania należy użyć sprzętu (timerów, DMA, USART itp).

Wiele rzeczy na Arduino jest robione na siłę, np obsługa karty SD, dekodowanie JPEG na AVR z 2kB RAM i wyświetlanie
obrazka na LCD 600x480 bez akceleratotra graficznego. Obrazek wyświetla się chyba z 10 sekund. Co sensownego można na tym zbudować? Odświeżanie ekranu 0,1 klatek/sek.


PS
Im więcej bibliotek Arduino znam, tym bardziej jestem przekonany, że to badziewie.
 
Odpowiedź
#39
Tak sobie myślę, ale tylko myślę (alkohol, łikend, itp.), że może by użyć RTOS'a.
Jest wersja na Ardu. Działa pięknie. Zajmuje mniej pamięci niż użycie timers.
Każdy pomiar, wyświetlanie itd, powrzucać do oddzielnych wątków i nie przejmować się tymi czasami.
Mam sterowanie odkurzacza zrealizowane na Arduino_FreeRTOS (detekcja przejścia przez zero, sterowanie fazą, wyświetlacz OLED, przyciski) i muszę powiedzieć, że jest moc.
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ź
#40
(19-08-2018, 00:57)Robson Kerman napisał(a): Tak sobie myślę, ale tylko myślę (alkohol, łikend, itp.), że może by użyć RTOS'a.
(...)
Mam sterowanie odkurzacza zrealizowane na Arduino_FreeRTOS (detekcja przejścia przez zero, sterowanie fazą, wyświetlacz OLED, przyciski) i muszę powiedzieć, że jest moc.

RTOS nie rozwiąże problemu pomiarów krótkich czasów. To trzeba zrobić sprzętowo ewentualnie na przerwaniach od timera. Pomocny będzie natomiast w "równoległym" wykonywaniu długotrwałych obliczeń i wyświetlania wyników.

Na wyświetlacz jest jednak prosta rada, wybrać odpowiedni tym (SPI, I2C) i komunikację zrobić przez DMA (Xmega, ARM, Z-80 - tak, tak, Z-80 mógł działać z DMA) lub na przerwaniach. Tyle, że do tego trzeba RAM aby cały bufor wyświetlacza zmieścił się uC. Więc należy zapomieć o Mega328, min to 4kB RAM.


PS
Co do odkurzacza, przejście przez zero co 20ms gdzie dokładność 1ms wystarcza to można spokojnie na Z-80 1MHz zrobić.
Robiłem sterowniki fazowe zarówno na AVR jak i ARM http://avt.4ra.pl/viewtopic.php?id=31. Pętla główna niewiele robi (wyświetlanie wyników, przeliczanie, oscyloskop). Wszystkie obliczenia i obsługa LCD wykonywane sa co 100ms, trwają kilka ms, resztę czasu procek śpi.
Samo sterowanie fazowe i wykrywanie zera załatwia w 90% sprzęt (generowanie impulsu dla triaka przez timer).
 
Odpowiedź
  


Skocz do:


Przeglądający: 2 gości