Kontempluj
:
Kod PHP:
const int ledPin = LED_BUILTIN;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
static int ledStan = LOW;
unsigned long aktualneMillis = millis();
static unsigned long nastepnyKrok;
if ( aktualneMillis > nastepnyKrok ) {
switch (ledStan) {
case 0:
ledStan = 1;
nastepnyKrok = aktualneMillis + 1000;
break;
case 1:
ledStan = 0;
nastepnyKrok = aktualneMillis + 2000;
break;
}
digitalWrite(ledPin, ledStan);
}
}
Użycie switch do migania diodą nie jest jakoś specjalnie lepsze od if..else jest ale jest to wstęp do maszyny stanów(sekwencji kroków).
Witam,
Poprzednik zapomniał dodać, że zwyczajowo używa się:
- instrukcji if...else (lub samo if)- w przypadku obsługi dwóch stanów,,
- switch...case- dla większej ilości stanów.
Pozdrawiam.
(20-03-2017, 15:38)Smaczek napisał(a): [ -> ]Poprzednik zapomniał dodać, że zwyczajowo używa się:
- instrukcji if...else (lub samo if)- w przypadku obsługi dwóch stanów,,
- switch...case- dla większej ilości stanów.
Zwyczajowo to porponuję przetrzeć oczęta bo wyraźnie napisałem:
(18-03-2017, 21:35)namok napisał(a): [ -> ]Użycie switch do migania diodą nie jest jakoś specjalnie lepsze od if..else jest ale jest to wstęp do maszyny stanów(sekwencji kroków).
Witam i przepraszam za niezbyt częste wizyty na forum. Z braku czasu musze odkładać pewne rzeczy na potem.
Ale chwilę dziennie poświęcam na kurs "Arduino od podstaw" Pana Tomasza Kubisztala.
I przypadł mi do gustu jeden jego projekt a mianowicie "Migajaca dioda petla FOR".
Niewiele czasu trzeba było aby przerobić szkic żeby dioda migała bez końca po naciśnięciu przycisku.
Ale Pan zrobił szkic na bazie "opóźnienia" DELAY, a mi zależy na działaniu na "Millis'ach".
I niestety to nie jest już takie proste dla mnie. Podejrzewam też, że dla funkcji "switch- case" pętlę FOR można zastąpić.
I też dioda będzie migała.
Kolego NAMOK.
Podałeś mi gotowca z wykorzystaniem switch case. Jestem wdzięczny. Ale i tak są to dla mnie czary mary.
Bo operowanie stanami na dowolnym pinie mikrokontrolera jest nie do przeskoczenia. Wiem, że są dwa (0/1) i to tyle.
Dziękuję. Poczytam jeszcze trochę i spać.
Witam. Jeszcze raz proszę o pomoc. Proszę o nakierowanie w utworzeniu funkcji do monitoringu stanu przycisku. Nie wiem jak to ugryźć. Chcę tylko uruchomić miganie diodą za pomocą przycisku. Ale przy użyciu funkcji millis() a nie delay(). Bo to drugie mi działa. Nie wiem jak napisać szkic, tak aby po puszczeniu palca z przycisku pętla wykonywała się nadal. Proszą o podpowiedź w temacie.
Ps.
Czytam i oglądam kursy, poradniki, fora itp. na temat ale mogę skleić faktów.
(04-04-2017, 16:20)Fuks81 napisał(a): [ -> ]Nie wiem jak napisać szkic, tak aby po puszczeniu palca z przycisku pętla wykonywała się nadal. Proszą o podpowiedź w temacie.
Ps.
Czytam i oglądam kursy, poradniki, fora itp. na temat ale mogę skleić faktów.
Nie możesz skleić faktów bo chcesz je skleić bez zrozumienia zasady działania.
Bez nauki samo nie przyjdzie.
Tu:
http://forum.arduinopolska.com/watek-dod...68#pid5768 masz przykład jednokrotnego wykonania polecenia po określonym czasie. Przerób w oparciu o BlinkWithoutDelay a będziasz miał ciągłe wykonywanie polecenia.
Witam. Kolego Namok, co prawda mam już szkic spełniający moje oczekiwania z pierwszego postu (przerobiony szkic z biblioteki "OneButton.h") ale to nie oto chodzi.
Wedle Twoich wskazówek połączyłem BlinkWithoutDelay z częścią szkicu Kolegi ferdricco i wyszło mi takie cuś:
Kod:
const int ledPin = LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;
int przycisk = 2;
int stanPrzycisku;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(przycisk, INPUT_PULLUP);
}
void migacz(){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
void loop() {
if(digitalRead(przycisk) == LOW){
delay(20);
stanPrzycisku=!stanPrzycisku;
while(digitalRead(przycisk) == LOW);
delay(20);
}
if(stanPrzycisku == HIGH){
migacz();
}
}
Nie jest to wersja idealna, ale nie jest zła.
Chodzi o stan w którym pozostaje dioda led po ponownym wciśnięciu przycisku.
Proszę o komentarz.
Jeśli ma to ręce i nogi, to pokombinuję z kodem do pojedynczego lub podwójnego mignięcia diodą w zależności od stanu. Tak jak radziłeś w/w wątku.
(06-04-2017, 21:53)Fuks81 napisał(a): [ -> ]Nie jest to wersja idealna, ale nie jest zła.
Chodzi o stan w którym pozostaje dioda led po ponownym wciśnięciu przycisku.
Proszę o komentarz.
Opisz dokładnie co masz na myśli z tą diodą to szybciej znajdziemy rozwiązanie.
Skoro używasz millis() to używaj wszędzie, przycisk aż prosi się żeby to zastosować.
"previousMillis" zdefiniuj w funkcji migacz z użyciem modyfikatora "static".
Witam. Z ciężkim bólem kod przerobiony na użycie samego millis(). Błąd z dioda pozostał.
W szkicu led na pinie 12 sygnalizuje działanie funkcji migacz a led_builtin wskazuje stan przycisku. I w sytuacji gdy stan led na pinie 13 jest HIGH to funkcja migacz działa poprawnie. Lecz jeśli stan przycisku się zmieni na przeciwny( led_bultin gaśnie ) w momencie gdy led na pinie 12 jest w stanie HIGH , to już taki zostaje do momentu zmiany stanu przycisku. Mam nadzieję, że zrozumiale to opisałem.
A poza tym sklejenie dwóch przykładów (BlinkWithoutMillis + Debounce) tyle czasu ponieważ wiedziałem, że muszę wstawić odpowiedni warunek do działania kodu. Problem w tym, że nie wiedziałem gdzie go wstawić. Poradniki tego nie "mówią".
Kod:
const int ledPin = LED_BUILTIN;
int ledPin1 = 12;
int ledState1 = LOW;
static int ledState = LOW;
const long interval = 500;
int przycisk = 2;
int stanPrzycisku;
int poprzedniStanPrzycisku = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(ledPin1, OUTPUT);
pinMode(przycisk, INPUT_PULLUP);
}
void migacz() {
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (ledState1 == HIGH) {
if ( currentMillis - previousMillis >= interval ) {
ledState1 = LOW;
previousMillis = currentMillis;
}
}
else {
if ( currentMillis - previousMillis >= interval * 5 ) {
ledState1 = HIGH;
previousMillis = currentMillis;
}
digitalWrite(ledPin1, ledState1);
}
}
void loop() {
int odczyt = digitalRead(przycisk);
if (odczyt != poprzedniStanPrzycisku) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (odczyt != stanPrzycisku) {
stanPrzycisku = odczyt;
if (stanPrzycisku == LOW) {
ledState = !ledState;
}
digitalWrite(ledPin, ledState);
}
}
poprzedniStanPrzycisku = odczyt;
if (ledState == HIGH) {
migacz();
}
}
Ten kod jest z dwoma opóźnieniami. Zasada ta sama.
Nie chce mi się analizować szczegółowo programu bo opis jest niejasny i używasz nazw które mylą. Nazwy diod powinny być w stylu ledStanPrzycisku i ledMiga.
Prawdopodobnie w funkcji migacz() w złym miejscu jest instrukcja "digitalWrite(ledPin1, ledState1);". Teraz wykonuje się gdy "ledState1 <> HIGH".