Skocz do zawartości

Kurs budowy robotów - #9 - ekspander I/O, serwo


Pomocna odpowiedź

html_mig_img
Zbliżamy się do końca kursu budowy robotów, pora omówić więc pozostałe możliwości naszego shieldu, które będą przydatne podczas dalszego rozbudowywania robotów!Zajmiemy się ekspanderem pinów oraz złączem dla serwomechanizmu modelarskiego. 

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Link do komentarza
Share on other sites

Mój pierwszy wpis, więc chciałbym się przywitać. Dzień dobry 🙂

Pytanie które nie daje mi spokoju, czy do ekspandera można w jakiś sposób podłączyć omawiany w rozdziale czujnik odległości lub serwo.

W przypadku serwa, nie jestem pewien w jaki sposób przekazać pin z ekspadera do np. servo.attach(x). Najlepiej byłoby : serwo.attach(expander.... no właśnie co ?

Dzięki za kursy, są świetne i inspirują 🙂

Link do komentarza
Share on other sites

Pytanie które nie daje mi spokoju, czy do ekspandera można w jakiś sposób podłączyć omawiany w rozdziale czujnik odległości lub serwo.

W przypadku serwa, nie jestem pewien w jaki sposób przekazać pin z ekspadera do np. servo.attach(x). Najlepiej byłoby : serwo.attach(expander.... no właśnie co ?

Da się, ale nie będziesz mógł używać do tego standardowej biblioteki, bo ona zakłada użycie "lokalnych" nóżek. Istnieją natomiast (lub można samemu napisać) biblioteki, które pozawalają na sterowanie takim serwem czy czujnikiem przez ekspander.

Istnieją także dedykowane "ekspandery" specjalnie do serw, którym tylko mówisz które serwo w jakiej pozycji ma się znaleźć, a one już same się martwią generowanie odpowiedniego sygnału, bez konieczności angażowania w to twojego mikrokontrolera -- przykładem takiego sterownika serw jest na przykład to: https://www.adafruit.com/product/815

Link do komentarza
Share on other sites

__ROBI__, tak jak napisał już deshipu, da się, tylko akurat do serw może to być mało opłacalne rozwiązanie. Opisywany ekspander to proste piny I/O idealnie do czujników cyfrowych, diod, przycisków etc. Serwomechanizmy potrzebują sygnału PWM, który tutaj musiałbyś generować programowo. Do takiego zastosowania można znaleźć inne, dedykowane układy, które odciążają główny kontroler.

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

Dzięki za pomoc 🙂

Fakt, całkiem zapomniałem o PWM - biblioteka servo zdaje się rozwiązuje to programowo i dlatego też o tym nie pomyślałem 😉

wgląda na to że najlepszym rozwiązaniem jest przełączenie wszystkiego co się da do expandera: czujniki podczerwieni, przełączniki, włącznik i wszystko to co wymaga odczytu/ustawienia konkretnego stanu (HIGH/LOW).

hmm, można by się pokusić o podpięcie pinów sterujących kierunkiem silnika do expandera, a PWM kontrolować z płytki, zawsze to cztery piny zaoszczędzone 😉

Muszę to sprawdzić.

Dzięki jeszcze raz

Link do komentarza
Share on other sites

hmm, można by się pokusić o podpięcie pinów sterujących kierunkiem silnika do expandera, a PWM kontrolować z płytki, zawsze to cztery piny zaoszczędzone

To już zależy od konkretnego mostka. Akurat ten, który jest na shieldzie wymaga tylko 2 pinów zwykłych i 2 PWM.

Więc dodawanie ekspandera dla samego mostka nie miałaby sensu 🙂

Link do komentarza
Share on other sites

do silników wykorzystuję : Pololu TB6612FNG mam tam trzy piny na silnik ( dwa kierunek, jeden PWM ).

ciekawe, na pewno trzeba poeksperymentować 😉

Dzięki za pomoc i wskazówki 🙂

Link do komentarza
Share on other sites

I jak zwykle mój 'poszukiwacz'

#include "Adafruit_MCP23008.h" //Dodanie biblioteki
Adafruit_MCP23008 ekspander; //Deklaracja "ekspandera"

//Biblioteka od serwomechanizmu
#include <Servo.h>
Servo serwo;
#define SERWO_PIN 11

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

//Piny krancowek
#define L_SIDE_SENSOR A2
#define R_SIDE_SENSOR A0

#define BUZZER 10 //Pin buzzera

//Pin czujnika swiatla
#define LIGHT_SENSOR A1

//Piny od czujnika odleglosci
#define trigPin 7
#define echoPin 8

void setup() {
 ekspander.begin(); //Rozpoczęcie komunikacji na domyslnym adresie 0x20

 //Konfiguracja pinow od mostka H
 pinMode(L_DIR, OUTPUT);
 pinMode(R_DIR, OUTPUT);
 pinMode(L_PWM, OUTPUT);
 pinMode(R_PWM, OUTPUT);

 //Konfiguracja pozostalych elementow
 pinMode(BUZZER, OUTPUT);
 digitalWrite(BUZZER, 0); //Wylaczenie buzzera    

 //Czujnik odleglosci
 pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
 pinMode(echoPin, INPUT); //a echo, jako wejście

 //Konfiguracja pinow od czujnikow
 pinMode(L_SIDE_SENSOR, INPUT_PULLUP);
 pinMode(R_SIDE_SENSOR, INPUT_PULLUP);

 //Serwo do pinu 11
 serwo.attach(SERWO_PIN);
 //Serwo na pozycje srodkowa 90 (bo zakres 0-180)
 serwo.write(90);

 //Deklaracja pinów jako wyjscia
 ekspander.pinMode(0, OUTPUT);
 ekspander.pinMode(1, OUTPUT);
 ekspander.pinMode(2, OUTPUT);
 ekspander.pinMode(3, OUTPUT);

 //Wylaczenie oswietlenia
 ekspander.digitalWrite(0, 0);
 ekspander.digitalWrite(1, 0);
 ekspander.digitalWrite(2, 0);
 ekspander.digitalWrite(3, 0);
}

void loop() {
 //Zapalenie swiatel
 int odczyt = analogRead(LIGHT_SENSOR);
 if(odczyt < 950){
  ekspander.digitalWrite(0, LOW);
  ekspander.digitalWrite(1, LOW);
  ekspander.digitalWrite(2, LOW);
  ekspander.digitalWrite(3, LOW);
  delay(100);
}else{
  ekspander.digitalWrite(0, HIGH);
  ekspander.digitalWrite(1, HIGH);
  ekspander.digitalWrite(2, HIGH);
  ekspander.digitalWrite(3, HIGH);
  delay(100);
}
 //Krancowki
 if (digitalRead(L_SIDE_SENSOR) == LOW) {
   //Jesli przeszkoda po lewej stronie
   //Jedz do tylu i w prawo
   leftMotor(-40);
   rightMotor(-40);
   digitalWrite(BUZZER, 1);
   delay(700);
   leftMotor(50);
   rightMotor(10);
   digitalWrite(BUZZER, 0);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }

 if (digitalRead(R_SIDE_SENSOR) == LOW){
   //Jesli przeszkoda po prawej stronie
   //Jedz do tylu w lewo
   leftMotor(-40);
   rightMotor(-40);
   digitalWrite(BUZZER, 1);
   delay(700);
   leftMotor(10);
   rightMotor(50);
   digitalWrite(BUZZER, 0);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }

 //Czy wykryto przeszkode w zakresie 0-35 cm
 if (zmierzOdleglosc() > 35) {
   leftMotor(40); //Jesli nie, to jedz prosto
   rightMotor(40);
 } else {
    //Jesli przeszkoda
    stopMotors(); //Zatrzymaj robota
    serwo.write(20); //Skrec czujnikiem w prawo
    delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

   //Sprawdz, czy po prawej stronie jest przeszkoda
   if (zmierzOdleglosc() > 35) {
      //Jesli jest pusto
     leftMotor(40);
     rightMotor(-40);
     delay(350); //Obracaj w prawo przez 350 ms
   } else {
     //Jeśli po prawej jest przeszkoda
     serwo.write(160); //Obroc czujnik w lewo
     delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

     //Sprawdz, czy po lowej stronie jest przeszkoda
     if (zmierzOdleglosc() > 35) {
        //Jesli jest pusto
       leftMotor(-40);
       rightMotor(40);
       delay(350); //Obracaj w lewo przez 350 ms
     } else {
       //Jesli z przodu, z lewej i prawej jest przeszkoda
       digitalWrite(BUZZER, 1);
       delay(500);
       digitalWrite(BUZZER, 0);
       //Daj sygnal buzzerem
     }
   }
   //Po sprawdzeniu przeszkod po bokach
   //Ustaw czujnik prosto    
   serwo.write(90);
 }

 //Opoznienie 100ms, ponieważ nie ma potrzeby sprawdzać przeszkod czesciej
 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 leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   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);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
}

Do oświetlenia wykorzystane czujniki z fotorezystorami z kursu.

Link do komentarza
Share on other sites

leepa79, no i super 🙂 Jak przymocowałeś czujnik do serwa?

Ładne oświetlenie robota - chyba jeden z dodatkowych modułów, nad którym pracujemy Ci się spodoba 😉

Link do komentarza
Share on other sites

Chciałbym połączyć program sterowania pilotem z ostatnim programem sterowania za pośrednictwem czujnika odległości.

Po skopiowaniu wszystkich elementów z programu obsługi czujnika, których niema w programie obsługi pilotem, przed void loop(), weryfikacja przebiega pozytywnie. Jednak po wklejeniu pod void loop() po ostatnim

Case….

…..

break;

case 56:

Całość programu obsługi czujnika po void loop()

break;

weryfikacja wykazuje błąd.

Całość programu :

#include <RC5.h>

//Biblioteka od serwomechanizmu
#include <Servo.h>
Servo serwo;
#define SERWO_PIN 11

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

//Piny od czujnika odleglosci
#define trigPin 7
#define echoPin 8

#define BUZZER 10
#define LED 13
#define TSOP_PIN 3

RC5 rc5(TSOP_PIN); //Informacja o podłączeniu odbiornika TSOP
byte address; 
byte command;
byte toggle;

void setup() {
 //Konfiguracja pinow od mostka H
 pinMode(L_DIR, OUTPUT);
 pinMode(R_DIR, OUTPUT);
 pinMode(L_PWM, OUTPUT);
 pinMode(R_PWM, OUTPUT);

 //Konfiguracja pozostalych elementow
 pinMode(BUZZER, OUTPUT);
 digitalWrite(BUZZER, 0); //Wylaczenie buzzera  
 pinMode(LED, OUTPUT); 
 digitalWrite(LED, 0); //Wylaczenie diody

 //Czujnik odleglosci
 pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
 pinMode(echoPin, INPUT); //a echo, jako wejście

 //Serwo do pinu 11
 serwo.attach(SERWO_PIN);
 //Serwo na pozycje srodkowa 90 (bo zakres 0-180)
 serwo.write(90);

 Serial.begin(9600);
}

void loop() {
if (rc5.read(&toggle, &address, &command)){
    switch(command) {
     case 2: //Do przodu
       leftMotor(40);
       rightMotor(40);
     break;

     case 8: //Do tyłu
       leftMotor(-40);
       rightMotor(-40);
     break;

     case 5: //STOP
       stopMotors();
     break;

     case 4: //Obrót w lewo
       leftMotor(-30);
       rightMotor(30);
     break;   

     case 6: //Obrót w prawo
       leftMotor(30);
       rightMotor(-30);
     break;       

     case 12:
       digitalWrite(BUZZER, 1);
       delay(500);
       digitalWrite(BUZZER, 0);
     break;

     case 56:
       //Czy wykryto przeszkode w zakresie 0-40 cm
 if (zmierzOdleglosc() > 40) {
   leftMotor(40); //Jesli nie, to jedz prosto
   rightMotor(40);
 } else {
    //Jesli przeszkoda
    stopMotors(); //Zatrzymaj robota
    serwo.write(20); //Skrec czujnikiem w prawo
    delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

   //Sprawdz, czy po prawej stronie jest przeszkoda
   if (zmierzOdleglosc() > 40) {
      //Jesli jest pusto
     leftMotor(40);
     rightMotor(-40);
     delay(400); //Obracaj w prawo przez 400 ms
   } else {
     //Jeśli po prawej jest przeszkoda
     serwo.write(160); //Obroc czujnik w lewo
     delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

     //Sprawdz, czy po lowej stronie jest przeszkoda
     if (zmierzOdleglosc() > 40) {
        //Jesli jest pusto
       leftMotor(-40);
       rightMotor(40);
       delay(400); //Obracaj w lewo przez 400 ms
     } else {
       //Jesli z przodu, z lewej i prawej jest przeszkoda
       digitalWrite(BUZZER, 1);
       delay(500);
       digitalWrite(BUZZER, 0);
       //Daj sygnal buzzerem
     }
   }
   //Po sprawdzeniu przeszkod po bokach
   //Ustaw czujnik prosto    
   serwo.write(90);
 }

 //Opoznienie 100ms, ponieważ nie ma potrzeby sprawdzać przeszkod czesciej
 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 leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   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);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
}
break;
   }
 }
}

void leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   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);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
}

Gdzie popełniam błąd.

Jak zapisać po „case 56:” polecenie aby program samoczynnie wykonywał jazdę na podstawie wskazań czujnika.

Link do komentarza
Share on other sites

Pesjar, proszę sprawdzić, gdzie i jak zadeklarowano funkcję leftMotor, rightMotor. Z tego, co widzę są one umieszczone w programie podwójnie. Raz na końcu programu (poprawnie) oraz drugi raz wewnątrz switch...case, co jest błędem. Nie można deklarować funkcji wewnątrz konstrukcji warunkowej switch. Tym bardziej nie można deklarować ich dwa razy 😉 Informacje na temat pisania własnych funkcji (i miejsca na ich umieszczanie) zostały opisane w kursie podstaw Arduino: Kurs Arduino – #9 – Czujnik odległości HC-SR04, funkcje

Link do komentarza
Share on other sites

Jestem kompletnym laikiem w programowaniu.

Wyciełem powtarzające się funkcję leftMotor, rightMotor i stopMotors.

Jednak w dalszym ciągu weryfikacja wkazuje błąd.

Co zrobić dalej?

Program pomkorekcie:

#include <RC5.h>

//Biblioteka od serwomechanizmu
#include <Servo.h>
Servo serwo;
#define SERWO_PIN 11

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

//Piny od czujnika odleglosci
#define trigPin 7
#define echoPin 8

#define BUZZER 10
#define LED 13
#define TSOP_PIN 3

RC5 rc5(TSOP_PIN); //Informacja o podłączeniu odbiornika TSOP
byte address; 
byte command;
byte toggle;

void setup() {
 //Konfiguracja pinow od mostka H
 pinMode(L_DIR, OUTPUT);
 pinMode(R_DIR, OUTPUT);
 pinMode(L_PWM, OUTPUT);
 pinMode(R_PWM, OUTPUT);

 //Konfiguracja pozostalych elementow
 pinMode(BUZZER, OUTPUT);
 digitalWrite(BUZZER, 0); //Wylaczenie buzzera  
 pinMode(LED, OUTPUT); 
 digitalWrite(LED, 0); //Wylaczenie diody

 //Czujnik odleglosci
 pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
 pinMode(echoPin, INPUT); //a echo, jako wejście

 //Serwo do pinu 11
 serwo.attach(SERWO_PIN);
 //Serwo na pozycje srodkowa 90 (bo zakres 0-180)
 serwo.write(90);

 Serial.begin(9600);
}

void loop() {
if (rc5.read(&toggle, &address, &command)){
    switch(command) {
     case 2: //Do przodu
       leftMotor(40);
       rightMotor(40);
     break;

     case 8: //Do tyłu
       leftMotor(-40);
       rightMotor(-40);
     break;

     case 5: //STOP
       stopMotors();
     break;

     case 4: //Obrót w lewo
       leftMotor(-30);
       rightMotor(30);
     break;   

     case 6: //Obrót w prawo
       leftMotor(30);
       rightMotor(-30);
     break;       

     case 12:
       digitalWrite(BUZZER, 1);
       delay(500);
       digitalWrite(BUZZER, 0);
     break;

     case 56:
       //Czy wykryto przeszkode w zakresie 0-40 cm
 if (zmierzOdleglosc() > 40) {
   leftMotor(40); //Jesli nie, to jedz prosto
   rightMotor(40);
 } else {
    //Jesli przeszkoda
    stopMotors(); //Zatrzymaj robota
    serwo.write(20); //Skrec czujnikiem w prawo
    delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

   //Sprawdz, czy po prawej stronie jest przeszkoda
   if (zmierzOdleglosc() > 40) {
      //Jesli jest pusto
     leftMotor(40);
     rightMotor(-40);
     delay(400); //Obracaj w prawo przez 400 ms
   } else {
     //Jeśli po prawej jest przeszkoda
     serwo.write(160); //Obroc czujnik w lewo
     delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

     //Sprawdz, czy po lowej stronie jest przeszkoda
     if (zmierzOdleglosc() > 40) {
        //Jesli jest pusto
       leftMotor(-40);
       rightMotor(40);
       delay(400); //Obracaj w lewo przez 400 ms
     } else {
       //Jesli z przodu, z lewej i prawej jest przeszkoda
       digitalWrite(BUZZER, 1);
       delay(500);
       digitalWrite(BUZZER, 0);
       //Daj sygnal buzzerem
     }
   }
   //Po sprawdzeniu przeszkod po bokach
   //Ustaw czujnik prosto    
   serwo.write(90);
 }

 //Opoznienie 100ms, ponieważ nie ma potrzeby sprawdzać przeszkod czesciej
 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;
}
 break;

   }
 }
}

void leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   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);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
}
Link do komentarza
Share on other sites

Pesjar, radziłbym na spokojnie przeanalizować poprzednie kursy Arduino, bazowanie na wklejaniu "gotowców" generuje więcej problemów niż dobrego 😉 Tak jak pisałem, wewnątrz instrukcji switch nie można deklarować żadnych funkcji. Nadal jest tam deklaracja funkcji zmierzOdleglosc(), która powinna znaleźć się tam gdzie pozostałe funkcje (na końcu).

Proszę pamiętać, aby kody umieszczać wewnątrz tag'ów - tym razem poprawię już ręcznie 🙂

Link do komentarza
Share on other sites

Pesjar, W środowisku Arduino jest fajny 'trik' - jak klikniesz za nawiasem klamrowym to zobaczysz wyżej taki prostokąt i już wiesz gdzie się zaczyna i kończy dany blok.

Bardzo pomocne na etapie działania 'kopiuj --> wklej' 😉

Sam jestem początkującym i też mi się zdarza tak działać...Co do Twojego kodu to na początku skasowałbym wszystko od 'case 56:' do ostatniego nawiasu klamrowego przed 'void leftMotor'. Przed 'void leftMotor' Powinny Ci zastać trzy nawiasy i zobacz czego każdy dotyczy (metodą z obrazka powyżej). Potem wróć do lekcji o odbiorniku IR (RC5) i ekspander I/O, serwo i zobacz jak to tam wyglądało (wskazówka - int zmierzOdleglosc() nie siedzi w void loop() ). Dla własnej nauki poprawiłem Twój kod, ale oczywiście nie zabiorę Ci tej przyjemności w zabawie i nie podam go na forum.

