Wątek przeniesiony 2018-11-08 11:36 z C/C++ przez Marooned.

Problem dotyczący ifa w ifie

0

Witam mam pewien problem dotyczący ifa w ifie.
Otóż robiłem robocika (arduino) na ultradźwiękowym czujniku odległości (przyjmujemy, że drogi które może obrać są 3 prawo lewo i przód) który miał działać tak, że gdy nie ma przeszkody jedzie do przodu (włącza styczniki których pinami wyjściowymi są 8 i 7, gdy jest przeszkoda skręca w prawo (włącza stycznik którego pinem wyjściowym jest 8 na 2 sekundy) lecz gdy skręcił w prawo i nadal wykrywa przeszkodę skręca dwukrotnie w lewo (włącza stycznik 7 na 4 sekundy), a program wygląda następująco

#define trigPin 12
#define echoPin 11
 
void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
  pinMode(echoPin, INPUT); //a echo, jako wejście
  pinMode(8, OUTPUT); //Wyjście dla buzzera
  pinMode(7, OUTPUT);
}
 
void loop() {  
  zakres(0, 3);   
  delay(100);
} 
 
int zmierzOdleglosc() {
  long czas, dystans;
 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  czas = pulseIn(echoPin, HIGH);
  dystans = czas / 58;
 
  return dystans;
}
 
void zakres(int a, int b) {
  int jakDaleko = zmierzOdleglosc();
  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(8, HIGH);
      delay(2000);
      digitalWrite(8, LOW);
      
      if ((jakDaleko > a) && (jakDaleko < b)) {
          digitalWrite(7, HIGH);
          delay(4000);
          digitalWrite(7, LOW);
      }

      else {
      digitalWrite(8, HIGH);
      digitalWrite(7, HIGH);
  }}
      else {
      digitalWrite(8, HIGH);
      digitalWrite(7, HIGH);
  }
}

Problem z tego co mi się wydaje znajduje się tu gdzie jest if w ifie

void zakres(int a, int b) {
  int jakDaleko = zmierzOdleglosc();
  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(8, HIGH);
      delay(2000);
      digitalWrite(8, LOW);
      
      if ((jakDaleko > a) && (jakDaleko < b)) {
          digitalWrite(7, HIGH);
          delay(4000);
          digitalWrite(7, LOW);
      }

      else {
      digitalWrite(8, HIGH);
      digitalWrite(7, HIGH);
  }

Proszę o pomoc.

0

Hej,
nie do końca rozumiem to warunkowanie. Może wystarczy takie: jeżeli dystans (na podstawie sygnału) jest mniejszy od określonej wartości, to wtedy podejmujemy jakieś czynności. Można jeszcze wysyłać jakieś sygnały w lewo i w prawo, i jak robocik natrafi na trzy ściany, to zawraca, dobrze myślę ?? czy ujowo ?? :)

0

Program nie był w całości pisany przeze mnie lecz skopiowany z forbota (program na załączanie buzzera) i przerobiony/dopisany.
Nie do końca rozumiem co miałeś na myśli gdyż sam nie pojmuję na jakiej zasadzie program sprawdza odległość lecz jest to tak zrobione, że gdy przeszkoda nie jest wykrywana to jedzie do przodu a gdy jest to sprawdza inne drogi do momentu w którym będzie mógł jechać przed siebie i nie chodzi mi tu o robota który przejdzie labirynt a jedynie "krętą drogę"

0

To w takim razie zajmij się tym, i ogarnij logikę poruszania się tego robota (tak na chłopski rozum), dojeżdża do ściany i co robi dalej, itd. a jak będziesz miał logikę rozrysowaną, możesz nawet sobie zrobić jakieś rysunki, to wtedy przełożenie na warunkowanie nie będzie trudne. bo zaczynasz robotę, że tak powiem od d$%^ strony :)

0

To jest tak że gdy dojedzie do ścianki to skręca w prawo i gdy już nie ma przeszkody jedzie w przód. Lecz gdy skręcił w prawo i nadal wykrywa przeszkodę t skręca w lewo dwukrotnie. System działania miałem zaplanowany zanim się zabrałem do przerabiania programu :P Problem jest taki, że wszystko wariuje gdy już dopiszę tą zależność gdy skręciłeś już w prawo i nadal masz przeszkodę włącz silnik lewy na czas dwukrotnie większy od tego gdy skręcałeś w prawo.

0

Ale z czym masz problem? Weź opisz jeszcze raz jak powinien działać program, a jak działa w rzeczywistości.

0

Chwilowo działa tak, że gdy nie ma przeszkody to jedzie w przód a gdy napotka przeszkodę to z kilkusekundowym opóźnieniem załącza się stycznik podpięty pod pin nr 7 tzn. włącza się lewy silnik. To jak ma działać wyjaśniłem już dokładnie.

0

W sensie, że za późno reaguje i wjeżdża w ścianę zamiast ją ominąć? Opisz dokładnie zasadę działania i w czym jest problem, bo nie opisałeś tego albo przynajmniej ja nie rozumiem.

0

Gdy czujnik nic nie wykrywa robot jedzie prosto lecz gdy jest przeszkoda to najpierw skręca w prawo i teraz albo nadal jest przeszkoda albo nie jeśli tak to skręca w lewo w czasie dwukrotnie większym niż gdy skręcał w prawo (by wrócić do pozycji na której napotkał przeszkodę a potem skręcić w 3 możliwą stronę) zaczekaj chwilę to ci to rozrysuję

0

W skrócie robot powinien skręcić w prawo po wykryciu przeszkody, a skręca w lewo tak? I gdy piny 8 i 7 są w stanie wysokim to jedzie prosto, gdy w stanie wysokim jest tylko pin 8 to jedzie w prawo, a jak tylko 7 to w lewo?

