Skocz do zawartości
narbej

Działanie millis i delay - rozważania o odmierzaniu czasu

Pomocna odpowiedź

Oczywiście, czasem nawet trzeba. Jednak zmienne globalne nie wymagają inicjalizacji, warto po prostu o tym widzieć. Więc przypisanie zera nic nie zmieni, wygenerowany kod będzie taki sam.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Myślę, że taki kod zmierzy za pomocą millis() upływ milisekund. Może  narbej  spróbuj to wykorzystać.

void loop()
{
  unsigned long poprzednio=millis(); 
  unsigned long teraz=0;
  unsigned long minelo=0;
  while(1)
  {
    teraz=millis();
    minelo=teraz-poprzednio;   //w minelo ilosc ms
    poprzednio=teraz;
    //a tu zrób co chcesz z wartością minelo
  }
}

Kod nie uwzględnia przepełnienia millis().

Edytowano przez Belferek

Udostępnij ten post


Link to post
Share on other sites
11 godzin temu, Belferek napisał:

Myślę, że taki kod zmierzy za pomocą millis() upływ milisekund. Może  narbej  spróbuj to wykorzystać.

dalej kod ....

Ale przecież ja nie mam żadnego problemu z moim kodem. To Ty chciałeś go zobaczyć [mój kod]. Mam jedynie problem z niedokładnością funkcji millis() w moim egzemplarzu klonu ardunio uno.

 

PS

To, że w moim kodzie nie było klawisza startu i stopu, to nie dlatego, że nie wiem jak napisać kod, tylko nie miałem pod ręką wyłącznika. Ostatecznie wpisałem i włączam/wyłączam, stykając druciki [;-)], chociaż w sumie już wygrzebałem jakieś wył.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

13 sekund na 45 minut to trochę dużo. Tak z ciekawości może porównaj swoje wyniki z tym:


void setup() {
Serial.begin(115200);
Serial.println(millis());
Serial.print("\n\n\n\n");
}

unsigned long currTime, stoper;
const unsigned long dod = 1000;

void loop() {
  if (millis() > stoper)
  {
    stoper += dod;
    Serial.println(stoper/dod);
  }
}

To Twój program bez wyświetlacza I2C.

Edytowano przez Belferek

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Oryginalne arduino uno rev3 według schematu

schemat arduino uno rev3

ma zamontowany rezonator ceramiczny o dokładności 0,5%, więc trudno się dziwić osiąganej dokładności.

rezonator ceramiczny arduino

@narbej zobacz jaki rezonator jest u Ciebie. Paradoksalnie tanie klony arduino z rezonatorem kwarcowym mogą być dokładniejsze od oryginałów.

Edytowano przez grg0
  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Na  moim jest oznaczenie: 12.000H546 ale nie znalazłem nic w internecie [w googlu] co to znaczy. Tak naprawdę, teraz to już dla mnie nie ważne, z jaką dokładnościa [nie dokładnością] tyka kwarc w moim uno. Bardziej interesowałoby mnie czy tyka z konsekwencją tzn, czy mimo, że nie tyka dokładnie ale czy tyka cały czas, czy jest stabilny [na ile jest] temperaturowo [zewnętrzna i po ogrzaniu samego układu] itd. Myślę, że to jest do ogarnięcia i właśnie to staram się zrobić 😉

@Belferek, nie bardzo rozumiem, co mam z czym porównywać? Poprawiasz mój własny program i myślisz, że na serialu z największą prędkością będzie lepiej działał? Myślisz, że to wyświetlacz lcd tak wpływa na mój program? I jak ja mam porównywać ilość sekund od startu [np 799] z moim stoperem, przeliczać w pamięci? 😉 

[edit] wyszło coś koło 957 😉 na 16 minut - ale na ile dokładnie włączyłem [zsynchronizowałem] stoper z arduino? [powinno wyjść 960].

Przecież napisałem, że nie mam problemu z programem, czy nie? Może zerknij tu, poz. 4: --> https://pl.spoj.com/ranks2/ 😉 Nie lubię się chwalić, ale ... po prostu, żeby nie było niejasności.

 

Natomiast z chęcią się dowiem, czy myślałeś o wykorzystaniu twojego RTC, DO POMIARU [sorry włączył się capslock] temperatury i jako generator? Takie możliwości wynikały z opisu tego układu [tak je zrozumiałem]. Bo kiedyś myślę o projekcie stacji pogodowej [pewnie jak większość] i generatorze dźwięku.

