Skocz do zawartości

Kurs budowy robotów - #5 - omijanie przeszkód


Komentator

Pomocna odpowiedź

qbeczek, haymon, dziękuję za więcej informacji. Po kilku testach nadal nie udało nam się odtworzyć tego błędu. Dziś siadam do tego jeszcze raz, jeśli nie uda się odtworzyć takiej sytuacji, to będę poszukiwał ochotnika, który dostarczy swojego złożonego robota (w dokładnie takiej "niedziałającej" konfiguracji) do producenta shieldu. Całość zajmie 2-3 dni, oczywiście pokryjemy wszystkie koszty wysyłki i odwdzięczymy się dodatkowymi gadżetami 🙂

Całość wygląda tak, jakby w Waszych Arduino nie działały pull-upy. Poprawne zachowanie na pinach A4 oraz A5 jest wytłumaczalne bardzo prosto. Piny te odpowiadają w Arduino za interfejs SPI, do którego na płytce podłączony jest ekspander portów w związku z tym są tam dodatkowe rezystory podciągające.

Tak, czy inaczej zachowanie to nie będzie stwarzało problemów, ponieważ już od kolejnej części kursu w miejsce to będziemy wpinać czujniki analogowe, więc w między czasie spokojnie można przepiąć czujniki przeszkód na A4 i A5.

Treker, jaki jest sens (w programie testowym) pomiarów przy pomocy ADC przy pinie ustawionym jako INPUT i rozwartym wyłączniku krańcowym? Przecież tam są przypadkowe wartości, co ma to nam powiedzieć?

Dzięki temu widać, czy czujniki podpięte są pod odpowiednie piny, czy nie są zwarte do masy/zasilania oraz,
czy pojawiają się na nich jakieś mocne zakłócenia "z powietrza" 🙂

Link do komentarza
Share on other sites

Zgodnie z planem kolejny odcinek kursu oczywiście jest już dostępny: Kurs budowy robotów – #6 – Światłolub (sterowanie latarką)

PS to jak, mamy jakiegoś ochotnika, który chciałby przekazać nam swojego robota z "niesprawnymi" krańcówkami na testy? Jeśli tak, to proszę o kontakt na PW.

Link do komentarza
Share on other sites

Hej. Przyznam, ze nie czytałem poprzednich postów a pewnie dużo już takich robotów było, ale wrzucam i swojego pierwszego :). Dołożyłem z tyłu HC-R04 w celu uniknięcia taranowania przeszkód tyłem. Najpierw sprawdziłem na jakiej odległości robot jest w stanie wykonać ruch bez korzystania z czujnika HC-R04 a następnie dodałem kolejne warunki odpowiadające za mniejszą odległość. Użyłem też losowych wartości prędkości jazdy wprzód i obrotu. Całość w kodzie i na filmie 🙂. Tor jest celowo taki mały, bo był "zbudowany" do testów czujnika ultradźwiękowego. Jako, ze teraz czasu jest całkiem sporo to w planach mam dołożenie jeszcze kilku elementów, na przykład potencjometrów do sterowania bazowym czasem obrotu, czy prędkością jazdy. 

KOD: 

#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165

#define L_SIDE_SENSOR A0
#define R_SIDE_SENSOR A1
#define BUZZER 10

#define trigPin 8
#define echoPin 7


void setup()
{
    //konfiguracja pinów dla mostka H
    pinMode(L_DIR, OUTPUT);
    pinMode(R_DIR, OUTPUT);
    pinMode(L_PWM, OUTPUT);
    pinMode(R_PWM, OUTPUT);

    pinMode(L_SIDE_SENSOR, INPUT_PULLUP); //koniguracja pinu jak przyckiski
    pinMode(R_SIDE_SENSOR, INPUT_PULLUP);

    pinMode(BUZZER, OUTPUT); //definicja pinów i stanu dla buzzera
    digitalWrite(BUZZER, 0);

    randomSeed(analogRead(5)); //inicjalizacja generatora liczb losowych

    pinMode(trigPin, OUTPUT); //Deklaracja pinów dla czujnika zbliżeniowego
    pinMode(echoPin, INPUT);
    

}

void loop()
{
    int los = random(5, 40) * 10; //wylosowanie liczby dla czasu obrotu
    int randomSpeed = random(2, 6) * 10; //wylosowanie predkosci jazdy do przodu

    //jedź do przodu
    leftMotor(randomSpeed);
    rightMotor(randomSpeed);

    if (digitalRead(L_SIDE_SENSOR) == LOW)
    { //jeśli przeszkoda zostanie wykryta po lewej stronie
      
        int odleglosc = zmierzOdlegosc(); //zmienna odczytująca dystans z czujnika US

        if (odleglosc > 30) //jeśli odległość jest większa niż 30 cm to robot zdąży wykonać pełny zadany ruch
        {
            leftMotor(-40);
            rightMotor(-40);
            digitalWrite(BUZZER, 1);
            delay(1000);
        }
        else
        {
            while (odleglosc > 8) //jeśli odległość mniejsza niż 30 cm sprawdzanie kolejnych odległości do momentu osiągnięcia wartości 8 cm
            {

                leftMotor(-40);
                rightMotor(-40);
                digitalWrite(BUZZER, 1);
                odleglosc = zmierzOdlegosc(); //zamiana wartości odległości
                delay(50);

            }
        }

        //obrót w miejscu w prawo
        leftMotor(randomSpeed);
        rightMotor(-randomSpeed);
        digitalWrite(BUZZER, 0);
        delay(150 + los);
        //koniec warunku, wracamy do jazdy prosto

    }

    if (digitalRead(R_SIDE_SENSOR) == LOW)
    { //jeśli przeszkoda zostanie wykryta po prawej stronie
      //jedź wstecz i wydawaj dźwięk
        int odleglosc = zmierzOdlegosc(); //powtarzamy co w poprzednim warunku

        if (odleglosc > 30)
        {
            leftMotor(-40);
            rightMotor(-40);
            digitalWrite(BUZZER, 1);
            delay(1000);
        }
        else
        {
            while (odleglosc > 8)
            {

                leftMotor(-40);
                rightMotor(-40);
                digitalWrite(BUZZER, 1);
                odleglosc = zmierzOdlegosc();
                delay(50);

            }
        }
        //obrót w miejscu w lewo
        leftMotor(-randomSpeed);
        rightMotor(randomSpeed);
        digitalWrite(BUZZER, 0);
        delay(150 + los);
        //koniec warunku, wracamy do jazdy prosto

    }

}

void leftMotor(int V)
{
    if (V > 0)
    { //jesli predkosc jest wieksza od 0 (dodatnia

        V = map(V, 0, 100, 0, PWM_MAX); //mapowanie wartosci predkosc w stosunku do PWM MAX
        digitalWrite(L_DIR, 0); //ustawienie kierunku
        analogWrite(L_PWM, V); //ustawienie predkosci

    }
    else
    {

        V = abs(V); //pobranie wartosci bezwzglednej podanej predkosci
        V = map(V, 0, 100, 0, PWM_MAX);
        digitalWrite(L_DIR, 1); //ustawienie kierunku
        analogWrite(L_PWM, V); //ustawienie predkosci
    }
}

void rightMotor(int V)
{
    if (V > 0)
    { //jesli predkosc jest wieksza od 0 (dodatnia

        V = map(V, 0, 100, 0, PWM_MAX); //mapowanie wartosci predkosc w stosunku do PWM MAX
        digitalWrite(R_DIR, 0); //ustawienie kierunku
        analogWrite(R_PWM, V); //ustawienie predkosci

    }
    else
    {

        V = abs(V); //pobranie wartosci bezwzglednej podanej predkosci
        V = map(V, 0, 100, 0, PWM_MAX);
        digitalWrite(R_DIR, 1); //ustawienie kierunku
        analogWrite(R_PWM, V); //ustawienie predkosci
    }
}

void stopMotors() //funkcja dla zatrzymania robota (niewykorzystana)
{
    analogWrite(L_PWM, 0); //wylaczenie silnika lewego
    analogWrite(R_PWM, 0); //wylaczenie silnika prawego
}

