Skocz do zawartości

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


Forseti

Pomocna odpowiedź

Witam szanowne grono.  

Planuję popełnić robota opartego o dwa programy działania tj. Program_1 (omijanie przeszkód) oraz Program_2 (sterowanie BT). Zależy mi na tym aby mieć możliwość przełączania trybów pracy za pomocą przełącznika ON/OFF/ON zgodnie z poniższym diagramem:

1588291795_Diagramsterujcy.thumb.jpg.7d7e81658f0d11978ccdbd0ea48a04db.jpg

Walczę z tematem od pewnego czasu i mam z nim nie lada problem. Jako absolutny laik w świecie Arduino (od ok 3 tyg.) oraz po konsultacji z @Gieneq postanowiłem założyć ten temat, celem pomocy osobom takim jak ja w ogarnięciu tematu jakim jest wielofunkcyjność programowa i możliwość przełączania programów za pomocą zewnętrznej, fizycznej ingerencji (przycisk/przełącznik). Chciałbym aby ten wątek, przy dobrych wiatrach, stał się swego rodzaju kompendium wiedzy z ww. zagadnienia dla osób mojego pokroju oraz co by nie dręczyli oni doświadczonych Forumowiczów :). 

Na początek wziąłem pod lupę prostą sprawę, a mianowicie sterowanie 4 diodami LED.  

Schemat.thumb.png.7dc337888266ed7046326a4289594375.png

Gwoli wyjaśnienia. Jeden przełącznik ON/OFF/ON jest symulowany za pomocą 3x przełączników. W zależności od odczytania stanu na każdym z nim diody odpowiednio symulują Program_1 lub Program_2. Stan OFF jest prezentowany przez miganie sekwencyjne wszystkich LEDów.

Kod programu:

//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
#define LED_1 8 //Symbolizuje Program 1
#define LED_2 9 //Symbolizuje Program 1
#define LED_3 10 //Symbolizuje Program 2
#define LED_4 11 //Symbolizuje Program 2
#define Przycisk_1 2
#define Przycisk_2 3
#define Przycisk_3 4


void setup() {
  pinMode(LED_1, OUTPUT); //Wyjście na LED 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED 2
  pinMode(LED_3, OUTPUT); //Wyjście na LED 3
  pinMode(LED_4, OUTPUT); //Wyjście na LED 4


  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

  digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona
  digitalWrite(LED_3, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_4, LOW); //Stan diody LED2 - wyłączona
}

void loop() {

  if (digitalRead(Przycisk_1) == LOW) { //Jeśli przycisk 1 jest włączony - Program 1 miganie ledów 1,2 na przemian
    digitalWrite(LED_1, HIGH); //Stan diody LED1 - włączona
    delay(100);
    digitalWrite(LED_2, HIGH); //Stan diody LED2 - włączona
    delay(100);
    digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
    delay(100);
    digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona
    delay(100);
  } else if (digitalRead(Przycisk_2) == LOW) { //Jeśli przycisk 2 jest włączony - Program 2 miganie ledów 3,4 jednocześnie
    digitalWrite(LED_3, HIGH); //Stan diody LED3 - włączona
    digitalWrite(LED_4, HIGH); //Stan diody LED4 - włączona
    delay(100);
    digitalWrite(LED_3, LOW); //Stan diody LED3 - wyłączona
    digitalWrite(LED_4, LOW); //Stan diody LED4 - wyłączona
    delay(100);
  } else if (digitalRead(Przycisk_3) == LOW) { //Tutaj wszystko off - LEDY dla efektu w linię
    digitalWrite(LED_1, HIGH); //Stan diody LED1 - włączona
    delay(100);
    digitalWrite(LED_2, HIGH); //Stan diody LED2 - włączona
    delay(100);
    digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
    delay(100);
    digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona
    delay(100);
    digitalWrite(LED_3, HIGH); //Stan diody LED1 - włączona
    delay(100);
    digitalWrite(LED_4, HIGH); //Stan diody LED2 - włączona
    delay(100);
    digitalWrite(LED_3, LOW); //Stan diody LED1 - wyłączona
    delay(100);
    digitalWrite(LED_4, LOW); //Stan diody LED2 - wyłączona
    delay(100);
  }
  else {

  }
}

 

