Skocz do zawartości

Zdalnie sterowany samochodzik pilotem IR


Pomocna odpowiedź

Strasznie brzydki ten kod...

Po pierwsze, masz jakieś tajemnicze zeroiksy w kodzie, które absolutnie nie wyglądają ładnie. Po drugie pomieszane odbieranie danych z wykonaniem polecenia. Na początek spróbuj kodu, który robi to samo co Twój, ale łatwiej będzie później coś zmienić:

#include <IRremote.hpp>
#include <AFMotor.h>

AF_DCMotor motorM1(4);
AF_DCMotor motorM2(3);
AF_DCMotor motorM3(2);
AF_DCMotor motorM4(1);

const int RECV_PIN = A0;
int speed=200;

/* a teraz żeby nie mieć porypanych stałych w kodzie */

#define J_PRZOD     0xBF40FF00
#define J_WSTECZ    0xE619FF00
#define J_LEWO      0xF807FF00
#define J_PRAWO     0xF609FF00
#define J_STOP      0xEA15FF00

// to sprawdź
#define J_REPEAT    0xFFFFFFFF

void setup() {
    IrReceiver.begin(RECV_PIN);
    motorM1.setSpeed(speed);
    motorM2.setSpeed(speed);
    motorM3.setSpeed(speed);
    motorM4.setSpeed(speed);
}

/* trochę porządku na poiczątek */
void loop() {
    uint32_t kod = 0;
    /* najpierw odbieramy dane */
    if (IrReceiver.decode()) {
        kod = IrReceiver.decodedIRData.decodedRawData;
        IrReceiver.resume();
    }

    /* a teraz interpretujemy odebrany kod */

    switch(kod) {
        case J_PRZOD:
        motorM1.run(FORWARD);
        motorM2.run(FORWARD);
        motorM3.run(FORWARD);
        motorM4.run(FORWARD);
        break;

        case J_WSTECZ:
        motorM1.run(BACKWARD);
        motorM2.run(BACKWARD);
        motorM3.run(BACKWARD);
        motorM4.run(BACKWARD);
        break;

        case J_LEWO:
        motorM1.run(FORWARD);
        motorM2.run(FORWARD);
        motorM3.run(BACKWARD);
        motorM4.run(BACKWARD);
        break;

        case J_PRAWO:
        motorM3.run(FORWARD);
        motorM4.run(FORWARD);
        motorM2.run(BACKWARD);
        motorM1.run(BACKWARD);
        break;

        case J_STOP:
        motorM3.run(RELEASE);
        motorM4.run(RELEASE);
        motorM2.run(RELEASE);
        motorM1.run(RELEASE);
        break;
    }
}

Sprawdź czy działa, a przede wszystkim czy kod powtórzenia jest rzeczywiście 0xffffffff (nie mam takiego pilota więc nie sprawdzę).

Reszta jutro.

 

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

@ethanak Wszystko działa. Twój kod wygląda 100 jak nie 1000 razy lepiej. Ogromne dzięki! Kiedyś znak powtórzenia to było u mnie 0xFFFFFFFF, ale teraz to jest po prostu 0x0.

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

Top tak pięć minut przed wyjściem - sprawdź jeszcze ten kod. Na razie w działaniu nie powinno być różnicy, ale to już można sobie ładnie przerabiać 🙂

#include <IRremote.hpp>
#include <AFMotor.h>

AF_DCMotor motorM1(4);
AF_DCMotor motorM2(3);
AF_DCMotor motorM3(2);
AF_DCMotor motorM4(1);

const int RECV_PIN = A0;
int speed=200;

/* a teraz żeby nie mieć porypanych stałych w kodzie */

#define C_PRZOD     0xBF40FF00
#define C_WSTECZ    0xE619FF00
#define C_LEWO      0xF807FF00
#define C_PRAWO     0xF609FF00
#define C_STOP      0xEA15FF00

// to sprawdź - na wszelki wypadek będą dwa
#define C_REPEAT    0xFFFFFFFF
#define C_REPEAT2   0x0

/* i reczywiste proste kody do programu */

enum {
    J_ZERO = 0,
    J_PRZOD,
    J_WSTECZ,
    J_LEWO,
    J_PRAWO,
    J_STOP
};

void setup() {
  IrReceiver.begin(RECV_PIN);
  motorM1.setSpeed(speed);
  motorM2.setSpeed(speed);
  motorM3.setSpeed(speed);
  motorM4.setSpeed(speed);
}

/* dalej trochę porządku - wywalamy odbieranie danych do funkcji
 * i pozbywamy się jakichś kodów w programie.
 * Trzeba pamiętać o zasadzie maksymalnej izolacji - funkcja
 * odbierająca kody z pilota nie musi wiedzieć noc o silnikach,
 * również części programu odpowiadającej za silniki nie jest
 * potrzebna wiedza o jakichkolwiek kodach */

 int getIR()
 {
     uint32_t kod;
     if (!IrReceiver.decode()) return 0; // tu nie ma co dalej myśleć
     kod = IrReceiver.decodedIRData.decodedRawData;
     IrReceiver.resume();
     /* teraz zamieniam odeprane kody IR na właściwe
      * Oczywiście można (i trzeba) zrobić to prościej,
      * ale na razie to musi wystarczyć
      */

    int rc;
    switch(kod) {
        case C_PRZOD:
        rc=J_PRZOD;
        break;

        case C_WSTECZ:
        rc=J_WSTECZ;
        break;

        case C_LEWO:
        rc=J_LEWO;
        break;

        case C_PRAWO:
        rc=J_PRAWO;
        break;

        /* kody powtarzania na razie nas nie interesują,
         * traktujemy ja na razie jako pomijane */

        case C_REPEAT:
        case C_REPEAT2:
        rc = 0;
        break;
 
        /* i teraz dowolny klawisz będzie służyć jako STOP */

        default:
        rc = J_STOP;
        break;
    }

    /* później będziemy jeszcze bawić się zmienną rc
     * ale na razie po prostu przekażemy to do programu */

     return rc;
}

