Skocz do zawartości

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


Pomocna odpowiedź

Sorki za taką prywatę ale liczyłem że będzie to naturalna kontynuacja kursu który oczywiście doceniam. EOT

(edytowany)

No a jak bys zrobil ten pomiar w jednej funkcji...w sensie podczas pomiaru wykonuje sie jedna funkcja i po jej opuszczeniu reszta kodu...

Edit...fajny ten silnik...ja robilem w wersji gamma...z malej puszki po kukurydzy, plyty cd etc...doszedlem do takiej wprawy ze silnik zasuwal naprawde efektownie (bardzo szybko) na kubku po jogurcie z wrzatkiem dzialal prawie godzine...😅

Edytowano przez farmaceuta
(edytowany)

Wydumałem takie cudo. Serwo obraca się lewo, prawo nawet po odjęciu ręki. Czasami jednak się przycina i zalicza tylko jeden z ruchów ( patrz_PRAWO(); )

Pętla loop() - istotny jest tylko case1 (póki co).

void loop() {

  aktualnyCzas = millis(); //Ustawienie wyjściowe dla millis()
  dystans = readPing(); //odczyt odległości

  if (!digitalRead(Przycisk_1)) tryb_program++; //Jeśli ostatni stan był wyłączony i aktualny stan jest włączony to:

  switch (tryb_program % 4)  {

    //Modulo - reszta z dzielenia przez 4 - bo 3 programy

    case 1:
      //Miganie LED_1 Wolne miganie Program_1
      if (aktualnyCzas - zapamietanyCzas_LED1 >= miganie_LED1) {
        stanLED1 = !stanLED1;
        digitalWrite(LED_1, stanLED1);
        zapamietanyCzas_LED1 = aktualnyCzas;  //zapamiętaj aktualny czas
      }

      if (dystans <= 15 && patrz_1) //jeśli dystans mniejszy od 15cm STOP->TYŁ->Patrz_Prawo->Patrz_lewo
      {
        patrz_1 = false; //zmień flagę
        //Silniki STOP!
        //Silnik tył!
    
      } else if ((aktualnyCzas - zapamietanyCzas_TEST >= 500UL) && !patrz_1 ) {

        dystansR = patrz_PRAWO();

        dystansL = patrz_LEWO();

        zapamietanyCzas_TEST = aktualnyCzas;

        patrz_1 = true;
      }
      else {
            } //Jedź naprzód

      if (aktualnyCzas - zapamietanyCzas_TEST >= 500UL) {
        moje_servo.write(115); //Ustawienie kąt 115°} //Zerowanie pozycji serva
      }
      
      Serial.println(dystans);//odczyt testowy z czujnika

      break;
    case 2:
      //Miganie LED_1 Szybkie miganie Program_2
      if (aktualnyCzas - zapamietanyCzas_LED1 >= miganie_LED2) {
        stanLED1 = !stanLED1;
        digitalWrite(LED_1, stanLED1);
        moje_servo.write(60);
        zapamietanyCzas_LED1 = aktualnyCzas;  //zapamiętaj aktualny czas
      }
      break;
    case 3:
      //Tutaj będzie stan OFF
      //Miganie LED_1 Szybkie miganie Program_3
      if (aktualnyCzas - zapamietanyCzas_LED1 >= 50) {
        stanLED1 = !stanLED1;
        digitalWrite(LED_1, stanLED1);

        zapamietanyCzas_LED1 = aktualnyCzas;  //zapamiętaj aktualny czas

      }
      break;
  }

  while (!digitalRead(Przycisk_1));
  delay(50);
}

Kolego @ethanak - Czy w dobrą stronę się kieruję ? Kod jeszcze nie uwzględnia zawracania. To później.

Edytowano przez Forseti

Czemu nie zrobisz z tego jednej funkcji? Teraz robisz dokladnie to samo co wczesniej tylko w inny sposob...jezeli podczas mierzenia dystansu nie zalezy Ci na gwaltownych reakcjach np. guzika to zrob to jak wczesniej tylko upakuj wszystko w jedna funkcje

(edytowany)
11 godzin temu, Forseti napisał:

Czy w dobrą stronę się kieruję

Nie. Tak jak napisał kolega wyżej - to jest ten sam kod co poprzednio, tylko inaczej napisany.

Funkcje takie jak "patrz_PRAWO", "patrz_LEWO", "zajrzyj_mi_GDZIEŚ" i podobne nie mają prawa istnieć!. Przeczytaj sobie dokładnie mój post  i pomyśl, czego nie zrobiłeś (a powinieneś) oraz co zrobiłeś (a nie powinieneś).

A w ogóle ten kod coraz bardziej nadaje się do wywalenia na śmietnik, co proponuję zrobić jak najszybciej i zacząć od początku.

Na przykład tak:

int odleglosc; // wartość zawsze aktualna, globalna zmienna dostępna dla każdego 

void loop()
{
  odleglosc=zmierz_odleglosc(); // nie masz prawa wywoływać tej funkcji w innym miejscu
  podejmij_decyzje();
}

Funkcja "podejmij_decyzje" ma podjąć decyzję co robić,a nie "podjąć decyzję, poczekać i zrobić jeszcze piętnaście innych rzeczy".

No i zaraz będzie "a jak ja będę wiedział jaka jest odległość jak ruszyłem serwem"?

A tak, że jak ruszysz tym nieszczęsnym serwem, to musisz sobie ustawić jakąś zmienną i zapamiętać kiedy ruszyłeś.

Wiedząc ile czasu zajmuje ruch serwa (czyli w najgorszym przypadku jakieś pół sekundy dla 180°) nie zmieniasz stanu maszyny, dopóki nie minęło tyle czasu że serwo na pewno dolazło do pozycji takiej jak trzeba i dalmierz mógł sobie zmierzyć odległość (to już sobie możesz policzyć ile czasu naprawdę trzeba).

Jeśli czas minął, aktualna odległość może być odczytana z globalnej zmiennej, i tę właśnie wartość podstawiasz do dystansR czy dystansL.

 

 

 

 

 

 

Edytowano przez ethanak
(edytowany)

@ethanak @farmaceuta Dziękuję za sugestie. Spróbuję się przez nie przegryźć.
 

1 godzinę temu, ethanak napisał:

 Przeczytaj sobie dokładnie mój post  i pomyśl, czego nie zrobiłeś (a powinieneś) oraz co zrobiłeś (a nie powinieneś). 

@ethanak Tak przeczytałem ale o ile rozumiem zamysł (wydaje się banalny w swej prostocie) to nie potrafię (jeszcze?) tego przełożyć na język Arduino. Jak już zapewne wiesz z Arduino mam do czynienia od kwietnia br. W związku z tym nie tak łatwo jest "pomyśleć" w sposób specyficzny dla tego środowiska osobie, która jest absolutnie z innej gałęzi zawodowej i profesjonalnie zajmuje się zupełnie czymś innym. Gwoli wyjaśnienia przeszukuję kazamaty internetu - nawet zerkam w książki traktujące o Arduino ale uwierz mi, że przy ograniczonych zasobach czasowych to zajmuje zdecydowanie więcej niż osobom kierunkowym. Tak jak wspomniałeś internet zawiera "multum przykładów" ale często błędnych i rozdrobnionych. FORBOT jest jednym z nielicznych miejsc porządnych gdzie warto szukać wsparcia i nauki od osób, które wiedzą co piszą - co też robię. Miej to proszę na uwadze.

Ale i tak dziękuję za Twój poświęcony czas - staram się wyciągać z tego jak najwięcej

1 godzinę temu, ethanak napisał:

A w ogóle ten kod coraz bardziej nadaje się do wywalenia na śmietnik, co proponuję zrobić jak najszybciej i zacząć od początku.

Najwyżej napiszę po raz kolejny kod od zera. Spróbuję się przegryźć przez internet w poszukiwaniu rozwiązania. Jak coś się uda pozwolę sobie zamieścić celem wykonania przez Was egzekucji 🙂 . Przy obecnym tempie mojego rozwoju w tym temacie zapewne za ok 2 tygodnie 😄 😄 😄 