Zachęcony powodzeniem jakże "skomplikowanego" zadania podjąłem próby implementacji rozwiązań j.w. do zmodernizowanego programu, który był tematem zadania 9.3 pracy domowej z Kurs Arduino – #9 – Czujnik odległości HC-SR04

Zasada działania jest analogiczna do powyższej z tym wyjątkiem, że teraz chcę sterować już funkcją bardziej zaawansowaną niż miganie LEDami.  Program_1 - linijka LED włączana w zależności od odległości obiektu od czujnika HC-SR04. Program_2 - Miganie niebieską diodą LED - symbol pracy programu nr 2.

Schemat.thumb.png.118170a42472daaeaf471a852d01a527.png

 

UWAGA! Na obecną chwilę utknąłem ponieważ nie wiem, w którym miejscu wprowadzić warunki if-else-if-else aby uzyskać efekt analogiczny do powyższego. Kod jest przygotowany do zmian i posiada już zdefiniowane elementy ze schematu (Przycisk_3, LED_5 niebieski).

Kod programu:

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

#define trigPin 12 //wejście wyzwalające
#define echoPin 11 //Odczyt zmierzonej odległości
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2
#define LED_3 4 //LED czerwona 1
#define LED_4 5 //LED czerwona 2
#define LED_5 6 //LED niebieska - Symbol innego programu
#define Przycisk_1 8
#define Przycisk_2 9
#define Przycisk_3 10

void setup() {

  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

  pinMode(trigPin, OUTPUT); //Trig jako wyjście - pomiar odległości
  pinMode(echoPin, INPUT); //ECHO jako wejście - odczyt zmierzonej odległości
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2
  pinMode(LED_3, OUTPUT); //Wyjście na LED czerwona 1
  pinMode(LED_4, OUTPUT); //Wyjście na LED czerwona 2
  pinMode(LED_5, OUTPUT); //Wyjście na LED niebieska - symulacja programu

  digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona
  digitalWrite(LED_3, LOW); //Stan diody LED3 - wyłączona
  digitalWrite(LED_4, LOW); //Stan diody LED4 - wyłączona
  digitalWrite(LED_5, LOW); //Stan diody LED5 - wyłączona

}

void loop() {

  zakres(10, 15, 20, 25, 30 ); //Włącz LEDY jeśli odległość 10,15,20,30 - poniżej 10 migaj 2x LED czerwony
  delay(100);
}

int zmierzOdleglosc() {
  long czas, dystans; //Zmienna przechowująca duże liczby - UWAGA! zużywa 4 bajty pamięci. Zawiera argumenty czas oraz dystans

  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); //Wejście wyzwalające - sygnał wysoki
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski

  czas = pulseIn(echoPin, HIGH); //Pomiar gdy na pinie echoPin stan wysoki - w tym przypadku PIN 11
  dystans = czas / 58; //Przelicznik 58 - z DTR producenta. Czas w jakim dźwięk przebywa 1cm w czasie 1 micro sek. - dystans w korelacji ze zmienną long i jej argumentem

  return dystans;
}

void zakres(int od_10cm, int od_15cm, int od_20cm, int od_25cm, int od_30cm) { //Funkcja sprawdzająca zakres w jakiej odległości jest obiekt
  int jakDaleko = zmierzOdleglosc(); //Zmienna - odniesienie do funkcji
  if ((jakDaleko > od_30cm) ) { //Jeżeli odległość jakDaleko > 30cm nic nie rób
    digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
    digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
    digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
    digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
  } else  if ((jakDaleko > od_25cm) ) { //Jeżeli odległość jakDaleko > 25cm
    digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
    digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
    digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
    digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
  } else  if ((jakDaleko > od_20cm) ) {//Jeżeli odległość jakDaleko > 20cm
    digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
    digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
    digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
    digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
  } else  if ((jakDaleko > od_15cm) ) {//Jeżeli odległość jakDaleko > 15cm
    digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
    digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
    digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
    digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
  } else  if ((jakDaleko > od_10cm) ) { //Jeżeli odległość jakDaleko > 10cm
    digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
    digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
    digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
    digitalWrite(LED_4, HIGH); //Włącz LED czerwona 2
  } else {
    digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
    digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
    digitalWrite(LED_4, HIGH); //Miganie LED czerwona 2
    digitalWrite(LED_3, HIGH); //Miganie LED czerwona 1
    delay(100);
    digitalWrite(LED_4, LOW); //Miganie LED czerwona 2
    digitalWrite(LED_3, LOW); //Miganie LED czerwona 1
    delay(100);

  }

}

 

