Skocz do zawartości

Funkcja millis i pomiar z czujnika - ile trwa?


bieri13

Pomocna odpowiedź

Cześć, 

Próbuję zrozumieć działanie funkcji millis ale mam kilka pytań:
1. Jeśli po czasie 100ms odczytuję wartość z czujnika to ile taki odczyt trwa? 
2. Jeśli chcę odczytywać pomiar z czujnika co 100ms, i jednocześnie sterować wyjściem PWM ale wyjście nie może być jednocześnie wysterowane gdy trwa pomiar to czy funkcja millis do tego się nadaje? Jeśli tak to prosiłbym o podpowiedź jak to zrobić? 

Próbuję rożnych kombinacji z millis do odczytu i do sterowania wyjściem ale nie uzyskuję zadowalających efektów - zawsze w którymś momencie pomiar mi się nakłada wraz z sygnałem sterującym. 

Link do komentarza
Share on other sites

Funkcja millis jest bardzo prosta - po prostu podaje czas w milisekundach, który upłynął od momentu włączenia Arduino. Tyle - nic więcej.

A ile trwa odczyt wartości czujnika... no cóż, może gdybyśmy wiedzieli jaki to czujnik, łatwiej by było odpowiedzieć na to pytanie.

18 minut temu, bieri13 napisał:

wyjście nie może być jednocześnie wysterowane gdy trwa pomiar

Możesz sprecyzować co to oznacza? Jaki ma być stan wyjścia w czasie pomiaru (bo przecież jakiś musi być, prawda?)

Link do komentarza
Share on other sites

Czujnik to termopara + WO.
Wyjście steruje grzałką - czyli układ regulatora temperatury.
Stan wyjścia w czasie pomiaru - wyjście wyłączone.

Link do komentarza
Share on other sites

Jest jeszcze funkcja micros() więc może tak zmierzysz ile trwa pomiar z Twojego czujnika:

unsigned long start=micros();               //lub millis()
pomiar_z_czujnika();                        //tu Twój pomiar
unsigned long czas_trwania=micros()-start;  //lub millis()-start

 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

A żeby wyłączyć PWM w Arduino wystarczy przed pomiarem wykonać:

digitalWrite(NUMER_PINU, LOW);

Po wykonaniu pomiaru można z powrotem włączyć PWM przez analogWrite.

Czas pomiaru będzie raczej pomijalny - sprawdź zgodnie z tym co napisał @Belferek i podaj tu wynik (tak się składa, że przypadkowo nie mam termopary...)

 

Link do komentarza
Share on other sites

Do tego się nadaje nawet funkcja delay(100); Pwm działa sobie dyskretnie w tle podczas trwania delaya, po zakończeniu wystarczy tylko odłączyć pin PWM lub skorzystać z ADC sleep mode co wyeliminuje wpływ działającego podczas próbkowania rdzenia i pobrać próbkę z termopary. Rozumiem, że do tej termopary masz podłączony jakiś wzmacniacz operacyjny? Czas na pobranie próbki to siłą rzeczy czas próbkowania przez ADC, można też dodać chwilkę delaya przed wykonaniem konwersji żeby napięcie się ustabilizowało.

Edytowano przez Gość
Link do komentarza
Share on other sites

18 minut temu, atMegaTona napisał:

Rozumiem, że do tej termopary masz podłączony jakiś wzmacniacz operacyjny?

Tak.

Na razie próbuję bez żadnego regulatora (typu PID) ustawić prawidłowo odczyt z termopary wraz z wysterowaniem wyjścia. Czyli reguluję ON-OFF.
Wszystko działa pięknie do póki temperatur nie oscyluje wokół zadanej - czyli jak temp. z czujnika zrówna się z zadaną to zaczyna się chwilowe próbkowanie i odczyt zostaje zakłócony o jakieś +-4 stopnie (przypomina mi to drgania styków).

