bieri13 Napisano Marzec 16, 2020 Udostępnij Napisano Marzec 16, 2020 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 More sharing options...
ethanak Marzec 16, 2020 Udostępnij Marzec 16, 2020 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 More sharing options...
bieri13 Marzec 16, 2020 Autor tematu Udostępnij Marzec 16, 2020 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 More sharing options...
Belferek Marzec 16, 2020 Udostępnij Marzec 16, 2020 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 More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
ethanak Marzec 16, 2020 Udostępnij Marzec 16, 2020 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 More sharing options...
Gość Marzec 16, 2020 Udostępnij Marzec 16, 2020 (edytowany) 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 Marzec 16, 2020 przez Gość Link do komentarza Share on other sites More sharing options...
ethanak Marzec 16, 2020 Udostępnij Marzec 16, 2020 2 minuty temu, atMegaTona napisał: Czas na pobranie próbki to siłą rzeczy czas próbkowania przez ADC Czyli dobrze mówiłem że pomijalny (ok. 100µs). Link do komentarza Share on other sites More sharing options...
bieri13 Marzec 16, 2020 Autor tematu Udostępnij Marzec 16, 2020 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 More sharing options...
ethanak Marzec 16, 2020 Udostępnij Marzec 16, 2020 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 More sharing options...
bieri13 Marzec 17, 2020 Autor tematu Udostępnij Marzec 17, 2020 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 More sharing options...
ethanak Marzec 17, 2020 Udostępnij Marzec 17, 2020 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 More sharing options...
bieri13 Marzec 18, 2020 Autor tematu Udostępnij Marzec 18, 2020 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 More sharing options...
ethanak Marzec 18, 2020 Udostępnij Marzec 18, 2020 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 More sharing options...
Gość Marzec 18, 2020 Udostępnij Marzec 18, 2020 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 More sharing options...
Belferek Marzec 18, 2020 Udostępnij Marzec 18, 2020 (edytowany) 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 Marzec 18, 2020 przez Belferek Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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ę »