Walczę z tematem i staram się rozwijać na tyle na ile pozwala mi czas. Liczę na pomoc szanownego grona doświadczonych Forumowiczów - radźcie 🙂 

 

PS. Docelowo może uda się rozwinąć temat o zastosowanie przycisków typu microswitch, przerwań, tablice zmiennych etc... Na początek jednak prosiłbym o pomoc w trywialnym dla doświadczonych programistów problemie laika.

 

Link do komentarza
Share on other sites

Cytat

 w którym miejscu wprowadzić warunki if-else-if-else aby uzyskać efekt analogiczny do powyższego.

Odpowiedziałeś sobie na to pytanie w komentarzach do pierwszego kodu:

void loop() {

  if (digitalRead(Przycisk_1) == LOW) { //Jeśli przycisk 1 jest włączony - Program 1 miganie ledów 1,2 na przemian
	
    //tu wstawiamy kod i funkcje, które wykonują się po wciśnięciu przycisku 1
    
  } else if (digitalRead(Przycisk_2) == LOW) { //Jeśli przycisk 2 jest włączony - Program 2 miganie ledów 3,4 jednocześnie
	
    //tu wstawiamy kod i funkcje, które wykonują się po wciśnięciu przycisku 2
    
  } else if (digitalRead(Przycisk_3) == LOW) { //Tutaj wszystko off - LEDY dla efektu w linię
		
    //tu wstawiamy kod i funkcje, które wykonują się po wciśnięciu przycisku 3
    
  }
  else {
	//rzeczy, które się dzieją, gdy żaden powyższy warunek nie jest spełniony
  }
}

Programem sterujemy z pętli (w tym przypadku). W klamry if-ów możemy wpisywać zarówno pojedyncze komendy (digitalRead, delay itd), jak i wywoływać konkretne funkcje zawarte w programie lub bibliotekach. Przykładowa pętla w drugim kodzie może więc wyglądać tak:

void loop() {  
  
  if (digitalRead(Przycisk_1) == LOW) { //Jeśli przycisk 1 jest włączony - Program 1 - linijka
	
    zakres(10, 15, 20, 25, 30 ); //Włącz LEDY jeśli odległość 10,15,20,30 - poniżej 10 migaj 2x LED czerwony
 	delay(100);
    
  } else if (digitalRead(Przycisk_2) == LOW) { //Jeśli przycisk 2 jest włączony - Program 2- niebieska dioda
	
    digitalWrite(LED_5,HIGH);			//miganie niebieską diodą
    delay(500);
    digitalWrite(LED_5,LOW);
    delay(500);
    
  } else if (digitalRead(Przycisk_3) == LOW) { //przycisk 3
		
    //jakieś inne rzeczy
    
  }
  else {
	
  }
}

 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

@Peposh - dziękuję za podpowiedź. Nie ukrywam, że poruszałem się w okolicy Twojej sugestii ale cały czas mam błąd w kodzie.

W pierwszym warunku if (Przycisk_1, Program_1) ująłem całą zawartość linijki. W warunku else-if ująłem drugi stan (Przycisk_2, Program_2). Całość spiąłem w klamry głównej pętli (loop).  Wyskakuje błąd braku zadeklarowania w danym zakresie.  Próbuję odszukać kościół, w którym dzwoni 🙂

Wrzucam sam void loop ()

