Skocz do zawartości

Pojazd sterowany przez IR


jas123

Pomocna odpowiedź

Mam jeden problem przy każdym włączeniu pojazdu i kliknięciu przycisku do sterowania serwem najpierw serwo przyjmuje skrajną pozycję i dopiero po tym ruchu działa normalnie. Wie ktoś może czy da się to naprawić programowo?

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

@jas123 bardzo fajna konstrukcja, na filmie działa znacznie lepiej niż się spodziewałem - gratulacje!

10 godzin temu, jas123 napisał:

Wie ktoś może czy da się to naprawić programowo?

Pewnie, ale bez wglądu w program wiele nie pomożemy 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

#include <RC5.h>
#include <AFMotor.h>
#include <Servo.h> 
#define MS 150 //maksymalna prędkość

int pozycjaSerwa1 = 0 ; 
int pozycjaSerwa2 = 0 ;
int pozycjaSerwa3 = 0 ;
int pozycjaSerwa4 = 0 ;
int pozycjaSerwa5 = 0 ;
int pozycjaSerwa6 = 0 ;
Servo serwo1; 
Servo serwo2;
Servo serwo3;
Servo serwo4;
Servo serwo5;
Servo serwo6;

RC5 rc5(2); 
byte address; 
byte command;
byte toggle;
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);


void setup(){

   serwo1.attach(A0);  
   serwo2.attach(A1);
   serwo3.attach(A2);
   serwo4.attach(A3);
   serwo5.attach(A4);
   serwo6.attach(A5);


}
void loop(){

 if (rc5.read(&toggle, &address, &command)){
     switch(command) {
      case 144: //przód
    motor1.run(BACKWARD);
    motor1.setSpeed(MS);
    motor2.run(BACKWARD);
    motor2.setSpeed(MS);
    motor3.run(BACKWARD);
    motor3.setSpeed(MS);
    motor4.run(BACKWARD);
    motor4.setSpeed(MS);
      break;
 

      case 145: //tył 
    motor1.run(FORWARD);
    motor1.setSpeed(MS);
    motor2.run(FORWARD);
    motor2.setSpeed(MS);
    motor3.run(FORWARD);
    motor3.setSpeed(MS);
    motor4.run(FORWARD);
    motor4.setSpeed(MS);
      break;

      case 151: 
        stopMotors();
      break;

      case 150: //lewo
    motor1.run(BACKWARD);
    motor1.setSpeed(150);
    motor2.run(BACKWARD);
    motor2.setSpeed(0);
    motor3.run(BACKWARD);
    motor3.setSpeed(0);
    motor4.run(BACKWARD);
    motor4.setSpeed(150);
      break;   
      
      case 149:  //prawo
    motor1.run(BACKWARD);
    motor1.setSpeed(0);
    motor2.run(BACKWARD);
    motor2.setSpeed(150);
    motor3.run(BACKWARD);
    motor3.setSpeed(150);
    motor4.run(BACKWARD);
    motor4.setSpeed(0);
      break;
  //////////////////////////////////////
       case 2: 
        serwo6.write(pozycjaSerwa6 = pozycjaSerwa6 + 5);
        delay(30);
        
      break;
      case 5: 
        serwo6.write(pozycjaSerwa6 = pozycjaSerwa6 -5);
        delay(30);
      break;
  ////////////////////////////////////
   case 8: 
   
        serwo5.write(pozycjaSerwa5 = pozycjaSerwa5 + 5);
        delay(30);
        
      break;
      case 0: 
      
        serwo5.write(pozycjaSerwa5 = pozycjaSerwa5 -5);
        delay(30);
      break;
  ////////////////////////////////////
      case 1: 
        serwo4.write(pozycjaSerwa4 = pozycjaSerwa4 + 5);
        delay(30);
        
      break;
      case 4: 
        serwo4.write(pozycjaSerwa4 = pozycjaSerwa4 -5);
        delay(30);
      break;
  ////////////////////////////////////
      case 7: 
        serwo3.write(pozycjaSerwa3 = pozycjaSerwa3 + 5);
        delay(30);
        
      break;
      case 15: 
        serwo3.write(pozycjaSerwa3 = pozycjaSerwa3 -5);
        delay(30);
      break;
      ///////////////////////////////
       case 3: 
        serwo2.write(pozycjaSerwa2 = pozycjaSerwa2 + 5);
        delay(30);
        
      break;
      case 6: 
        serwo2.write(pozycjaSerwa2 = pozycjaSerwa2 -5);
        delay(30);
      break;
      /////////////////////////////
     case 9: 
        serwo1.write(pozycjaSerwa1 = pozycjaSerwa1 + 5);
        delay(30);
        
      break;
      case 34: 
        serwo1.write(pozycjaSerwa1 = pozycjaSerwa1 -5);
        delay(30);
      break;
      ////////////////////////////
     }
 
}
}