Edytowano przez Forseti
23 minuty temu, Forseti napisał:

nie potrafię (jeszcze?) tego przełożyć na język Arduino.

Co Wy tu wszyscy z tym "językiem Arduino"... Nie ma

 

żadnego  języka Arduino, jest C++ i standardowe biblioteki Arduino. Tak samo jak nie ma języka warszawskiego, białostockiego czy gdańskiego, jest język polski (to taki odpowiednik C++) i ewentualne elementy gwarowe (czyli takie biblioteki).

27 minut temu, Forseti napisał:

Najwyżej napiszę po raz kolejny kod od zera

A to się na pewno przyda. A jak znam życie to tych kolejnych razów może być więcej - i możesz mi uwierzyć, że to nic nadzwyczajnego.

 

29 minut temu, Forseti napisał:

Spróbuję się przegryźć przez internet w poszukiwaniu rozwiązania.

Praktycznie wszystko czego potrzebujesz już tu dostałeś - czy to jako bezpośrednie wskazówki, czy przynajmniej jako informację, czego szukać w googlach.

31 minut temu, Forseti napisał:

nie tak łatwo jest "pomyśleć" w sposób specyficzny dla tego środowiska osobie, która jest absolutnie z innej gałęzi zawodowej i profesjonalnie zajmuje się zupełnie czymś innym.

Jakoś to się całkiem nieźle udaje paru tu obecnym rolnikom, emerytowanemu księgowemu, o paru innych profesjach typu muzyk czy mechanik samochodowy już nie wspomnę...

  • Lubię! 1
(edytowany)

@ethanak 

50 minut temu, ethanak napisał:

Co Wy tu wszyscy z tym "językiem Arduino"... Nie ma

Będę złośliwy - Język Arduino - Nie twierdzę, że jest to oddzielny język. Uproszczenie lub doprecyzowanie zakresu(jak najbardziej poprawne), które użyłem na podstawie wiedzy zdobytej w Kurs Arduino – #1 – podstawy Arduino oraz środowisko - możesz zerknąć.

50 minut temu, ethanak napisał:

Jakoś to się całkiem nieźle udaje paru tu obecnym rolnikom, emerytowanemu księgowemu, o paru innych profesjach typu muzyk czy mechanik samochodowy już nie wspomnę...

Ok. Po prostu podchodzę z pokorą do kwestii, na których się nie znam, a w tych w których jestem dobry nie jestem arogancki. Nie szukam wymówek - ogarnę temat.

Co do reszty Twojego postu- ok. Skorzystam i powrócę jak będzie gotowe (ręce do dupci mi nie przyrosły 🙂 ). Mam nadzieję, że będzie w porządku.

Pozdrowienia

 

Edytowano przez Forseti
  • Lubię! 2
26 minut temu, Forseti napisał:

Będę złośliwy

Cóż, sam chciałeś... 😉

27 minut temu, Forseti napisał:

Język Arduino - uproszczenie lub doprecyzowanie zakresu(jak najbardziej poprawne)

Nie, nie jest poprawne. Nie jest to ani uproszczenie, ani doprecyzowanie.

28 minut temu, Forseti napisał:

które użyłem na podstawie wiedzy zdobytej w Kurs Arduino – #1 – podstawy Arduino oraz środowisko

Z całym szacunkiem dla Autorów owego kursu - informacja jakoby "język w którym programuje się Arduino był podobny do C/C++" jest co prawda całkiem zgodna z rzeczywistością (bo przecież C++ jest całkiem podobny do C++), ale sformułowanie jest bardzo niezręczne i mylące. Zresztą - dyskusji na ten temat tu już trochę było, jak chcesz to poszukaj, znajdziesz dokładniejsze wyjaśnienia.

A co powiesz na informację, że "mieszkańcy Krakowa są podobni do Polaków"? Czy że "język krakowski jest zbliżony do polskiego"? Czy ja jadąc do Krakowa muszę się zaopatrzyć w słownik polsko-krakowski? A może bielsko-krakowski wystarczy? Znam jeszcze białostocki, może jest słownik białostocko-krakowski? Jak będzie po krakowsku "postaw dla mnie piwo"?

