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
Link to post
Share on other sites

@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 ? 

Link to post
Share on other sites
(edytowany)

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

Edytowano przez _LM_
Link to post
Share on other sites
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..

Link to post
Share on other sites
(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
Link to post
Share on other sites

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
Link to post
Share on other sites

@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
Link to post
Share on other sites
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 🙂

Link to post
Share on other sites
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
Link to post
Share on other sites
(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
Link to post
Share on other sites
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. 

 

Link to post
Share on other sites

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.

Link to post
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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

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