void loop() {
  if (digitalRead(Przycisk_1) == LOW) { //Jeśli przycisk 1 jest włączony - Program 1 - linijka

    zakres(10, 15, 20, 25, 30 ); //Włącz LEDY jeśli odległość 10,15,20,30 - poniżej 10 migaj 2x LED czerwony
    delay(100);

    int zmierzOdleglosc() {
      long czas, dystans; //Zmienna przechowująca duże liczby - UWAGA! zużywa 4 bajty pamięci. Zawiera argumenty czas oraz dystans

      digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH); //Wejście wyzwalające - sygnał wysoki
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski

      czas = pulseIn(echoPin, HIGH); //Pomiar gdy na pinie echoPin stan wysoki - w tym przypadku PIN 11
      dystans = czas / 58; //Przelicznik 58 - z DTR producenta. Czas w jakim dźwięk przebywa 1cm w czasie 1 micro sek. - dystans w korelacji ze zmienną long i jej argumentem

      return dystans;
    }

    void zakres(int od_10cm, int od_15cm, int od_20cm, int od_25cm, int od_30cm) { //Funkcja sprawdzająca zakres w jakiej odległości jest obiekt
      int jakDaleko = zmierzOdleglosc(); //Zmienna - odniesienie do funkcji
      if ((jakDaleko > od_30cm) ) { //Jeżeli odległość jakDaleko > 30cm nic nie rób
        digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
        digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
        digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
        digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
      } else  if ((jakDaleko > od_25cm) ) { //Jeżeli odległość jakDaleko > 25cm
        digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
        digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
        digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
        digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
      } else  if ((jakDaleko > od_20cm) ) {//Jeżeli odległość jakDaleko > 20cm
        digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
        digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
        digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
        digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
      } else  if ((jakDaleko > od_15cm) ) {//Jeżeli odległość jakDaleko > 15cm
        digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
        digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
        digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
        digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
      } else  if ((jakDaleko > od_10cm) ) { //Jeżeli odległość jakDaleko > 10cm
        digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
        digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
        digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
        digitalWrite(LED_4, HIGH); //Włącz LED czerwona 2
      } else {
        digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
        digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
        digitalWrite(LED_4, HIGH); //Miganie LED czerwona 2
        digitalWrite(LED_3, HIGH); //Miganie LED czerwona 1
        delay(100);
        digitalWrite(LED_4, LOW); //Miganie LED czerwona 2
        digitalWrite(LED_3, LOW); //Miganie LED czerwona 1
        delay(100);
      }
      }
      }	else if (digitalRead(Przycisk_2) == LOW) { //Jeśli przycisk 2 jest włączony - Program 2- niebieska dioda
	    digitalWrite(LED_5, HIGH);			//miganie niebieską diodą
      	delay(500);
      	digitalWrite(LED_5, LOW);
      	delay(500);
      }
      	else {}
  	  }

 

Link do komentarza
Share on other sites

Nie możesz deklarować funkcji wewnątrz innej funkcji.

Czyli nie:
 

void loop()
{
	// jakiś kod, a w nim
	int funkcja(cośtam) {
	// kod funkcji
	} // koniec funkcji
    coś = funkcja(cośinnego);
  
} //koniec loop

tylko

int funkcja(cośtam)
{
    // kod funkcji
}

void loop()
{
   // kod loop a w nim
   cośtam = funkcja(cośinnego);
}

 

 

  • Pomogłeś! 1
Link do komentarza
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

14 godzin temu, Forseti napisał:

Na obecną chwilę utkalem gdzie wprowadzić warunki if-else-if-else aby uzyskać efekt analogiczny do powyższego.

A moze lepszym pomyslem bylo by zastosowanie "switch-case"? jakos tak prosciej by to wygladalo..

switch(jakDaleko) //wartosc odleglosci
{
  case 10 ... 14: //jesli jakDaleko = 10,11,12,13 lub 14 to wykonaj
     led1;
     break;
  case 15 ... 19:
     led1;
     led2;
     break;
  case 20 ... 24:
     led1;
     led2:
     led3:
     break;
}

led1/2/3 etc to tak dla przykladu..dodatkowo w funkcji  "zakres" nie musisz podawac argumentow jesli wartosci sie nie zmieniaja, a odrazu mozesz na "sztywno" wpisac wartosci jakie Cie interesuja..(oszczednosc pamieci) 

zakres();

void zakres() { //Funkcja sprawdzająca zakres w jakiej odległości jest obiekt
  int jakDaleko = zmierzOdleglosc(); //Zmienna - odniesienie do funkcji
  if ((jakDaleko > 30) ) { 
    // ble ble
    // ble ble ble
    // ble
    }
  if ((jakDaleko > 20) ) { 
    // ble ble
    // ble ble ble
    // ble
    }

 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

(edytowany)

Poprawiłem kod - @Peposh @ethanak o to chodziło?:

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

#define trigPin 12 //wejście wyzwalające
#define echoPin 11 //Odczyt zmierzonej odległości
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2
#define LED_3 4 //LED czerwona 1
#define LED_4 5 //LED czerwona 2
#define LED_5 6 //LED niebieska - Symbol innego programu
#define Przycisk_1 8
#define Przycisk_2 9
#define Przycisk_3 10


int zmierzOdleglosc() {
  long czas, dystans; //Zmienna przechowująca duże liczby - UWAGA! zużywa 4 bajty pamięci. Zawiera argumenty czas oraz dystans

  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); //Wejście wyzwalające - sygnał wysoki
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski

  czas = pulseIn(echoPin, HIGH); //Pomiar gdy na pinie echoPin stan wysoki - w tym przypadku PIN 11
  dystans = czas / 58; //Przelicznik 58 - z DTR producenta. Czas w jakim dźwięk przebywa 1cm w czasie 1 micro sek. - dystans w korelacji ze zmienną long i jej argumentem

  return dystans;
}

void setup() {

  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

  pinMode(trigPin, OUTPUT); //Trig jako wyjście - pomiar odległości
  pinMode(echoPin, INPUT); //ECHO jako wejście - odczyt zmierzonej odległości
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2
  pinMode(LED_3, OUTPUT); //Wyjście na LED czerwona 1
  pinMode(LED_4, OUTPUT); //Wyjście na LED czerwona 2
  pinMode(LED_5, OUTPUT); //Wyjście na LED niebieska - symulacja programu

  digitalWrite(LED_1, LOW); //Stan diody LED1 - wyłączona
  digitalWrite(LED_2, LOW); //Stan diody LED2 - wyłączona
  digitalWrite(LED_3, LOW); //Stan diody LED3 - wyłączona
  digitalWrite(LED_4, LOW); //Stan diody LED4 - wyłączona
  digitalWrite(LED_5, LOW); //Stan diody LED5 - wyłączona

}

void loop() {


  if (digitalRead(Przycisk_1) == LOW) {

    int jakDaleko = zmierzOdleglosc(); //Zmienna - odniesienie do funkcji
    if ((jakDaleko > 30) ) { //Jeżeli odległość jakDaleko > 30cm nic nie rób
      digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 25) ) { //Jeżeli odległość jakDaleko > 25cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 20) ) {//Jeżeli odległość jakDaleko > 20cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 15) ) {//Jeżeli odległość jakDaleko > 15cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 10) ) { //Jeżeli odległość jakDaleko > 10cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
      digitalWrite(LED_4, HIGH); //Włącz LED czerwona 2
    } else {
      digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_4, HIGH); //Miganie LED czerwona 2
      digitalWrite(LED_3, HIGH); //Miganie LED czerwona 1
      delay(100);
      digitalWrite(LED_4, LOW); //Miganie LED czerwona 2
      digitalWrite(LED_3, LOW); //Miganie LED czerwona 1
      delay(100);
    }
  }   else if (digitalRead(Przycisk_2) == LOW) { //Jeśli przycisk 2 jest włączony - Program 2- niebieska dioda

    digitalWrite(LED_5, HIGH);//Miganie LED niebieska - symulacja programu
    delay(500);
    digitalWrite(LED_5, LOW);
    delay(500);

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

}

Poprawiony schemat:

Schemat.thumb.png.cfbaff61d508bc3277b68a62d4206b0e.png

Generalnie działa. Przycisk_3 w sumie zbędny do tej symulacji ale zostawiam do dalszej rozbudowy programu.

@farmaceuta Podoba mi się Twoja sugestia z zastosowaniem warunku wielokrotnego wyboru. Program wygląda zdecydowanie zgrabniej. Z chęcią się tego nauczę i przedstawię wynik 

 

Edytowano przez Forseti
Dodany schemat
  • Lubię! 1
Link do komentarza
Share on other sites

Poszedłem o krok dalej. Rozbudowałem kod i zaimplementowałem 2 funkcje. Program_1 - linijka oraz Program_2 - odczyt odległości z czujnika. Program_3 - demonstrator działania przycisku

