How can I alter the IR statements to the new method using switch case

I am trying to alter an old program that uses the old method of decoding IR inputs. I have succeeded in almost all of the sketch but am stuck with a switch case section. Do you know what lines I need to be able to use a switch case with a IR input?

void getIRData() {
  //if (irrecv.decode(&results)){ 
  if (IrReceiver.decode()){
    IR_PreMillis = millis();
    //switch(results.value){
    //unsigned long val = IrReceiver.decodedIRData.command;
    switch(IrReceiver.decodedIRData.command());
      {
      case f:   func_mode = IRremote; mov_mode = FORWARD;  break;
      case b:   func_mode = IRremote; mov_mode = BACK;     break;
      case l:   func_mode = IRremote; mov_mode = LEFT;     break;
      case r:   func_mode = IRremote; mov_mode = RIGHT;    break;
      case s:   func_mode = IRremote; mov_mode = STOP;     break;
      case KEY1:  func_mode = LineTeacking;                break;
      case KEY2:  func_mode = ObstaclesAvoidance;          break;
      default: break;
      }
    //irrecv.resume();
         delay(1500);
    IrReceiver.resume();
  }
}

The whole sketch is quite long but I assume the problem is with the format for addressing the switch.
At the beginning of the sketch each case is defined a number i.e.
#define f 16736925 // FORWARD
#define b 16754775 // BACK
Whether the numbers are right is unimportant at this point, the sketch should still compile.
when I try to compile the sketch I get
Compilation error: expression cannot be used as a function.
for the line
switch(IrReceiver.decodedIRData.command());
If I uncomment val and use val in the brackets after switch instead I get the same error
If I use

  val = IrReceiver.decodedIRData.command;
    Serial.println(val);

The number assigned to the remote button shows up in the monitor so I know that is reading the remote.
Do you know what the line would be to call the IR input?
I am assuming I need the correct wording in the brackets after switch?
Can you help?

If the switch() is not working, print the return value of this (above) to Serial Monitor to understand what the switch() is seeing.

Post the entire sketch.

1 Like

Hi xfpd, thanks for replying

Do you think if I put the whole sketch in someone will comment on some other part of the sketch?
Here it is

#include <IRremote.h>
#include <Servo.h>  

#define f 16736925  // FORWARD
#define b 16754775  // BACK
#define l 16720605  // LEFT
#define r 16761405  // RIGHT
#define s 16712445  // STOP
#define KEY1 16738455 //Line Teacking mode
#define KEY2 16750695 //Obstacles Avoidance mode
#define KEY3 16756815
#define KEY4 16724175
#define KEY5 16718055
#define KEY6 16743045
#define KEY7 16716015
#define KEY8 16726215
#define KEY9 16734885
#define KEY0 16730805
#define KEY_STAR 16728765
#define KEY_HASH 16732845

//#define RECV_PIN  12
//#define IR_RECEIVE_PIN  12
const byte IR_RECEIVE_PIN=12;
#define ECHO_PIN  A4  
#define TRIG_PIN  A5 
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define LED_Pin 13
#define LineTeacking_Pin_Right  10
#define LineTeacking_Pin_Middle 4
#define LineTeacking_Pin_Left   2
#define LineTeacking_Read_Right   !digitalRead(10)
#define LineTeacking_Read_Middle  !digitalRead(4)
#define LineTeacking_Read_Left    !digitalRead(2)
#define carSpeed 250

Servo servo;
//put replacement for IRrecv irrecv(RECV_PIN);
//decode_results results;
unsigned long IR_PreMillis;
unsigned long LT_PreMillis;
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

enum FUNCTIONMODE{
  IDLE,
  LineTeacking,
  ObstaclesAvoidance,
  Bluetooth,
  IRremote
} func_mode = IDLE;

enum MOTIONMODE {
  STOP,
  FORWARD,
  BACK,
  LEFT,
  RIGHT
} mov_mode = STOP;

void delays(unsigned long t) {
  for(unsigned long i = 0; i < t; i++) {
    getBTData();
    getIRData();
    delay(1);
  }
}

int getDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  return (int)pulseIn(ECHO_PIN, HIGH) / 58;
}