0

WIN_20180901_230256.JPG może to ci w jakiś sposób rozjaśni to jak ma działać (tak wiem ciężko zrozumieć mój tok myślenia)

0

mogę nagrać filmik obrazujący to jak teraz działa

0
Draaz napisał(a):

W skrócie robot powinien skręcić w prawo po wykryciu przeszkody, a skręca w lewo tak? I gdy piny 8 i 7 są w stanie wysokim to jedzie prosto, gdy w stanie wysokim jest tylko pin 8 to jedzie w prawo, a jak tylko 7 to w lewo?

tak ale to nie jedyny błąd jaki się pojawia w grę wchodzi jeszcze dziwne opóźnienie tak jakby mieszał komendy

0

No to masz w takim razie źle skonstruowane warunki. Zrób tak, żeby domyślnie oba piny były w stanie wysokim, a do skręcania w prawo ustawiasz pin 7 na stan niski, a do skręcania w lewo pin 8 na niski.
Aktualny kod, jeśli robot jedzie prosto, to po tych dwóch sekundach on powoduje skręt w lewo zamiast w prawo, bo ustawiasz pin 8 na stan niski.

digitalWrite(8, HIGH); //jeśli domyślnie 8 i 7 jest w stanie wysokim, to to nic nie robi
      delay(2000);
      digitalWrite(8, LOW); // a tutaj powodujesz skręt w lewo zamiast skrętu w prawo, bo teraz tylko pin 7 jest w stanie wysokim
0

Faktycznie ma to sens zaraz zmienię to w programie i się odezwę jak działa.
Dzięki.

Ps. jak ustawić żeby domyślnie stan pinów był wysoki?

0

void zakres(int a, int b) {
int jakDaleko = zmierzOdleglosc();
if ((jakDaleko > a) && (jakDaleko < b)) {
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
delay(2000);

  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
      delay(4000);
  }
0

Działa dzięki za pokazanie mi jaki głupi błąd zrobiłem.
<3 (no homo)

0

W arduino masz dwie pętle, jedna wykonująca się tylko przy starcie programu, a druga działająca cały czas. W tej pierwszej ustaw oba piny na wysokie i nie zapomnij ich odpowiednio ustawiać przy warunkach od czujnika. A co do tych dziwnych opóźnień co mówiłeś to są one pewnie związane z tymi delayami przy załączaniu pinów, masz to źle ustawione to program wariuje. Zrób tak, że gdy czujnik wykryje przeszkodę to zeruje dany pin, a gdy przeszkody już nie wykrywa to załącza. Opóźnienia możesz zastosować tylko koło 20 milisekund, żeby zabezpieczyć program przed drganiami styków. Takie delaye na 2 czy 4 sekundy to złe rozwiązanie.

0

Chwila jednak nie działa.
teraz gdy wykryje przeszkodę to najpierw skręca w prawo a potem olewa to czy jest przeszkoda czy nie i skręca w lewo. :/

0

Pokaż kod.

0

void zakres(int a, int b) {
int jakDaleko = zmierzOdleglosc();
if ((jakDaleko > a) && (jakDaleko < b)) {
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
delay(2000);

  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
      delay(4000);
  }
  
  else {
  digitalWrite(8, HIGH);
  digitalWrite(7, HIGH);

}

} else {
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
}

0

Muszę chwilę pokombinować i zaraz odpiszę jeśli coś się uda.

a teraz skręca tylko w prawo po wykryciu przeszkody i przestaje jechać (gdy w voidsetup dałem digitalWrite(8, HIGH); i digitalWrite(7, HIGH);
a następnie zmieniłem to:

void zakres(int a, int b) {
  int jakDaleko = zmierzOdleglosc();
  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(7, LOW);
      delay(2000);
      
      if ((jakDaleko > a) && (jakDaleko < b)) {
          digitalWrite(8, LOW);
          delay(4000);
      }

  } 
}
0

No bo wyzerowałeś oba piny to robot nie jedzie, w momencie gdy zerujesz pin przy skręcie w prawo i potem chcesz skręcić w lewo to musisz tamten pin z powrotem ustawić na wysoki. Cały kod wrzucaj w formatkę, bo nieczytelny jest w ten sposób

0
void zakres(int a, int b) {
  int jakDaleko = zmierzOdleglosc();
  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(7, LOW);
      delay(2000);
      digitalWrite(7, HIGH);
      
      if ((jakDaleko > a) && (jakDaleko < b)) {
          digitalWrite(8, LOW);
          delay(4000);
          digitalWrite(8, HIGH);
0

Zobacz:
int jakDaleko = zmierzOdleglosc();
To liczysz na początku, a potem sprawdzasz warunek, jak się zgadza skręcasz w prawo. A potem sprawdzasz to jeszcze raz i skręcasz w lewo. Warunek jest ten sam z tą samą odległością, więc i przy skręcie w lewo i w prawo się zgadza. Po skręceniu w prawo musisz na nowo obliczyć tę wartość, czyli:

int jakDaleko = zmierzOdleglosc();
  if ((jakDaleko > a) && (jakDaleko < b)) {
      digitalWrite(7, LOW);
      delay(2000);
      digitalWrite(7, HIGH);

  jakDaleko = zmierzOdleglosc();    //teraz masz swieże dane z czujnika czy jest przeszkoda czy nie i mając swieże dane możesz zareagować prawidłowo, czyli czy trzeba skręcać czy jechać prosto. Jeśli ta funkcja zwraca to co myślę

      if ((jakDaleko > a) && (jakDaleko < b)) {
          digitalWrite(8, LOW);
          delay(4000);
          digitalWrite(8, HIGH);

Przetestuj teraz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1