• 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
Sprawdzanie zmiennej niezależnie od delay()
#1
Witam grono,
Ktoś może podsunąć mi rozwiązanie problemu związanego z programem, który ma się następująco.

Przeprowadzam pomiary z kilku czujników, na wyświetlenie każdego z nich na LCD jest przeznaczony odpowiedni delay.
Chcę dodać funkcję ustawień do nastaw.

Dodałem przerwanie, robię zmienną z 0 na 1, część wyświetlającą wyniki mam w while(x == 0) a ustawienia analogicznie w (x == 1) .

Problem polega na tym że pętla musi "przelecieć" swój obieg aby program zareagował na zmianę parametru X.

Co mogę z tym zrobić wystrzegając się jak diabła przepisywania programu z wykorzystaniem millis()?

Dziękuje za sugestie i pozdrawiam forumowiczów.
 
Odpowiedź
#2
Chcesz zrobić sensowny program to naucz się używać millis zamiast delay. Można sprawdzać w przerwaniach timera sprzętowego, ale jak nie umiesz prostszych rzeczy to tylko sobie zrobisz bałagan na strychu. Szkoda Ci przepisać program? Trzeba ich napisać setki w różnych wersjach, to każdy kolejny jest łatwiejszy, palce zaczynają same pisać algorytmy.
Uwierz, że prawie wszyscy boją się rzeczy, których nie rozumieją i nie umieją robić. Boją się nawet podjąć próbę zrozumienia. Potem będziesz się z tego śmiał. I dalej bał spróbować zrozumieć innych rzeczy...
A to powyżej to while (x) lub whiel(! x) i masz to samo dla x dopóki 1 i dopóki NIE 1.
 
Odpowiedź
#3
Szukam rozwiązania poza millis()...i tyle, nie mam zamiaru oglądać w logach bałaganu po 50kilku dniach funkcjonowania arduino gdy millis() się zapełni więc tak szkoda mi przepisać program bo pogorszę sprawę Wink
 
Odpowiedź
#4
Klątwa 50 dni millis() dotyka tylko tych, którzy nie umieją z tej funkcji korzystać.
Zwróć uwagę, na komentarz o klątwie:
Kod:
#define led 13
uint32_t czasTeraz,czasPoprzedni,tik=100; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty=1,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis[10];

void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(led,OUTPUT);


}
//oczywiscie serialprinty i ledy sa do wyrzucenia
void loop() {
  // put your main code here, to run repeatedly:




//gdy nowa sekunda zmien stan led
if (fsekundy)
{
  digitalWrite(led, ! digitalRead (led));
}

//gdy nowa sekunda i co dwie sekundy
if (fsekundy && sekundy%2==0)
{
  sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);
}

if (fminuty && minuty%30==0) //gdy nowa minuta i co 30min
{
Serial.println("Minelo 30 minut");
}

 
  czas();

}


void czas()
{
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tak napisany warunek jest odporny na "klątwe 50 dni millis()"
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
  if(nTik>=(1000/tik))
  {
    nTik=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
To teoretycznie mógłby być problem gdybyś chciał jednorazowo zliczyć okres powyżej 50 dni. Do takich zliczeń timer sprzętowy i tak popełni zbyt duży błąd przez zależność od temperatury, że to nie ma żadnego sensu. Dodatkowo musi być wtedy wspomagany na timerach programowych i liczbach spoza domeny 8 bitowych AVR. Należy wtedy użyć RTC z kompensowanym temperaturowo kwarcem.
Funkcja powyżej używana w ESP8266 też gubi sekundę co kilka minut, widać to w logach przy wysyłaniu na serwer thinkspeak, dla mnie to nie ma znaczenia, ale łatwo to można skorygować zdejmując kilka ms ze zmiennej. Serwer z tym działał mi prawie rok, pierwszy zgon zaliczył gdy padło zasilanie.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości