Skocz do zawartości

HC-SR04 - Wielofunkcyjność programowa na podstawie czujnika odległości. Modyfikacja programu


Pomocna odpowiedź

(edytowany)

Na obecną chwilę warto podsumować i zebrać w jeden post rozwiązanie kwestii wielofunkcyjności programowej, dającej możliwość przełączania trybów pracy za pomocą przełącznika ON/OFF/ON, zgodnie z poniższym diagramem:

Diagram sterujący.jpg

Rozwiązanie powyższego zagadnienia zależy od tego czy chcemy sterować za pomocą przycisków monostabilnych (microswitch) czy bistabilnych (np. przełącznik suwakowy czy kołyskowy). 

Wersja 1 - Przełącznik bistabilny ON/OFF/ON

Program oparty o warunkowanie IF-ELSE-IF:

Schemat_ONOFF.thumb.png.a51b6fb74de6e73fa8f2edcd52083560.png

 

//Program symulujący pracę dwóch programów przełączanych za pomocą przełącznika ON/OFF/ON lub suwakowego.
//Nie dotyczy przycisków typu microswitch
//Program_1 - LED 1
//Program_2 - LED 2

#define Przycisk_1 8 //Przełącznik_1
#define Przycisk_2 9 //Przełącznik_2
#define Przycisk_3 10 //Przełącznik_3
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2

void setup () {
  //Wyprowadzenie przycisków
  pinMode(Przycisk_1, INPUT_PULLUP); //Wejście przycisku 1 w trybie PULLUP
  pinMode(Przycisk_2, INPUT_PULLUP); //Wejście przycisku 2 w trybie PULLUP
  pinMode(Przycisk_3, INPUT_PULLUP); //Wejście przycisku 3 w trybie PULLUP

  //Wyprowadzenia LED
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2

  //Ustawienie wyjściowego stanu LED
  digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona
}

void loop() {

  if (digitalRead(Przycisk_1) == LOW) { //Jeśli Przycisk_1 jest włączony - Program_2
    digitalWrite(LED_1, HIGH);
    digitalWrite(LED_2, LOW);
    //Włącz LED zielona 1 - PROGRAM 1

  } else if (digitalRead(Przycisk_2) == LOW) { //Jeśli Przycisk_2 jest włączony - Program_2

    digitalWrite(LED_1, LOW);
    digitalWrite(LED_2, HIGH);
    //Włącz LED zielona 2 - PROGRAM 2

  } else if (digitalRead(Przycisk_3) == LOW) { //Jeśli Przycisk_3 jest włączony - Stan OFF

    digitalWrite(LED_1, LOW);
    digitalWrite(LED_2, LOW);
    //Wyłącz LED - Symulacja Stan OFF

  } else {
    digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
    digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
  }
}

 

Wersja 2 - Przełącznik monostabilny (microswitch)

Schemat_przycisk.thumb.png.c92f4e5360f4b306dd5a32141de8cc77.png

Program oparty o warunkowanie switch case. 

//Program symulujący pracę dwóch programów przełączanych za pomocą przełącznika monostabilnego
//Przyciski typu microswitch
//Program_1 - LED 1
//Program_2 - LED 2

#define Przycisk_1 8 //Microswitch_1
#define Przycisk_2 9 //Microswitch_2
#define Przycisk_3 10 //Microswitch_3
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2

uint8_t tryb_program = 0; //Zmienna trybu programu

void setup () {
  //Wyprowadzenie przycisków
  pinMode(Przycisk_1, INPUT_PULLUP); //Wejście przycisku 1 w trybie PULLUP
  pinMode(Przycisk_2, INPUT_PULLUP); //Wejście przycisku 2 w trybie PULLUP
  pinMode(Przycisk_3, INPUT_PULLUP); //Wejście przycisku 3 w trybie PULLUP

  //Wyprowadzenia LED
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2


  //Ustawienie wyjściowego stanu LED
  digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona

}

void loop () {

  if (digitalRead(Przycisk_1) == LOW) {
    tryb_program = 1; //Warunek - sprawdzenie stanu - jeśli Przycisk_1 włączony
  }
  if (digitalRead(Przycisk_2) == LOW) {
    tryb_program = 2; //Warunek - sprawdzenie stanu - jeśli Przycisk_2 włączony
  }
  if (digitalRead(Przycisk_3) == LOW) {
    tryb_program = 3; //Warunek - sprawdzenie stanu - jeśli Przycisk_3 włączony
  }

  switch (tryb_program) {

    case 1:
      digitalWrite(LED_1, HIGH);
      digitalWrite(LED_2, LOW);
      //Włącz LED zielona 1 - PROGRAM 1
      break;
    case 2:
      digitalWrite(LED_1, LOW);
      digitalWrite(LED_2, HIGH);
      //Włącz LED zielona 2 - PROGRAM 2
      break;
    case 3:
      digitalWrite(LED_1, LOW);
      digitalWrite(LED_2, LOW);
      //Wyłącz LED - Stan OFF
      break;
  }
}

 

Przykład implementacji jednego z powyższych rozwiązań do bardziej zaawansowanego kodu.

Oczywiście kod ten można usprawnić co, zgodnie z sugestiami, zamierzam zrobić 🙂

Edytowano przez Forseti
  • Lubię! 1

@farmaceuta  A zdecydowanie tak. Jeszcze nie wiem jak to zrobić ale jak wspominałem ten kod jest rozwojowy. Przypuszczam, że powinienem się kierować w stronę takiego założenia:

  1. Jeśli przycisnę pierwszy raz przycisk - Program_1
  2. Jeśli przycisnę drugi raz przycisk - Program_2
  3. Jeśli przycisnę trzeci raz przycisk - OFF

Czyli zapamiętanie i porównanie stanu przycisku ? 

(edytowany)

Farmaceucie pewnie chodziło o to że co klik przycisku przełącza się funkcja no czyli tak jak napisałeś 

Edytowano przez _LM_
8 minut temu, Forseti napisał:

Jeśli przycisnę pierwszy raz przycisk - Program_1

  1. Jeśli przycisnę drugi raz przycisk - Program_2
  2. Jeśli przycisnę trzeci raz przycisk - OFF

Dokladnie tak...wystarczy zrobic jeden if i za kazdym wcisnieciem guzika dodawac o 1 do "tryb_programu"...ale tu juz trzeba zrobic jakis "opuzniacz" dla guzika zeby nie wystepowal negatywny skutek drgan stykow...(teraz ten efekt wystepuje ale jest nie istotny bo za kazdym razem w if przypisujesz ta sama wartosc do zmiennej) tylko w takiej opcji mozesz zmieniac tylko kolejno, czyli program..0/1/2/3..0/1/2/3 itd. 

Mozna tez sie polakomic i zrobic tak ze powiedzmy przez 2s sprawdzasz ile razy guzik wcisniety a po uplywie tego czasu odpowiednio wykonujesz...taki sposob daje Ci mozliwosc przeskoku z kazdego podprogramu do dowolnie innego np...0/1/3/2/3/0/1/3 itp...

15 minut temu, _LM_ napisał:

Farmaceucie pewnie chodziło o to że co klik przycisku przełącza się funkcja no czyli tak jak napisałeś 

Dokladnie😉 puki pinow nie brakuje to taki sposob moze byc zbedy..w przeciwnym razie to juz koniecznosc..

(edytowany)

@farmaceuta  Walczę z tematem 🙂 Uzupełniłem kod o metodę "zatrzasku" @Gieneq i idę w kierunku odczytania stanu przycisku. Póki co jeszcze nie doszedłem jak zawrócić program. Przełącza się pomiędzy case ale nie rozpoczyna na nowo.

//Program symulujący pracę dwóch programów przełączanych za pomocą przełącznika monostabilnego
//Przyciski typu microswitch
//Program_1 - LED 1
//Program_2 - LED 2

#define Przycisk_1 8 //Microswitch_1
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2

uint8_t tryb_program = 0; //Zmienna trybu programu
int ostatniStan = HIGH; //PULLUP