void forward(bool debug = false){ 
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,HIGH);
  if(debug) Serial.println("Go forward!");
}

void back(bool debug = false){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1,LOW);
  digitalWrite(IN2,HIGH);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,LOW);
  if(debug) Serial.println("Go back!");
}

void left(bool debug = false){
  analogWrite(ENA,carSpeed);
  analogWrite(ENB,carSpeed);
  digitalWrite(IN1,LOW);
  digitalWrite(IN2,HIGH);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,HIGH); 
  if(debug) Serial.println("Go left!");
}

void right(bool debug = false){
  analogWrite(ENA,carSpeed);
  analogWrite(ENB,carSpeed);
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,LOW);
  if(debug) Serial.println("Go right!");
}

void stop(bool debug = false){
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
  if(debug) Serial.println("Stop!");
}
void getBTData() {
  if(Serial.available()) {
    switch(Serial.read()) {
      case 'f': func_mode = Bluetooth; mov_mode = FORWARD;  break;
      case 'b': func_mode = Bluetooth; mov_mode = BACK;     break;
      case 'l': func_mode = Bluetooth; mov_mode = LEFT;     break;
      case 'r': func_mode = Bluetooth; mov_mode = RIGHT;    break;
      case 's': func_mode = Bluetooth; mov_mode = STOP;     break;
      case '1': func_mode = LineTeacking;                   break;
      case '2': func_mode = ObstaclesAvoidance;             break;
      default:  break;
    } 
  }
}
void getIRData() {
  //if (irrecv.decode(&results)){ 
  if (IrReceiver.decode()){
    //IR_PreMillis = millis();
    //switch(results.value){
    // int val = IrReceiver.decodedIRData.command;
    unsigned long val = IrReceiver.decodedIRData.command;
    //  switch(decode.value);
    //switch(IrReceiver.decodedIRData.command());
     // {
     // case f:   func_mode = IRremote; mov_mode = FORWARD;  break;
     // case b:   func_mode = IRremote; mov_mode = BACK;     break;
    //  case l:   func_mode = IRremote; mov_mode = LEFT;     break;
     // case r:   func_mode = IRremote; mov_mode = RIGHT;    break;
     // case s:   func_mode = IRremote; mov_mode = STOP;     break;
     // case KEY1:  func_mode = LineTeacking;                break;
    //  case KEY2:  func_mode = ObstaclesAvoidance;          break;
    //  default: break;
    //  }
    //irrecv.resume();
     //    delay(1500);
    //IrReceiver.resume();
  }
}

void bluetooth_mode() {
  if(func_mode == Bluetooth){
    switch(mov_mode){
      case FORWARD: forward();  break;
      case BACK:    back();     break;
      case LEFT:    left();     break;
      case RIGHT:   right();    break;
      case STOP:    stop();     break;
      default: break;
    }
  }
}

void irremote_mode() {
  if(func_mode == IRremote){
    switch(mov_mode){
      case FORWARD: forward();  break;
      case BACK:    back();     break;
      case LEFT:    left();     break;
      case RIGHT:   right();    break;
      case STOP:    stop();     break;
      default: break;
    }
    if(millis() - IR_PreMillis > 500){
      mov_mode = STOP;
      IR_PreMillis = millis();
    }
  }   
}

void line_teacking_mode() {
  if(func_mode == LineTeacking){
    if(LineTeacking_Read_Middle){
      forward();
      LT_PreMillis = millis();
    } else if(LineTeacking_Read_Right) { 
      right();
      while(LineTeacking_Read_Right) {
        getBTData();
        getIRData();
      }
      LT_PreMillis = millis();
    } else if(LineTeacking_Read_Left) {
      left();
      while(LineTeacking_Read_Left) {
        getBTData();
        getIRData();
      }
      LT_PreMillis = millis();
    } else {
      if(millis() - LT_PreMillis > 150){
        stop();
      }
    }
  }  
}
void obstacles_avoidance_mode() {
  if(func_mode == ObstaclesAvoidance){
    servo.write(90);
    delays(500);
    middleDistance = getDistance();
    if(middleDistance <= 40) {
      stop();
      delays(500);
      servo.write(10);
      delays(1000);
      rightDistance = getDistance();
      
      delays(500);
      servo.write(90);
      delays(1000);
      servo.write(170);
      delays(1000); 
      leftDistance = getDistance();
      
      delays(500);
      servo.write(90);
      delays(1000);
      if(rightDistance > leftDistance) {
        right();
        delays(360);
      } else if(rightDistance < leftDistance) {
        left();
        delays(360);
      } else if((rightDistance <= 40) || (leftDistance <= 40)) {
        back();
        delays(180);
      } else {
        forward();
      }
    } else {
        forward();
    }  
  }  
}