void loop() {
    /* najpierw odbieramy dane */
    int kod = getIR();

    /* a teraz interpretujemy odebrany kod */

    switch(kod) {
        case J_PRZOD:
        motorM1.run(FORWARD);
        motorM2.run(FORWARD);
        motorM3.run(FORWARD);
        motorM4.run(FORWARD);
        break;

        case J_WSTECZ:
        motorM1.run(BACKWARD);
        motorM2.run(BACKWARD);
        motorM3.run(BACKWARD);
        motorM4.run(BACKWARD);
        break;

        case J_LEWO:
        motorM1.run(FORWARD);
        motorM2.run(FORWARD);
        motorM3.run(BACKWARD);
        motorM4.run(BACKWARD);
        break;

        case J_PRAWO:
        motorM3.run(FORWARD);
        motorM4.run(FORWARD);
        motorM2.run(BACKWARD);
        motorM1.run(BACKWARD);
        break;

        case J_STOP:
        motorM3.run(RELEASE);
        motorM4.run(RELEASE);
        motorM2.run(RELEASE);
        motorM1.run(RELEASE);
        break;
    }
}

Reszta jutro (daj w międzyczasie znać czy ruszyło)

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

8 minut temu, BeeKeyPro napisał:

po co takie coś robić?

Czytelność, oraz łatwiej zaprowadzić zmiany, poprawki.

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

No to teraz przed tobą najfajniejszy etap nauki arduino: autopiloty, światłoluby, linefollowery, dodawanie różnych innych funkcji na pokład... mnóstwo potencjału. Gratuluję udanego projektu!

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

@BeeKeyPro już kolega wyjaśnił. W komentarzu masz coś o izolacji, prawda?

I od tej pory można zajmować się tylko funkcją getIR. Jeśli np. zmieni się pilot, albo w ogóle zasda przekazywania poleceń (np. radio) reszta programu nie musi nic wiedzieć o zmianach. Ty masz akurat prosty program, ale w bardziej skomplikowanych przypadkach (np. półautomatyczny robot) taka izolacja jest niezbędna.

No a jutro postaram się wrzucić do tej funkcji zależności czasowe.

@AntekBezak i najważniejsze - automat skończony aka maszyna stanów.

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

@ethanak

#include <IRremote.hpp>
#include <AFMotor.h>

AF_DCMotor motorM1(4);
AF_DCMotor motorM2(3);
AF_DCMotor motorM3(2);
AF_DCMotor motorM4(1);

const int RECV_PIN = A0;
boolean standiod = 1;
int speed=200;

#define J_PRZOD     0xBF40FF00
#define J_WSTECZ    0xE619FF00
#define J_LEWO      0xF807FF00
#define J_PRAWO     0xF609FF00
#define J_STOP      0xEA15FF00
#define L_ONOFF     0xBA45FF00
#define J_REPEAT    0x0

#define BIEG_1    0xF30CFF00
#define BIEG_2    0xE718FF00
#define BIEG_3    0xA15EFF00

void setup() {
  Serial.begin(9600);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  IrReceiver.begin(RECV_PIN);
}

void loop() {
  digitalWrite(A1, standiod);
  digitalWrite(A2, standiod);
  
  motorM1.setSpeed(speed);
  motorM2.setSpeed(speed);
  motorM3.setSpeed(speed);
  motorM4.setSpeed(speed);

  uint32_t kod = 0;
  if (IrReceiver.decode()) {
    kod = IrReceiver.decodedIRData.decodedRawData;
    Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
    IrReceiver.resume();
  }
  switch(kod) {
    case J_PRZOD:
    motorM1.run(FORWARD);
    motorM2.run(FORWARD);
    motorM3.run(FORWARD);
    motorM4.run(FORWARD);
    break;

    case J_WSTECZ:
    motorM1.run(BACKWARD);
    motorM2.run(BACKWARD);
    motorM3.run(BACKWARD);
    motorM4.run(BACKWARD);
    break;

    case J_LEWO:
    motorM1.run(FORWARD);
    motorM2.run(FORWARD);
    motorM3.run(BACKWARD);
    motorM4.run(BACKWARD);
    break;

    case J_PRAWO:
    motorM3.run(FORWARD);
    motorM4.run(FORWARD);
    motorM2.run(BACKWARD);
    motorM1.run(BACKWARD);
    break;

    case J_STOP:
    motorM3.run(RELEASE);
    motorM4.run(RELEASE);
    motorM2.run(RELEASE);
    motorM1.run(RELEASE);
    break;

    case L_ONOFF:
    standiod = !standiod;
    break;

    case BIEG_1:
    speed=100;
    break;

    case BIEG_2:
    speed=150;
    break;

    case BIEG_3:
    speed=250;
    break;
  }
}

 

Link do komentarza
Share on other sites

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

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.