A u mnie kod na takim etapie:

#include "Adafruit_MCP23008.h" //Dodanie biblioteki
Adafruit_MCP23008 ekspander; //Deklaracja "ekspandera"
//adrs biblioteki https://github.com/adafruit/Adafruit-MCP23008-library

//Biblioteka od serwomechanizmu
#include <Servo.h>
Servo serwo;
#define SERWO_PIN 11

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

//Piny krancowek
#define L_SIDE_SENSOR A2
#define R_SIDE_SENSOR A0

#define BUZZER 10 //Pin buzzera

//Pin czujnika swiatla
#define LIGHT_SENSOR A1

//Piny od czujnika odleglosci
#define trigPin 7
#define echoPin 8

//Oswietlenie miganie
const int ledPin1 = 1;
const int ledPin2 = 0;
int stan = LOW;
unsigned long previousMillis = 0;
const long interval = 500;

void setup() {
 ekspander.begin(); //Rozpoczęcie komunikacji na domyslnym adresie 0x20

 //Konfiguracja pinow od mostka H
 pinMode(L_DIR, OUTPUT);
 pinMode(R_DIR, OUTPUT);
 pinMode(L_PWM, OUTPUT);
 pinMode(R_PWM, OUTPUT);

 //Konfiguracja pozostalych elementow
 pinMode(BUZZER, OUTPUT);
 digitalWrite(BUZZER, 0); //Wylaczenie buzzera    

 //Czujnik odleglosci
 pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
 pinMode(echoPin, INPUT); //a echo, jako wejście

 //Konfiguracja pinow od czujnikow
 pinMode(L_SIDE_SENSOR, INPUT_PULLUP);
 pinMode(R_SIDE_SENSOR, INPUT_PULLUP);

 //Serwo do pinu 11
 serwo.attach(SERWO_PIN);
 //Serwo na pozycje srodkowa 90 (bo zakres 0-180)
 serwo.write(90);

 //Deklaracja pinów jako wyjscia (oswietlenie)
 ekspander.pinMode(2, OUTPUT);
 ekspander.pinMode(3, OUTPUT);
 pinMode(ledPin1, OUTPUT);
 pinMode(ledPin2, OUTPUT);

 //Wylaczenie oswietlenia
 digitalWrite(ledPin1, LOW);
 digitalWrite(ledPin2, LOW);
 ekspander.digitalWrite(2, 0);
 ekspander.digitalWrite(3, 0);
}