aktualnyCzas = millis();
if (100UL <= aktualnyCzas - zapamietanyCzas1 <= 120UL)  
   {
   digitalWrite(iron, LOW);
   odczyt = analogRead(czujnik_temp);
        
   if (10UL <= aktualnyCzas - zapamietanyCzas1 <= 80UL) 
      {
      if(odczyt <= napiecie)
        {
        lcd.setCursor(12,0);
        lcd.print("*");
        analogWrite(grzalka, 255);
        } 
        else
        {
        lcd.setCursor(12,0);
        lcd.print(" "); 
        digitalWrite(grzalka, LOW);
        }
   }
zapamietanyCzas1 = aktualnyCzas;

 

Link do komentarza
Share on other sites

12 minut temu, bieri13 napisał:

if (100UL <= aktualnyCzas - zapamietanyCzas1 <= 120UL) 

 

Niestety tak nie wolno. Co prawda kompilator się nie przyczepi ale oznacza to zupełnie coś innego - w tym przypadku zupełnie bez sensu.

if (aktualnyCzas - zapamietanyCzas1 >=100UL && aktualnyCzas - zapamietanyCzas1 <= 120UL) 

a tak wolno.

 

Link do komentarza
Share on other sites

Coś robię nie tak - ponieważ przy tym kodzie

aktualnyCzas = millis();
           
      if (aktualnyCzas - zapamietanyCzas1 >= 10UL && aktualnyCzas - zapamietanyCzas1 <= 80UL) 
      {
      if(odczyt <= ustaw)
        {
        lcd.setCursor(12,0);
        lcd.print("*");
        analogWrite(grzalka, 255);
        Serial.print("A = ");
        Serial.println(aktualnyCzas);
        } 
        else
        {
        lcd.setCursor(12,0);
        lcd.print(" "); 
        digitalWrite(grzalka, LOW);
        Serial.print("B = ");
        Serial.println(aktualnyCzas); 
        }
      }
      
      if (aktualnyCzas - zapamietanyCzas1 >= 20UL && aktualnyCzas - zapamietanyCzas1 <= 80UL)  
      {
      digitalWrite(grzalka, LOW);
      odczyt = analogRead(czujnik_temp);
      Serial.print("C = ");
      Serial.println(aktualnyCzas);
      }
          
  // odczyt danych z potencjometru nastawy temperatury  
   if (aktualnyCzas - zapamietanyCzas1 >= 10UL && aktualnyCzas - zapamietanyCzas1 <= 100UL) 
   {
     ustaw = analogRead(ustaw_temp);
     Serial.print("D = ");
     Serial.println(aktualnyCzas); 
     
   }
zapamietanyCzas1 = aktualnyCzas;

Odczyt przez port szeregowy wygląda tak:

B = 5714
C = 5714
D = 5714
B = 5739
C = 5739
D = 5739
B = 5764

 

Link do komentarza
Share on other sites

Owszem, robisz coś nie tak: podajesz fragment kodu który Twoim zdaniem jest błędny skrzętnie ukrywając resztę, gdzie prawdopodobnie tkwi błąd.

Poza tym zamiast aktualnyCzas wypisuj sobie (aktualnyCzas - zapamietanyCzas1) - przynajmniej będzie się można z tego czegoś dowiedzieć.

 

Link do komentarza
Share on other sites

Reszta kody to ustawienia zmiennych oraz obsługa LCD.

Częściowo znalazłem problem - w każdym if-ie gdzie wykorzystuję funkcję millis zrobiłem oddzielną zmienną do zapamiętywania czasu i wyniki mam takie:

C = 0
B = 154
C = 0
D = 222
C = 0
B = 154
C = 0
D = 218

Natomiast gdy próbuję zrobić podwójny warunek nic się nie dzieje, pomimo dużego czasu:

if (aktualnyCzas - zapamietanyCzas2 >= 110UL && aktualnyCzas - zapamietanyCzas2 <= 200UL)

 

Link do komentarza
Share on other sites

Albo pokażesz cały kod, albo uznamy że sam wiesz najlepiej gdzie masz błąd, od nas oczekujesz jedynie kibicowania i po prostu pomyliło Ci się forum z własnym blogiem.

To jak będzie?

Link do komentarza
Share on other sites

Wyrażenia pomiędzy operatorami logicznymi && powinny być zawarte w nawiasach. To dobra metoda aby do każdej gałęzi if dodawać osobną zmienną pamiętającą zadane opóźnienie, jednak taka zmienna powinna zawierać już stan łącznie z opóźnieniem aby nie trzeba było wykonywać na niej działań podczas sprawdzania warunków dzięki czemu samo sprawdzenie będzie bardziej czytelne. 


if(zmienna_timeout <= millis()){
  // jakiś kod
  zmienna_timeout = millis() + zadany_delay;
}

 

Link do komentarza
Share on other sites

5 godzin temu, bieri13 napisał:

Natomiast gdy próbuję zrobić podwójny warunek nic się nie dzieje, pomimo dużego czasu:


if (aktualnyCzas - zapamietanyCzas2 >= 110UL && aktualnyCzas - zapamietanyCzas2 <= 200UL)

 

To może zrób tak i pochwal się poza swoim tajnym kodem wynikiem takiej modyfikacji:

if ((aktualnyCzas - zapamietanyCzas2 >= 110UL) && (aktualnyCzas - zapamietanyCzas2 <= 200UL))
{
 //tutaj twoje instrukcje
}
else { Serial.print("Roznica = "); Serial.print(aktualnyCzas - zapamietanyCzas2); }

 

Edytowano przez Belferek
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.