//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 - linijka
//Program_2 - odczyt danych przez Monitor portu

#define trigPin 12 //wejście wyzwalające
#define echoPin 11 //Odczyt zmierzonej odległości
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2
#define LED_3 4 //LED czerwona 1
#define LED_4 5 //LED czerwona 2
#define LED_5 6 //LED niebieska - Symbol innego programu
#define Przycisk_1 8
#define Przycisk_2 9
#define Przycisk_3 10


int zmierzOdleglosc() {
  long czas, dystans; //Zmienna przechowująca duże liczby - UWAGA! zużywa 4 bajty pamięci. Zawiera argumenty czas oraz dystans

  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); //Wejście wyzwalające - sygnał wysoki
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski

  czas = pulseIn(echoPin, HIGH); //Pomiar gdy na pinie echoPin stan wysoki - w tym przypadku PIN 11
  dystans = czas / 58; //Przelicznik 58 - z DTR producenta. Czas w jakim dźwięk przebywa 1cm w czasie 1 micro sek. - dystans w korelacji ze zmienną long i jej argumentem

  return dystans;
}

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

  //Obsługa czujnika odległości
  Serial.begin(9600); //Ustawienie prędkości transmisji
  pinMode(trigPin, OUTPUT); //Trig jako wyjście - pomiar odległości
  pinMode(echoPin, INPUT); //ECHO jako wejście - odczyt zmierzonej odległości

  //Wyprowadzenia LED
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2
  pinMode(LED_3, OUTPUT); //Wyjście na LED czerwona 1
  pinMode(LED_4, OUTPUT); //Wyjście na LED czerwona 2
  pinMode(LED_5, OUTPUT); //Wyjście na LED niebieska - symulacja programu

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

}

void loop() {


  if (digitalRead(Przycisk_1) == LOW) {

    int jakDaleko = zmierzOdleglosc(); //Zmienna - odniesienie do funkcji
    if ((jakDaleko > 30) ) { //Jeżeli odległość jakDaleko > 30cm nic nie rób
      digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 25) ) { //Jeżeli odległość jakDaleko > 25cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 20) ) {//Jeżeli odległość jakDaleko > 20cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 15) ) {//Jeżeli odległość jakDaleko > 15cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 10) ) { //Jeżeli odległość jakDaleko > 10cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
      digitalWrite(LED_4, HIGH); //Włącz LED czerwona 2
    } else {
      digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_4, HIGH); //Miganie LED czerwona 2
      digitalWrite(LED_3, HIGH); //Miganie LED czerwona 1
      delay(100);
      digitalWrite(LED_4, LOW); //Miganie LED czerwona 2
      digitalWrite(LED_3, LOW); //Miganie LED czerwona 1
      delay(100);
    }
  } else if (digitalRead(Przycisk_2) == LOW) { //Jeśli przycisk 2 jest włączony - Program_2 - odczyt danych przez Monitor portu

    digitalWrite(LED_5, HIGH);//Miganie LED niebieska - sygnalizacja stanu pracy Programu_2
    delay(500);
    digitalWrite(LED_5, LOW);
    delay(500);
    Serial.print(zmierzOdleglosc());
    Serial.println("cm");
    delay(500);

  } else if (digitalRead(Przycisk_3) == LOW) { //Jeśli przycisk 3 jest włączony - Program 3- niebieska dioda

    digitalWrite(LED_5, HIGH);//Miganie LED niebieska - symulacja programu
    delay(50);
    digitalWrite(LED_5, LOW);
    delay(50);

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

}

Pobawię się jeszcze z sugestiami @farmaceuta i spróbuję przejść do obsługi za pomocą microswitch'y. Z wolna zaczynam łapać o co chodzi. Dziękuję Wam za pomoc.

Link do komentarza
Share on other sites

10 minut temu, Forseti napisał:

Pobawię się jeszcze z sugestiami @farmaceuta i spróbuję przejść do obsługi za pomocą microswitch'y. Z wolna zaczynam łapać o co chodzi.

W "switch" podajesz jakas zmienna..pozniej numerujesz sobie "case" i teraz jesli zmienna bedzie miala np. wartosc 5 to wykona sie "case 5:" to taki "if else" wlasnie, tylko ze nie musisz tworzyc argumentow z osobna..

Link do komentarza
Share on other sites

Walczę z kodem aby w miejsce przełączników ON/OFF zastosować Microswitche. Poszedłem w stronę zapamiętywania stanu przycisku z warunkami if-else ale taka kompilacja nie działała. Postanowiłem skorzystać z pętli while. Na niej program odpala ale nadal nie jest to to o co chodzi - nie ma możliwości przełączania trybów w czasie pracy. Jeżeli np. włączę Program_1 to pozostałe przyciski tracą funkcjonalność i analogicznie reszta. Jeśli włączę Program_2 nie działają 1 oraz 3 itd. Wydaje mi się, że nie potrafię zatrzymać raz uruchomionej pętli while.

//Program symulujący pracę dwóch programów przełączanych za pomocą przełącznika ON/OFF lub suwakowego. Dwufunkcyjnego
//Przyciski typu microswitch
//Program_1 - linijka
//Program_2 - odczyt danych przez Monitor portu

#define trigPin 12 //wejście wyzwalające
#define echoPin 11 //Odczyt zmierzonej odległości
#define LED_1 2 //LED zielona 1
#define LED_2 3 //LED zielona 2
#define LED_3 4 //LED czerwona 1
#define LED_4 5 //LED czerwona 2
#define LED_5 6 //LED niebieska - Symbol innego programu
#define Przycisk_1 8 //Microswitch_1
#define Przycisk_2 9 //Microswitch_2
#define Przycisk_3 10 //Microswitch_3

int ostatniStan_1 = HIGH;  //Odczyt stanu wysokiego ponieważ przycisk wpięty z użyciem PULLUP
int ostatniStan_2 = HIGH;
int ostatniStan_3 = HIGH;

int zmierzOdleglosc() {
  long czas, dystans; //Zmienna przechowująca duże liczby - UWAGA! zużywa 4 bajty pamięci. Zawiera argumenty czas oraz dystans

  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); //Wejście wyzwalające - sygnał wysoki
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW); //Wejście wyzwalające - sygnał niski

  czas = pulseIn(echoPin, HIGH); //Pomiar gdy na pinie echoPin stan wysoki - w tym przypadku PIN 11
  dystans = czas / 58; //Przelicznik 58 - z DTR producenta. Czas w jakim dźwięk przebywa 1cm w czasie 1 micro sek. - dystans w korelacji ze zmienną long i jej argumentem

  return dystans;
}


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

  //Obsługa czujnika odległości
  Serial.begin(9600); //Ustawienie prędkości transmisji
  pinMode(trigPin, OUTPUT); //Trig jako wyjście - pomiar odległości
  pinMode(echoPin, INPUT); //ECHO jako wejście - odczyt zmierzonej odległości

  //Wyprowadzenia LED
  pinMode(LED_1, OUTPUT); //Wyjście na LED zielona 1
  pinMode(LED_2, OUTPUT); //Wyjście na LED zielona 2
  pinMode(LED_3, OUTPUT); //Wyjście na LED czerwona 1
  pinMode(LED_4, OUTPUT); //Wyjście na LED czerwona 2
  pinMode(LED_5, OUTPUT); //Wyjście na LED niebieska - symulacja programu

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

}

