Как использовать несколько ИК-сигналов для того же? - PullRequest
0 голосов
/ 14 января 2019

Я хочу использовать разные сигналы от разных ИК-пультов для управления колесным роботом.

Робот - это автомобильный комплект Smart robot v1.0 от Elegoo.
Я использовал файл infrared_remote_control_car.ino с диска вместе с ним.
Я только добавил #define JVC и операторов в конце.

Код выглядит так:

#include <IRremote.h>
int receiverpin = 12;
int in1=9;
int in2=8;
int in3=7;
int in4=6;
int ENA=10;
int ENB=5;
int ABS=130;
unsigned long RED;

#define A 16736925
#define B 16754775
#define X 16712445
#define C 16720605
#define D 16761405

#define JVCfront 49816
#define JVCback 49688
#define JVCright 49704
#define JVCleft 49832
#define JVCmenu 49900
#define JVC3ok 49724
#define JVCstop 49856


IRrecv irrecv(receiverpin);
decode_results results;

void _mForward()
{  
  digitalWrite(ENA,HIGH);
  digitalWrite(ENB,HIGH);
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
  Serial.println("go forward!");
}
void _mBack()
{
  digitalWrite(ENA,HIGH);
  digitalWrite(ENB,HIGH);
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
  Serial.println("go back!");
}
void _mleft()
{
  analogWrite(ENA,ABS);
  analogWrite(ENB,ABS);
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
  Serial.println("go left!");
}
void _mright()
{
  analogWrite(ENA,ABS);
  analogWrite(ENB,ABS);
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
  Serial.println("go right!");
}
void _mStop()
{
  digitalWrite(ENA,LOW);
  digitalWrite(ENB,LOW);
  Serial.println("STOP!");  
}
void setup() {
  pinMode(in1,OUTPUT);
  pinMode(in2,OUTPUT);
  pinMode(in3,OUTPUT);
  pinMode(in4,OUTPUT);
  pinMode(ENA,OUTPUT);
  pinMode(ENB,OUTPUT);
  pinMode(receiverpin,INPUT);
  Serial.begin(9600);
  _mStop();
  irrecv.enableIRIn();
}

void loop() {
  if (irrecv.decode(&results))
  {
    RED=results.value;
    Serial.println(RED);
    irrecv.resume();
    delay(150);
    if(RED==(A || JVCfront))
    {  
       _mForward();
    }
    else if(RED==(B or JVCback))
    {
      _mBack();
    }
    else if(RED==(C or JVCleft))
    {
      _mleft();
    }
    else if(RED==(D or JVCright))
    {
      _mright();
    }
    else if(RED==(X or JVCstop or JVCmenu or JVC3ok))
    { 
      _mStop();
    }
  }
} 

Я пробовал разные способы, которыми я видел в интернете для оператора ИЛИ, как вы можете видеть. На самом деле, робот всегда идет вперед.

1 Ответ

0 голосов
/ 14 января 2019

Всегда ли Serial.println(RED) распечатывает ожидаемое значение? Ваш if-else блок на первый взгляд не кажется проблематичным. Не имеет значения, используете ли вы || или or. Они эквивалентны. Проблема в том, как вы проверяете значение:

Поэтому, если у вас есть круглые скобки в операторе OR, вы создаете значение bool. if(RED==(A || JVCfront) переводится как:

  • установлен A установлен или JVCfront установлен; это означает, что они! = 0 (да, они оба, так что это выражение true
  • - это RED == true (нет, это не так, потому что true представляет 1 в целых числах)
  • поэтому код в этом блоке не выполняется

Если вы хотите решить это с помощью if-else, вам необходимо:

if(RED == A or RED == JVCfront)
{
    _mForward();
}

Во всяком случае, я бы предложил заявление о переключении:

switch(RED):
{
    case A:
    {
        //intentional fallthrough
    }
    case JVCfront:
    {
        _mForward();
        break;
    }
    case B:
    {
        //intentional fallthrough
    }
    case JVCback:
    {
        _mBack();
        break;
    }
    case C: 
    {
        //intentional fallthrough
    }
    case JVCleft:
    {
        _mleft();
        break;
    }
    case D:
    {
        //intentional fallthrough
    }
    case JVCright:
    {
        _mright();
        break;
    }
    case X:
    {
        //intentional fallthrough
    }
    case JVCstop:
    {
        //intentional fallthrough
    }
    case JVCmenu:
    {
        //intentional fallthrough
    }
    case JVC3ok:
    {
        _mStop();
        break;
    }
    default:
    {
        _mStop();
    }
}

Лично я нахожу этот код намного проще для чтения и более понятным. Обратите внимание: если вы не поместите break в футляр, он автоматически выполнит и следующую case. Вот почему я написал //intentional fallthrough в этой части кода. Возможная ошибка когда case A выполняется, ничего не происходит. Он просто падает в case JVCFront и выполняет там все.

...