• 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
miganie 20x4
#11
Jak się uda coś rozwiązać to miło by było pokazać działające rozwiązanie. Mam nadzieję, że mówisz serio z wyrzuceniem delay, bo są lepsze sposoby zarządzania czasem w procesorze. Nie denerwuje Cię też działanie przycisku? Tu masz przykład jak zapikać buzerem przez 10s nie zatrzymując programu:
Kod:
const int buzzer=13;
const int button=2;
boolean stanbuzzera=0;

void setup() {
 // put your setup code here, to run once:
pinMode(buzzer,OUTPUT);
pinMode(button,INPUT_PULLUP);

}

void loop() {
 // put your main code here, to run repeatedly:
 if(!digitalRead(2)||stanbuzzera)  dzwiek(500,10,buzzer);
 
 

}

void dzwiek(uint16_t dlugosc, uint16_t pikniec, uint16_t pin) //(dlugosc piku, ile pikniec, na ktory pin)
{
 static uint16_t aktualnyPik=0;
static boolean stanpoprzedni=0;
static uint32_t lasttime=0;
uint32_t currenttime=millis();
// na razie zakladam 5 pikniec co 1000ms
if(currenttime-lasttime>=(uint32_t)dlugosc)
{
 lasttime=currenttime;
 if( aktualnyPik++ <(pikniec*2))//mnozymy *2 by pikniec bylo 10, nie zmian stanu
 {
   digitalWrite(pin,!digitalRead(pin));
   stanbuzzera=1;
 }
 else
 {
  aktualnyPik=0;
  stanbuzzera=0;
 }

}
 
}
Millis jest tylko nieco mniej prymitywne od delay w zarządzaniu czasem, ale to już zapewnia działanie w czasie rzeczywistym programu. Obsługe przycisku fajnie rozwiązuje biblioteka bounce2.
 
Odpowiedź
#12
(22-11-2018, 07:58)kaczakat napisał(a): Jak się uda coś rozwiązać to miło by było pokazać działające rozwiązanie. Mam nadzieję, że mówisz serio z wyrzuceniem delay, bo są lepsze sposoby zarządzania czasem w procesorze. Nie denerwuje Cię też działanie przycisku? Tu masz przykład jak zapikać buzerem przez 10s nie zatrzymując programu:
Kod:
const int buzzer=13;
const int button=2;
boolean stanbuzzera=0;

void setup() {
 // put your setup code here, to run once:
pinMode(buzzer,OUTPUT);
pinMode(button,INPUT_PULLUP);

}

void loop() {
 // put your main code here, to run repeatedly:
 if(!digitalRead(2)||stanbuzzera)  dzwiek(500,10,buzzer);
 
 

}

void dzwiek(uint16_t dlugosc, uint16_t pikniec, uint16_t pin) //(dlugosc piku, ile pikniec, na ktory pin)
{
 static uint16_t aktualnyPik=0;
static boolean stanpoprzedni=0;
static uint32_t lasttime=0;
uint32_t currenttime=millis();
// na razie zakladam 5 pikniec co 1000ms
if(currenttime-lasttime>=(uint32_t)dlugosc)
{
 lasttime=currenttime;
 if( aktualnyPik++ <(pikniec*2))//mnozymy *2 by pikniec bylo 10, nie zmian stanu
 {
   digitalWrite(pin,!digitalRead(pin));
   stanbuzzera=1;
 }
 else
 {
  aktualnyPik=0;
  stanbuzzera=0;
 }

}
 
}
Millis jest tylko nieco mniej prymitywne od delay w zarządzaniu czasem, ale to już zapewnia działanie w czasie rzeczywistym programu. Obsługe przycisku fajnie rozwiązuje biblioteka bounce2.

Cytat:Nie denerwuje Cię też działanie przycisku? 
Jeżeli chodzi o samo działanie to spełnia to swoją funkcję, ale jeżeli chodzi o sam kod to faktycznie jest on trochu pogmatwany. Chyba go zmienię. W ogóle to planuję do tego termostatu dołożyć obsługę serwa i menu ponieważ jest jeden warunek na który też chciałbym mieć wpływ a nawstawjać przycisków to nie sztuka. 
   Poprawiony kod wstawię oczywiście później.

Co do millis.....  zawsze miałem z tym problemy.
 
Odpowiedź
#13
https://pastebin.com/f6kHhEh6

To poprawiony kod. W sumie to faktycznie użycie delay w pipkaniu blokuje trochę program. Teraz to widzę.
 
Odpowiedź
#14
Z delay łatwo zacząć, trudno skończyć. Można wyobrazić sobie program jako koło fortuny, a to jest już prosta zabawa.
Pętla loop jak koło fortuny, nagrody to poszczególne polecenia, każda przegródka to cykl zegara. Loop z jednym poleceniem kręci się 16mln/s (załóżmy w uproszczeniu, tyle ile zegar), robisz delay to władasz patyk w szprychy i zatrzymujesz to na długo za długo.
Jest OK, jak to jest tylko to jedno polecenie. Jak ich jest 1000 to wszystkie czekają jak zabierzesz blokadę, no ale w tym czasie mogły się zadziać różne rzeczy, ekran się zatrzymał, wciśniętego przycisku nikt nie zauważył. Z millis do koła w jednym punkcie ktoś doczepia karteczki ze zliczonymi ms, ty sobie sprawdzasz w innym punkcie jaki czas upłynął po każdym okrążeniu, jeśli minął czas na np. piknięcie to doczepiasz flagę piknij i w innym punkcie koła if zmieni stan wyjścia buzera, flagę zrzuci do kosza, by następnym obiegiem nie zmienić niepotrzebnie znowu (za np. 5us). Jak zamiast prostej instrukcji jest funkcja to niestety program przeskakuje w tym punkcie na boczne pole lub nawet koło (w sumie delay jest takim bocznym loop i jedynym jego zadaniem jest czekanie), główne jest zatrzymane. Pełnia szczęścia jak wszystko jest tak szybkie, że użytkownik programu nie widzi takich zatrzymań, a z funkcjami jednak jest łatwiej ogarnąć większy program. I jeśli większość instrukcji jest wykonywana w jednym cyklu, część w kilka, a nawet jeśli  jakaś MEGA funkcja trwa nawet 16000 cyknięć, to i tak w sekundę zrobić ich można 1000. No a z delay 1000 można zrobić 0.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości