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

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

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.