Edytowano przez narbej

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Ja "sprawdziłem" swojego klona (Waveshare Uno Plus z Botlandu) z rezonatorem kwarcowym w teście 1,5 godzinnym czyli 5400 sekund. Przyjmując, że stoper w PC uruchomiłem z sekundowym opóźnieniem to Arduino powinno odliczyć po upływie 1,5 godziny w/g stopera 5401 - odliczyło 5402. Sugeruje to, że Arduino się śpieszy jeśli przyjąć, że program PC to wzorzec. Mimo wszystko ta niedokładność w porównaniu do Twojego Arduino jest dużo mniejsza.

1 godzinę temu, narbej napisał:

Natomiast z chęcią się dowiem, czy myślałeś o wykorzystaniu twojego RTC, DO POMIARU [sorry włączył się capslock] temperatury i jako generator?

Mierzę tylko temperaturę. Do obsługi tego RTC korzystam z biblioteki - RTC by Makuma

Edytowano przez Belferek

Udostępnij ten post


Link to post
Share on other sites

@narbej mimo wszystko, czy mógłbyś zamieścić zdjęcie Twojego arduino uno, albo dać link do sklepu ze zdjęciami tego klona. Na kwarcu powinno być raczej napisane 16.000. Rezonator powinien być podłączony bezpośrednio do nóg 9, 10 obudowy DIP, lub do nóg 7,8 obudowy TQFP Atmegi328.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
23 godziny temu, grg0 napisał:

... mimo wszystko, czy mógłbyś zamieścić zdjęcie Twojego arduino uno, albo dać link do sklepu ze zdjęciami tego klona.

To już tak trochę mija się z tematem, ale ...