No i najważniejsze: czy szukając np. implementacji jakiegoś algorytmu będziesz szukał tylko i wyłącznie dla Arduino (w większości przypadków albo nie znajdziesz, albo dostaniesz gotowca w postaci biblioteki)? Czy może poszukasz jak to się robi w C++ (z reguły znajdziesz)? To ostatnie weź sobie do serca.

 

  • Lubię! 1
  • Nie zgadzam się! 2
void loop() {

  aktualnyCzas = millis(); //Ustawienie wyjściowe dla millis()

  if (!digitalRead(Przycisk_1)) tryb_program++; //Jeśli ostatni stan był wyłączony i aktualny stan jest włączony to:

  switch (tryb_program % 4)  {

    case 1:
      dystans = readPing();
      
      if (dystans <= 15 && x == 0)  {
        licznik++;
        x = 1;
      }
        switch (licznik)  {

     case 0:
     // a jedz ty w ch..............przed siebie
          break;
    case 1:
    //ustaw servo lewo
    czas_zwloki = 500; //czas opoznienia dla ruchu serva
    czas1 = millis();
    licznik++;
          break ;
   case 2:
      break;
       case 3:
       dystansL = readPing();
       licznik++;

           break;
        case 4:
        //ustaw servo prawo
    czas_zwloki = 500; //czas opoznienia dla ruchu serva
    czas1 = millis();
    licznik++;
      break;   
       case 5:
      break;
      case 6:
      dystansR = readPing();
       licznik++;
      break;
       case 7:
       // ustaw servo na center
       if (dystansL > dystansR) {
        //skrec odpowiednio
        licznik = 0;
        x = 0;
       } else {
        //skrec odpowiednio
        licznik = 0;
        x = 0;
       }
      break;
    if (millis() -  czas1 >  czas_zwloki) {
     licznik++;
   czas_zwloki = 10000000;

    }
  }
    case 2:
     
      break;
    case 3:
    
      break;
  
  }
  while (!digitalRead(Przycisk_1));
  delay(50);
}

Sprobuj cos takiego...tylko sobie podopisuj zmienne i komendy od jazdy/skretu itp jak w komentarzach...powinno teraz skrecac cyklicznie az do wykrycia dystansu wiekszego niz 15cm...moglem oczywiscie strzelic jakiegos babola wrednego..wiec sie poprawi jakby co..

  • Lubię! 1
(edytowany)

@farmaceuta Dziękuję Ci bardzo. Nie rozumiałem jednej kwestii, a mianowicie czy można switch() case w innym switch() case. Dzięki Tobie rozjaśniła mi się kwestia j.w. Ogarnę to jak najszybciej i dam znać 🙂

A, że tak zapytam. Można przypisać poza loop() cały switch(licznik) i go później przywoływać? np stworzyć int licznik i potem go w pętli przywołać aby kod był czytelniejszy? Ale to na później. Teraz hej przygodo- byleby zadziałało 🙂

Edytowano przez Forseti
3 minuty temu, Forseti napisał:

 Nie rozumiałem jednej kwestii, a mianowicie czy można switch() case w innym switch() case.

Mozesz praktycznie wszystko we wszystkim😉...i to jest wlasnie urok calej tej zabawy...ze mozna stworzyc cos na milion sposobow..

 

5 minut temu, Forseti napisał:

 A, że tak zapytam. Można przypisać poza loop() cały switch(licznik) i go później przywoływać? 

Nie wiem czy dobrze rozumiem...ale jesli chodzi Ci o normalny switch poza loop to nie da sie...jedynie w funkcji..(z tego co mi wiadomo😉) tzn. Mozesz sobie zrobic funkcje z tego "wewnetrznego" switch i wywalic poza loop...o to chodzilo??

 

6 minut temu, Forseti napisał:

Teraz hej przygodo- byleby zadziałało 🙂

Teoretycznie powinno zadzialac...tylko tutaj juz odrazu wpisujesz ruchy serwa w odpowiednie case...funkcje ktore miales mozesz juz wywalic...

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