int zmierzOdlegosc() //funkcja dla mierzenia odległości przez czujnik SC
{
    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;
}

 

Edytowano przez BHBmacieg
Link do komentarza
Share on other sites

Cześć wszystkim!

W miarę wyregulowałem czas cofania i obrotu. Teraz jak to oglądam to wydaje mi się ze lepiej by było jakbym jeszcze poprawił krańcówki żeby były bardziej do przodu niż na boki.

 

 

  • Lubię! 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

Dzień dobry,

mam pytanie dotyczące czujników. Dlaczego są podpięte do A0, A1, czy to nie są wejścia służące do analog in, a w kodzie są traktowane jako digital? 

Jeżeli mogę je wykorzystywać jako digitalRead(), mogę również je wykorzystywać jako DigitalWrite()?

Dla chętnych krótsza wersja do sterowania silników i myśle że bardziej przejrzysta. Przepraszam za mieszanie engines z motors. 

#define PWM_MAX 165
#define L_SIDE_SENSOR A0
#define R_SIDE_SENSOR A1
#define BUZZER 10

enum Direction { Forward, Backward };

struct ENGINE
{
  int forward;
  int backward;
  int PWD_PIN;
  int DIR_PIN;
  ENGINE(int _forward, int _backward, int _pwd_pin, int _dir_pin) : forward(_forward), backward(_backward), PWD_PIN(_pwd_pin), DIR_PIN(_dir_pin) {}
};

ENGINE leftEngine(0, 1, 5, 4);
ENGINE rightEngine(1, 0, 6, 9);

void setup()
{
  Serial.begin(9600);
  // BRIDGE-H
  pinMode(leftEngine.PWD_PIN, OUTPUT);
  pinMode(leftEngine.DIR_PIN, OUTPUT);
  pinMode(rightEngine.PWD_PIN, OUTPUT);
  pinMode(rightEngine.DIR_PIN, OUTPUT);

  //SENSORS
  pinMode(L_SIDE_SENSOR, INPUT_PULLUP);
  pinMode(R_SIDE_SENSOR, INPUT_PULLUP);

  //BUZZER
  pinMode(BUZZER, OUTPUT);
  digitalWrite(BUZZER, 0);
}

void loop()
{
  delay(5000);
  motorInput(50, Direction::Forward, leftEngine);
  delay(5000);
  stopMotor(leftEngine);

  delay(5000);
  motorInput(50, Direction::Backward, leftEngine);
  delay(5000);
  stopMotor(leftEngine);

  delay(5000);
  motorInput(50, Direction::Forward, rightEngine);
  delay(5000);
  stopMotor(rightEngine);
  
  delay(5000);
  motorInput(50, Direction::Backward, rightEngine);
  delay(5000);
  stopMotor(rightEngine);
}

void motorInput(int perCentPower, Direction dir, ENGINE engine )
{
  int power = map(perCentPower, 0, 100, 0, PWM_MAX);
  int motorDir = dir == Direction::Forward ? engine.forward : engine.backward;

  //Dir
  digitalWrite(engine.DIR_PIN, motorDir);
  //Power
  analogWrite(engine.PWD_PIN, power);
}

void stopMotor(ENGINE motor)
{
  analogWrite(motor.PWD_PIN, 0);
}

void stopMotors()
{
  stopMotor(leftEngine);
  stopMotor(rightEngine);
}

 

Edytowano przez arczi14
Link do komentarza
Share on other sites

13 godzin temu, arczi14 napisał:

Jeżeli mogę je wykorzystywać jako digitalRead(), mogę również je wykorzystywać jako DigitalWrite()?

@arczi14 tak możesz je do tego celu wykorzystać. ADC jest taką opcjonalną funkcją na tych wyprowadzeniach (podobnie jak wyjścia PWM też mogą pełnić role zwykłych wejść/wyjść). Domyślnie każde wyprowadzenie jest wejściem/wyjsciem cyfrowym, ale niektóre mogą pełnić szczególną rolę jak PWM, ADC, I2C, SPI itp.

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.