void loop() {
 //Zapalenie swiatel
 int odczyt = analogRead(LIGHT_SENSOR);
 if(odczyt < 950){
  digitalWrite(ledPin1, 0);
  digitalWrite(ledPin2, 0);
  ekspander.digitalWrite(2, LOW);
  ekspander.digitalWrite(3, LOW);
  delay(100);
}else{
  light();
}
 //Krancowki
 if (digitalRead(L_SIDE_SENSOR) == LOW) {
   //Jesli przeszkoda po lewej stronie
   //Jedz do tylu i w prawo
   leftMotor(-40);
   rightMotor(-40);
   digitalWrite(BUZZER, 1);
   delay(700);
   leftMotor(50);
   rightMotor(10);
   digitalWrite(BUZZER, 0);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }

 if (digitalRead(R_SIDE_SENSOR) == LOW){
   //Jesli przeszkoda po prawej stronie
   //Jedz do tylu w lewo
   leftMotor(-40);
   rightMotor(-40);
   digitalWrite(BUZZER, 1);
   delay(700);
   leftMotor(10);
   rightMotor(50);
   digitalWrite(BUZZER, 0);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }

 //Czy wykryto przeszkode w zakresie 0-35 cm
 if (zmierzOdleglosc() > 35) {
   leftMotor(40); //Jesli nie, to jedz prosto
   rightMotor(40);
 } else {
    //Jesli przeszkoda
    stopMotors(); //Zatrzymaj robota
    serwo.write(20); //Skrec czujnikiem w prawo
    delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

   //Sprawdz, czy po prawej stronie jest przeszkoda
   if (zmierzOdleglosc() > 35) {
      //Jesli jest pusto
     leftMotor(40);
     rightMotor(-40);
     delay(350); //Obracaj w prawo przez 350 ms
   } else {
     //Jeśli po prawej jest przeszkoda
     serwo.write(160); //Obroc czujnik w lewo
     delay(800); //Poczekaj 800ms dla ustabilizowania konstrukcji

     //Sprawdz, czy po lowej stronie jest przeszkoda
     if (zmierzOdleglosc() > 35) {
        //Jesli jest pusto
       leftMotor(-40);
       rightMotor(40);
       delay(350); //Obracaj w lewo przez 350 ms
     } else {
       //Jesli z przodu, z lewej i prawej jest przeszkoda
       digitalWrite(BUZZER, 1);
       delay(500);
       digitalWrite(BUZZER, 0);
       //Daj sygnal buzzerem
       delay(1000);
       leftMotor(35); //Obrot w miejscu o 180 st w prawo
       rightMotor(-35); 
       delay(850);
     }
   }
   //Po sprawdzeniu przeszkod po bokach
   //Ustaw czujnik prosto    
   serwo.write(90);
 }

 //Opoznienie 100ms, ponieważ nie ma potrzeby sprawdzać przeszkod czesciej
 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 leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   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);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
}

void light(){
 unsigned long currentMillis = millis();
 if (currentMillis - previousMillis >= interval) {
   previousMillis = currentMillis;
   if (stan == LOW) {
     stan = HIGH;
   } else {
     stan = LOW;
   }
   digitalWrite(ledPin1, stan);
   digitalWrite(ledPin2, !stan);
   ekspander.digitalWrite(2, 1);
   ekspander.digitalWrite(3, 1);
 }
}

Czyli próba zastosowania 'millis' dla migania diod z tyłu i ucieczka w sytuacji gdzie po lewej i po prawej przeszkoda poniżej 35 cm.

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.