void stopMotors(){
 motor1.setSpeed(0);
  motor2.setSpeed(0);
   motor3.setSpeed(0);
    motor4.setSpeed(0);
}

 

Link do komentarza
Share on other sites

@jas123 przyznam, że nie wiem czy taki zapis działa (na pewno zaraz ktoś z większym doświadczeniem wypowie się w tej kwestii)... ale wygląda to trochę podejrzanie. Lepiej byłoby to rozbić na 2 linie:

pozycjaSerwa1 = pozycjaSerwa1 + 5; 
serwo1.write(pozycjaSerwa1);

Zobacz co się stanie przy takiej wersji 🙂

Link do komentarza
Share on other sites

Trzeba na początku zgrać ze sobą rzeczywistą pozycję serwa i tą, którą zna program. Niestety - włączając Arduino nie wiemy w jakiej pozycji jest serwo i nie możemy tego sprawdzić - pozostaje jedynie na samym początku (w funkcji setup) ustawić serwa w jakiejś pozycji początkowej.

Inna możliwość to zapamiętanie pozycji serwa przed wyłączeniem (co może być nieco trudniejsze, jako że Arduino nie wróżka i nie wie, że go za chwilę będziesz wyłączać) lub okresowe zapamiętywanie pozycji (np. po zakończeniu ruchu) - co z kolei może być bardzo niezdrowe dla owej nieulotnej pamięci, mającej ograniczoną ilość zapisów.

Ja bym się nie bawił w jakieś skomplikowane rzeczy, tylko w setup wrzuciłbym coś w stylu:

servo1.write(pozycjaSerwa1 = 0);

oczywiście dla każdego serwa - a najlepiej zamiast zera dałbym tam jakąś konkretną początkową wartość (taką, aby ramię na początku było w jakiejś sensownej pozycji - np. 90 dla serwa realizującego obrót całego ramienia).

Wracając do zapisu:

Trzeba pamiętać, że w C/C++ nie istnieje coś takiego jak "instrukcja podstawienia". Zamiast tego jest operator podstawienia, który - jak to operatory miewają w zwyczaju - zwraca jakąś wartość (w jego przypadku po prostu tę podstawioną) i który może być użyty w najprzeróżniejszych miejscach w programie jeśli tylko w danym miejscu następuje pobranie wartości (tzw. r-wartość czy z angielska r-value, coś co może stać po prawej stronie operatora podstawienia). Dlatego zapis:

fun(a=b+c);

jest całkowicie prawidłowy i zgodny z oczekiwaniami - do fun zostanie przekazana wartość podstawiana do a.

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Anonim

@Treker słusznie się zdziwił, to nie jest dobry styl programowania. Najlepiej jest przypisanie zastosować przed wywołaniem funkcji a funkcję wywoływać już z aktualną wartością zmiennej. Niektóre kompilatory oponowałyby na taki zapis.

Do zapamiętywania danych pomiędzy uruchomieniami w avr służy eeprom ewentualnie flash gdyby się uprzeć. Czasami zdarza się, że koniecznym jest odtworzenie wcześniejszych wartości zmiennych po resecie/wyłączeniu więc warto zainteresować się tym bliżej.

Dnia 23.01.2020 o 20:16, ethanak napisał:

Arduino nie wróżka i nie wie, że go za chwilę będziesz wyłączać

Racja ale zawsze można je wcześniej poinformować aby zdążyło sobie zapisać dane. Wyłączanie nie musi przecież sprowadzać się do rozłączenia zasilania. Ostatecznie wystarczy większy kondensator aby po wykryciu braku zasilania arduino zdążyło zapisać potrzebne dane.

Jak na początek całkiem udany projekt, gratulacje @jas123 . Przy okazji obrazuje on czym w istocie jest arduino - "nie trzeba mieć pojęcia, wystarczy mieć arduino". :)

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.