void loop() {

  int stan_1 = digitalRead(Przycisk_1); // Ostatni stan przycisku
  int stan_2 = digitalRead(Przycisk_2); // Ostatni stan przycisku
  int stan_3 = digitalRead(Przycisk_3); // Ostatni stan przycisku

  while (ostatniStan_1 == HIGH && stan_1 == LOW) { //Jeśli przycisk wciśnięty to włącz

    int jakDaleko = zmierzOdleglosc(); //Zmienna - odniesienie do funkcji
    if ((jakDaleko > 30) ) { //Jeżeli odległość jakDaleko > 30cm nic nie rób
      digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 25) ) { //Jeżeli odległość jakDaleko > 25cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 20) ) {//Jeżeli odległość jakDaleko > 20cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, LOW); //Wyłącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 15) ) {//Jeżeli odległość jakDaleko > 15cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
      digitalWrite(LED_4, LOW); //Wyłącz LED czerwona 2
    } else  if ((jakDaleko > 10) ) { //Jeżeli odległość jakDaleko > 10cm
      digitalWrite(LED_1, HIGH); //Włącz LED zielona 1
      digitalWrite(LED_2, HIGH); //Włącz LED zielona 2
      digitalWrite(LED_3, HIGH); //Włącz LED czerwona 1
      digitalWrite(LED_4, HIGH); //Włącz LED czerwona 2
    } else {
      digitalWrite(LED_1, LOW); //Wyłącz LED zielona 1
      digitalWrite(LED_2, LOW); //Wyłącz LED zielona 2
      digitalWrite(LED_4, HIGH); //Miganie LED czerwona 2
      digitalWrite(LED_3, HIGH); //Miganie LED czerwona 1
      delay(100);
      digitalWrite(LED_4, LOW); //Miganie LED czerwona 2
      digitalWrite(LED_3, LOW); //Miganie LED czerwona 1
      delay(100);
    }

  } while (ostatniStan_2 == HIGH && stan_2 == LOW) { //Jeśli przycisk 2 jest włączony - Program_2 - odczyt danych przez Monitor portu

    digitalWrite(LED_5, HIGH);//Miganie LED niebieska - sygnalizacja stanu pracy Programu_2
    delay(500);
    digitalWrite(LED_5, LOW);
    delay(500);
    Serial.print(zmierzOdleglosc());
    Serial.println("cm");
    delay(500);

  } while (ostatniStan_3 == HIGH && stan_3 == LOW) { //Jeśli przycisk 3 jest włączony - Program 3- niebieska dioda

    digitalWrite(LED_5, HIGH);//Miganie LED niebieska - symulacja programu
    delay(50);
    digitalWrite(LED_5, LOW);
    delay(50);

  }

  ostatniStan_1 = stan_1; //odczytaj stan przycisku_1
  delay(50); //Opóźnienie na drgania
  ostatniStan_2 = stan_2; //odczytaj stan przycisku_2
  delay(50); //Opóźnienie na drgania
  ostatniStan_3 = stan_3; //odczytaj stan przycisku_3
  delay(50); //Opóźnienie na drgania

}

Schemat_przycisk.thumb.png.78db96503fb060918ff86b5d8057c7dc.png

Spróbuję jeszcze przerobić na switch case. Może to będzie lepsze rozwiązanie. 

 

 

 

Link do komentarza
Share on other sites

35 minut temu, Forseti napisał:

@farmaceuta Zatem odejdę od pętli while. Nauczka. 

Petla while jest bardzo przydatna, ale musisz pamietac ze jesli argumentem jest zmienna to po wejsciu w ta petle modyfikacja tej zmiennej musi zachodzic w tej petli...tak jak miales teraz to w while juz zostajesz bo zmienna w argumencie jest modyfikowana poza ta petla, wiec nigdy nie ulegnie zmianie w while...

A co do tych switchy to rozumiem ze beda rozne kombinacje na trzech switchach tak? W sensie jak np. pierwszy wlaczony to program1..jak drugi i pierwszy to program2 itp?

Link do komentarza
Share on other sites

No to w takim razie najprostrze co mi przychodzi do glowy...

uint8_t tryb_program = 0;

if (digitalRead(switch1) == LOW) {
  tryb_program = 0;
  }
if (digitalRead(switch2) == LOW) {
  tryb_program = 1;
  }
if (digitalRead(switchoff) == LOW) {
  tryb_program = 2;
  }

switch(tryb_program)   {
  case 0:
      //program pierwszy...
  break;
  case 1:
      //program drugi...
  break;
  case 2:
      //program off...
  break;
 }

tylko pamietac musisz ze "switchoff" wylacza...jezeli np. mialbys sytuacje ze wlaczasz najpierw "switch1" potem "switch2", po czym wylaczasz "switch1" i dalej "switch2" to pomimo ze wszystkie switche sa wylaczone to wykonujesz program2...chodzi o kolejnosc.

Dopiero switchoff powoduje ze wykonuje sie twoja opcja "off"

Edit...chociaz zmienna "tryb" mozesz umiescic na gorze w "loop" i tak sobie ustawic ze wartosc "0" nie robi nic w programie...wtedy opcja "off" niepotrzebna..

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

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.