void setup () {
  //Wyprowadzenie przycisków
  pinMode(Przycisk_1, INPUT_PULLUP); //Wejście przycisku 1 w trybie PULLUP

  //Wyprowadzenia LED
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2

  //Ustawienie wyjściowego stanu LED
  digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona

}

void loop () {

  int aktualnyStan = digitalRead(Przycisk_1);

  if (ostatniStan == HIGH &&  aktualnyStan == LOW)  {//Jeśli ostatni stan był wyłączony i aktualny stan jest włączony to:
    tryb_program += 1; //Warunek - sprawdzenie stanu - jeśli Przycisk_1 włączony
  }

  switch (tryb_program) {

    case 1:
      digitalWrite(LED_1, HIGH);
      digitalWrite(LED_2, LOW);
      //Włącz LED zielona 1 - PROGRAM 1
      break;
    case 2:
      digitalWrite(LED_1, LOW);
      digitalWrite(LED_2, HIGH);
      //Włącz LED zielona 2 - PROGRAM 2
      break;
    case 3:
      digitalWrite(LED_1, LOW);
      digitalWrite(LED_2, LOW);
      //Wyłącz LED - Stan OFF
      break;
  }
  ostatniStan = aktualnyStan;
  delay(50);
}

 

Edytowano przez Forseti

Narazie dodaj taka poprawke...

if (ostatniStan == HIGH &&  aktualnyStan == LOW)  {//Jeśli ostatni stan był wyłączony i aktualny stan jest włączony to:
    tryb_program++; //inkrementacja(dodaj 1)
  if (tryb_program > 3) { //jesli przekroczysz ilosc podprogramow to zacznij liczyc odnowa..
    tryb_program = 0;
    }
  }

I bedziesz mial opcje..0/1/2/3/0/1/2/3 etc..😉

  • Pomogłeś! 1

@farmaceuta No tak... warunek IF w warunku IF... teraz to takie oczywiste 😡 - ale lekcja super. Do tego dodałem opóźnienie i przełączanie reaguje bardzo ładnie na kliknięcia microswitcha. Thx

  • Lubię! 1
2 minuty temu, farmaceuta napisał:

Wszystko na spokojnie ogarniesz😊 a nastepnie to jeszcze ta ilosc klikniec sie zrobi i bedzie do wyboru..

Myślałem, o zmiennej byte (mało zajmuje miejsca w pamięci) do zapamiętywania ilości kliknięć ale to na następny raz - pewnie znów mi się popierniczy ale grunt, że coś wychodzi i niewiele brakuje mi do rozwiązania danego problemu - to cieszy 🙂

Cytat

Myślałem, o zmiennej byte (mało zajmuje miejsca w pamięci) do zapamiętywania ilości kliknięć 

Do zapamiętywania małych liczb możesz użyć ośmiobitowego integera: 

int zmienna_1; //"zwykły" int, zajmuje 2 bajty pamięci(16 bit) i przyjmuje wartości od -32768 do 32767
uint8_t zmienna_2; //int ośmiobitowy(1 bajt), przyjmuje wartości od 0 do 255.

Oczywiście trzeba uważać, żeby nie przekroczyć zakresu tej zmiennej.

  • Lubię! 1
(edytowany)

coś wam pokażę 😉

if(!digitalRead(Przycisk_1))tryb_program++;

switch(tryb_program % 4){
  case 0:...
    ....
}

P.S jest tu drobny BUG. Gdzie?

 

Edytowano przez _LM_
post script
  • Lubię! 1
1 godzinę temu, _LM_ napisał:

P.S jest tu drobny BUG. Gdzie?

Reszta z dzielenia...(modulo) czyli 

1 % 4 = 1 //reszty 1 bo niepodzielna
2 % 4 = 2 
3 % 4 = 3
4 % 4 = 0 //zero bo brak reszty. 

 

Ten kod zadziała patrz że nie trzeba sprawdzać nawet wartości tryb_program, mimo to w jednej okoliczności działanie będzie niepożądane.

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...