void setup() {
  Serial.begin(9600);
  servo.attach(3,500,2400);// 500: 0 degree  2400: 180 degree
  servo.write(90);
 // irrecv.enableIRIn();
    IrReceiver.begin(IR_RECEIVE_PIN);//use pin 13
  pinMode(ECHO_PIN, INPUT);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(LineTeacking_Pin_Right, INPUT);
  pinMode(LineTeacking_Pin_Middle, INPUT);
  pinMode(LineTeacking_Pin_Left, INPUT);
}

void loop() {
  getBTData();
  getIRData();
  bluetooth_mode();
  irremote_mode();
  line_teacking_mode();
  obstacles_avoidance_mode();
}


The offending bit is commented out so I can find anything else that is wrong.

Does whatever this is satisfy the switch()?

Numbers would not be assigned if they were not important.

I forgot to also ask: Post the complete error.

Not important at this point. I just added it to point out that the remote is working and the rxer on the robot is rxing correctly.

At this point we are trying to get the program to compile, the numbers coming from the remote are unimportant.

Compilation error: expression cannot be used as a function

This happens when I don't comment out the void getIRdata as below

void getIRData() {
  //if (irrecv.decode(&results)){ 
  if (IrReceiver.decode()){
    //IR_PreMillis = millis();
    //switch(results.value){
    // int val = IrReceiver.decodedIRData.command;
    unsigned long val = IrReceiver.decodedIRData.command;
     // switch(decode.value);
    switch(IrReceiver.decodedIRData.command());
      {
      case f:   func_mode = IRremote; mov_mode = FORWARD;  break;
      case b:   func_mode = IRremote; mov_mode = BACK;     break;
      case l:   func_mode = IRremote; mov_mode = LEFT;     break;
      case r:   func_mode = IRremote; mov_mode = RIGHT;    break;
      case s:   func_mode = IRremote; mov_mode = STOP;     break;
      case KEY1:  func_mode = LineTeacking;                break;
      case KEY2:  func_mode = ObstaclesAvoidance;          break;
      default: break;
      }
    //irrecv.resume();
     //    delay(1500);
    //IrReceiver.resume();
  }

It highlights the switch line and all the case lines including the default line as the error.

I doubt both, but you seem to have the important parts under control.

Not that anything I say means anything important, or at all, but I have no errors compiling using IRremote.h by shiriff on a Nano.

Sketch uses 11090 bytes (36%) of program storage space. Maximum is 30720 bytes.
Global variables use 780 bytes (38%) of dynamic memory, leaving 1268 bytes for local variables. Maximum is 2048 bytes.

Are you using the full sketch I posted or have you uncommented the lines as in the small part at the end of my last post?
With the full sketch I get a good compile because the error is in the void getIRData section that is commented out of the full sketch.

I lost everything yesterday, or the day before and couldn't understand why so I decided to leave it for a while
After further thought I revisited my IRremote library and found I had updated it to the shiriff 4.3.1 and the sketch needs the shiriff 2.0.1 version. After I had removed the new one and reloaded the 2.0.1 the robot started working again.
The original reason for this thread was to try to get help to alter the sketch so it would work on the 4.3.1.
I have decided to just use the 2.0.1 and have spent this evening trying to alter the working sketch to add a set of mecanum wheels before realising that this robot only has one controller and both the left set of wheels are locked from one half of the controller and the right set together from the other half. Macanum wheels need all four wheels to be independent. So altering is going to be harder than I thought.
I would still like to alter the sketch so I can use the 4.3.1 library but I can't see how yet.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.