Skocz do zawartości

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

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

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
8 minut temu, BeeKeyPro napisał:

po co takie coś robić?

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

  • Lubię! 1

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

@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

@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;
  }
}

 

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