Dostałem uno pod choinkę, od Mikołaja, więc nie wiem z jakiego sklepu pochodzi. Znalazłem identyczny model [ale nie jest to https://botland.com.pl/ ]

--> https://abc-rc.pl/product-pol-6233-UNO-R3-CH340-Atmel-ATMega328-16MHz-kompatybilny-z-Arduino.html

I masz rację, podałem napis z "dużego" kwarca przy USB. Wydaje mi się, że jest tam jeszcze jeden "mikrusi" między C5 i C6, ale z niego napisów nie jestem w stanie odczytać ;-(

 

PS

Jestem w takim wieku, że już nie wierzę w Mikołaja, a listę moich propozycji, wysłałem do mojej córki, Katarzyny.

Moja młodsza córka, Kasia, jest już w tak podeszłym wieku, że nie wierzy już w Mikołaja, a listę moich propozycji ... [pewnie skonsultowała z narzeczonym?]

Edytowano przez narbej

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Arduino na zdjęciu ma rezonator ceramiczny, co może tłumaczyć małą dokładność odmierzania czasu. Co do programowej korekcji rezonatora ceramicznego to nie wiem. Współczynnik temperaturowy i starzenia jest większy niż dla rezonatorów kwarcowych. Może bardziej doświadczeni koledzy coś podpowiedzą.

Edytowano przez grg0

Udostępnij ten post


Link to post
Share on other sites

Co jakiś czas widzę marudzenie o millis i 50 dniach do apokalipsy. Otóż nic ciekawego się nie wydarzy po 50 dniach, jeśli zmienne używane w milis (i stała interwału np.1000UL) jest określona jako UL lub wynik rzutowany na UL to nie uronicie nawet ms, nie mówiąc już o zawieszeniu programu. Oczywiście nie mówię o dokładności, zgubić ms można po prostu długością pętli, ale nie ma apokalipsy, zawieszenia, urwania sekundy bo zmienna się skończyła, itp.Jak komuś się nie chce czekać to można zrobić to z micros, jest 1000x szybciej, a jak komuś się bardzo spieszy to podobne wyliczenia może zrobić dla uint8_t. Nie jest to doskonała metoda zarządzania czasem, ale super działa niezależnie od sprzętu - AVR, ARM (DUE/STM), ESP8266 i ESP32. 

Udostępnij ten post


Link to post
Share on other sites

Długo się zbierałem, żeby do tematu wrócić, ale kolega @kaczakat dobrze mnie zmotywował.

Więc wracając do samego początku. Zacznijmy od prostego programu z delay - używam nieco przerobionego programu blink z przykładów Arduino:

void setup() 
{
    pinMode(2, OUTPUT);
}

void loop() 
{
    digitalWrite(2, HIGH);
    digitalWrite(2, LOW);
    delay(100);
}

Opóźnienie ustawiłem na 100ms bo nie jestem cierpliwy zbytnio, a w przypadku analizatora logicznego jest to całkiem rozsądne opóźnienie. Pierwszy program wydaje się działać poprawnie:

2019-01-14-151410_2560x1416_scrot.thumb.png.fa3dc07035aff63c3a596fddbcc3ef8f.png

Oczywiście wiemy, że to tylko pozory. Wszystko działa - błąd jest, bo delay() zatrzymuje procesor na 100ms, ale nawet wykonanie samej głównej pętli oraz digitalWrite() moment zajmuje.

Kolejny krok to dodanie czegoś do programu. Ponieważ nie ma debuggera, więc większość programów wypisuje dane o swoim działaniu przez port szeregowy (albo raczej USB). Dodam więc coś takiego do mojego kodu:

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{
    digitalWrite(2, HIGH);
    Serial.println("Wysyłamy trochę danych");
    Serial.println("jeszcze trochę...");
    Serial.println("i jeszcze więcej");
    digitalWrite(2, LOW);
    delay(100);
}

Czas na kolejny pomiar:

2019-01-14-151716_2560x1416_scrot.thumb.png.19fe50dd85a2c984355f9b55b699855b.png

I tutaj widać pierwszy problem. Czas W to delay(), i wygląda jak 100ms. Jednak okres impulsów T jest już nieco dłuższy jakieś 101,1ms. Czyli nasz zegar zaczyna się spóźniać.

Oczywiście im bardziej będzie zajęty procesor, tym gorzej dla naszego programu. Tak działa delay() i po prostu trzeba o tym pamiętać.

Kolejny krok to program z kursu:

unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long roznicaCzasu = 0;

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{
    aktualnyCzas = millis();
    roznicaCzasu = aktualnyCzas - zapamietanyCzas;
  
    if (roznicaCzasu >= 100UL) {
        zapamietanyCzas = aktualnyCzas;
 
        digitalWrite(2, HIGH);
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.println("i jeszcze więcej");
        //delay(15);
        digitalWrite(2, LOW);        
    }    
}

Jak pewnie się domyślamy działa nieco lepiej:

2019-01-14-152037_2560x1416_scrot.thumb.png.4a237ecac92ba8c5f8a1ecdb7fdaccee.png

Żeby lepiej było widać różnicę dodałem delay(15) - w kodzie powyżej jest zakomentowany, po usunięciu komentarza lepiej widać działanie programu:

2019-01-14-152108_2560x1416_scrot.thumb.png.67859d21dbca7814a45dcc1626d7bcf7.png

 

Teraz więc wróćmy do propozycji zmian zaproponowanej przez kolegę @narbej na początku tego tematu.

Program wygląda następująco:

unsigned long zapamietanyCzas = 0;
unsigned long roznicaCzasu = 100UL;

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{  
    if (zapamietanyCzas + roznicaCzasu <= millis()) {
        zapamietanyCzas += roznicaCzasu;
 
        digitalWrite(2, HIGH);
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.println("i jeszcze więcej");
        delay(15);
        digitalWrite(2, LOW);        
    }    
}

Kolejny pomiar i zgodnie z oczekiwaniami wszystko pięknie działa:

2019-01-14-152654_2560x1416_scrot.thumb.png.a641ddaef7a802183713fcf2fa283b45.png

Więc teraz zastanówmy się co będzie się działo za te niecałe 2 miesiące - czyli po przepełnieniu zakresu unsigned long, w którym mamy przechowywany czas.

Albo lepiej przetestujmy. Zgodnie z sugestią zmieniam long na char:

unsigned char zapamietanyCzas = 0;
unsigned char roznicaCzasu = 100UL;

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{  
    if (zapamietanyCzas + roznicaCzasu <= millis()) {
        zapamietanyCzas += roznicaCzasu;
 
        digitalWrite(2, HIGH);
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.println("i jeszcze więcej");
        delay(15);
        digitalWrite(2, LOW);        
    }    
}

Jak łatwo policzyć unsigned char przepełni się po 2 cyklach programu. Zgodnie z uwagą kolegi @kaczakat nie obawiamy się niczego i wykonujemy pomiar:

2019-01-14-152849_2560x1416_scrot.thumb.png.428357e81a57ed6fb5469e600016d837.png

Chyba jednak nie tego oczekiwaliśmy, prawda?

Ok, mała poprawka. Trochę z rozpędu zapomniałem o typie zwracanym przez millis().

Poniżej dodaję nową zmienną m typu unsigned char, tak żeby nie było problemu dłuższego typu zwracanego z millis:

unsigned char zapamietanyCzas = 0;
unsigned char roznicaCzasu = 100UL;

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{  
    unsigned char m = millis();
    if (zapamietanyCzas + roznicaCzasu <= m) {
        zapamietanyCzas += roznicaCzasu;
 
        digitalWrite(2, HIGH);
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.println("i jeszcze więcej");
        delay(15);
        digitalWrite(2, LOW);        
    }    
}

Teraz jest już dokładnie tak jak powinno:

2019-01-14-155101_2560x1416_scrot.thumb.png.55a1904d8157ee89e865a38cdd55f879.png

Chociaż właściwie jak czytam co napisałem, to nadal nie jest jak powinno - co nie znaczy, że wtedy zadziała, ale może ktoś wcześniej zauważy gdzie popełniłem błąd w mojej "symulacji" przepełnienia 🙂

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Jak zwykle pośpiech to nic dobrego - wcześniej chciałem na szybko sprawdzić jak działa program i oczywiście tylko narobiłem błędów. O ostatnim napisałem, ale zauważyłem go dopiero czytając moje wcześniejsze komentarze. Jednak lepiej widać błędy czytając niż pisząc.

Porblem wynikał z dodawania wewnątrz if-a. Po lewej stronie dodawałem dwie zmienne 8-bitowe, niestety kompilator miał prawo rozszerzyć wynik i dlatego po dwóch cyklach program przestawał generować kolejne impulsy.

Teraz poprawiam program wprowadzając dodatkową zmienną - tak aby być pewnym że jest tylko 8-bitów po dodawaniu:

unsigned char zapamietanyCzas = 0;
unsigned char roznicaCzasu = 100UL;

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{  
    unsigned char m = millis();
    unsigned char next = zapamietanyCzas + roznicaCzasu;
    if (next <= m) {
        zapamietanyCzas += roznicaCzasu;
 
        digitalWrite(2, HIGH);
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.println("i jeszcze więcej");
        delay(15);
        digitalWrite(2, LOW);        
    }    
}

Czy program działa dobrze? Oczywiście nie, chociaż inaczej niż poprzednio:

2019-01-14-220317_2560x1416_scrot.thumb.png.0bc413e02adae14a340c1214026c55cd.png

Czas może chwilę pomyśleć zamiast ciągle eksperymentować.

Spróbujmy wykonać program "na kartce" . Na początku wartość zmiennej "zapamietanyCzas" ma wartość 0. Dodajemy "roznicaCzasu" i w "next" mamy wartość 100.

Teraz wszystko działa poprawnie, z millis() odczytujemy różne wartości aż dostaniemy coś większego lub równego od 100.

Gdy to nastąpi, program dodaje do "zapamietanyCzas" 100, więc wartość zmiennej będzie wynosiła 200 i dalej wszystko jest ok.

Znowu czekamy, aż wartości zwracane przez millis() wzrosną i zaczyna być ciekawie.

Dodajemy do zapamietanyCzas wartość 100, ale występuje przepełnienie. Nowa wartość powinna wynosić 300, ale zmienna jest 8-bitowa, więc zamiast tego dostajemy 44. To poprawny wynik, ale problem zacznie się przy kolejnym obiegu pętli.

Załóżmy że obieg pętli trwa 16ms, a poprzenio millis() zwróciło 200. Nowa wartość zapamietanyCzas wynosi 44, millis() zwroci poprawny czas 216 i... nasz warunek if bedzie spełniony.

Wobec tego do 44 w zapamietany czas dodamy 100, czyli bedziemy mieli tam 144, oraz niepoprawnie wykonamy tresc w warunku.

W nastepnym obrocie petli tez bedzie zle. Millis() zwroci 232, a wiec znowu wykonamy nasz warunek...

To tlumaczy te dziwne dlugie impulsy na wykresie.

Jak widać tak prosty program można na wiele sposobów popsuć - moża również łatwo naprawić, stąd moje pytanie: jak?

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Przede wszystkim napisałem, że zmienne mają byc UL bo chodzi by były tego samego  typu, nic mądrego nie wyniknie z przypisania m=millis(). Nie wiem co ma to dać: unsigned char roznicaCzasu = 100UL;  - zmienna jest 8 bitowa, wartość też, a na siłę robi się z niej UL. No i faktycznie udało się to zepsuć, brawo. Ja testowałem z mircos i nic się nie przepełnia:

uint32_t zapamietanyCzas = 0;
uint32_t roznicaCzasu = 200000UL;
uint32_t licznikmillis,minuty;
uint8_t msetki,sekundy,fmsetek;
void setup() 
{
    pinMode(13, OUTPUT);
    Serial.begin(115200);
}

void loop() 
{  
 fmsetek=0;
     uint32_t m = micros();
    if ((uint32_t)(m - zapamietanyCzas) >= roznicaCzasu) {
        zapamietanyCzas = m ;
 
      fmsetek=1;
      msetki+=2;
      if(msetki>=5)
      {
        msetki=0;
        sekundy++;
        if(sekundy>=60)
        {
          sekundy=0;
          minuty++;
        }
      }
             
    }    

if(fmsetek)
{
        digitalWrite(13, ! digitalRead(13));
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.print("Powinno przestac dzialac po 70 minutach, a minelo minut:");
        Serial.println(minuty);
        delayMicroseconds(150000);
}
    
}

Dokładność z micros jest kiepska, może coś innego jest skopcone, nie będę szukał, idę spać, ale wg stopera w telefonie działa ponad 100minut.

Jak komuś szkoda czasu to tu jest opisany prawidłowy sposób przetestowania millis na wartościach 8bit: https://www.baldengineer.com/arduino-how-do-you-reset-millis.html. Zgodnie z tym przykład blinkWithOutDelay odporny na przekręcenie licznika powinien wyglądać tak:

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
uint32_t previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const uint32_t interval = 1000UL;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  uint32_t currentMillis = millis();

  if ((uint32_t)(currentMillis - previousMillis) >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
      
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
    
  }
}

I tak, przetestowałem go - działa. Bez rzutowania też działał, ale już nie pamiętam, był inny problem przy przekręceniu zakresu zmiennej, chyba własnie nie doliczał do pełnej sekundy.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@kaczakat - program który podałeś działa nieco inaczej. Cały problem nie wynika z użycia millis(), micros() czy innej funkcji. Równie dobrze możemy po prostu używać licznika w pętli.

Każda z tych funkcji zwraca zmienną o skończonej długości - np. 32 bitów. Więc po pewnym czasie - dla millis() będzie to 49dni, dla micros 1000 razy szybciej następuje przepełnienie i wartości liczą od początku.

Problem polega na "sprytnym" operowaniu typami ze znakiem i bez znaku, tak aby uzyskać poprawne działanie. W przypadku kodu, który podał @narbej tak nie było.

Ja chciałem pokazać jak zasymulować problem używając zmiennych 8-bitowych i tylko udowodniłem samemu sobie jak trzeba uważać z typami w C. Wbrew pozorom przypisanie m =millis() jest ważne. Sam millis zwraca zmienną 32-bitową, więc porównując ją z 8-bitową łatwo uzyskać stale fałszywy wynik - co niestety mi się udało.

A wracając do progamu, który analizowałem - przecież zmienne są typu unsinged char, więc nie rozumiem gdzie miał być problem. Jest typ 8-bitowy bez znaku, a program działa błędnie. Pytanie jak go poprawić? I dlaczego wtedy już będzie dobrze?

Edit: Widzę, że metoda znalezienia gotowca w sieci jest teraz dobra na wszystko.

Ja jednak lubię nieco podrążyć temat. Więc po pierwsze ten programik z sieci nie rozwiązuje usterki, którą zgłosił @narbej - czasy, które program spędza poza if-em dodają się do błędu.

No i na czym polega lepszość tego rozwiązania? Jak udowodnić, że teraz wszystko działa dobrze oraz rozwiązać problem z gubieniem czasu poza if-em?

Edit 2:

Faktycznie fora internetowe potrafią zabić w człowieku cały entuzjazm i chęć dzielenia się wiedzą. Więc tylko napiszę, jak można było ten program poprawić:

unsigned char zapamietanyCzas = 0;
unsigned char roznicaCzasu = 100;

void setup() 
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
}

void loop() 
{  
    unsigned char m = millis();
    unsigned char diff = m - zapamietanyCzas;

    delay(10);
    if (diff >= 100) {
        zapamietanyCzas += roznicaCzasu;
 
        digitalWrite(2, HIGH);
        Serial.println("Wysyłamy trochę danych");
        Serial.println("jeszcze trochę...");
        Serial.println("i jeszcze więcej");
        delay(15);
        digitalWrite(2, LOW);        
    }    
}

Są tutaj dwa kluczowe elementy. Pierwszy to odejmowanie przy zmiennej diff. Dzięki niemu unikamy problemów, które zawierała wersja kolegi @narbej Przepełnienie zmiennej nic złego już nie robi.

Druga sztuczka to dodawanie różnicyCzasu do zmiennej zapamietanyCzas, zamiast do m, czy też wartości millis(). Dzięki temu nawet jeśli wywołanie if()-a się opóźni (po to jest delay(10)), wartość średnia częstotliwości wykonania warunku będzie stała.

2019-01-14-225216_2560x1416_scrot.thumb.png.98230c3769d2bf207826aa32ffd15c30.png

  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Napisz odpowiedź...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...