#PLEASE# Extremely expert at IR remote controller ## PLEASE ##

Problem fixed at the last page

Hi, i have been struggling for a while. if you have a look and find any solution i would be appreciate.

The problem is occuring AT THE VOID LOOP IN THE SWITCH CASE ;

when any of the case (east, south, west or north) selected by IRremote controller, the case`s functions executes well. But the program not allowed to switch another cases.

[b]How to switch between cases and execute all if functions in the selected case ?[/b]
#include <Wire.h> 
#include <HMC5883L.h> 
HMC5883L compass; 



#include <IRremote.h>   
int RECV_PIN = 7;        //  
IRrecv irrecv(RECV_PIN);
decode_results results;

#define on/off 16712445 
#define east   16761405
#define south  16754775 
#define west   16720605 
#define north  16736925 





void setup() 
{ 
   irrecv.enableIRIn(); // Start the receiver
   
  
  Serial.begin(9600); 
  Wire.begin(); 
  compass = HMC5883L(); 
  compass.SetScale(1.3); 
  compass.SetMeasurementMode(Measurement_Continuous); 
  pinMode(13, OUTPUT);    //led1
  pinMode(12, OUTPUT);    //led2
  pinMode(11, OUTPUT);    //led3
  pinMode(10, OUTPUT);    //led4
 
 
} 
void loop() 
{ 
MagnetometerScaled scaled = compass.ReadScaledAxis(); 
  float xHeading = atan2(scaled.YAxis, scaled.XAxis); 

  if(xHeading < 0) xHeading += 2*PI; 

  int xDegrees = xHeading * 180/M_PI; 

  Serial.println(xDegrees); 
  delay(500);
    if (irrecv.decode(&results))
    unsigned int value = results.value;
    
   
      
      switch(value)   
{
      case east:
      digitalWrite(10, HIGH);
}
      break;
     case south:
  {      
    digitalWrite(11, HIGH);
}

   break;
   case west:
  {      
   digitalWrite(12, HIGH);
  }
   break;
   case north:
  {      
    digitalWrite(13, HIGH);
    servo.write (90);
  }
   
  }
}

when mixing || &&, use parenthesis.

i'd say 1- run your program and show serial output debug (add more println in the code) 2- explain better your issue. it's not clear.

cheers.

sonyhome: when mixing || &&, use parenthesis.

i'd say 1- run your program and show serial output debug (add more println in the code) 2- explain better your issue. it's not clear.

cheers.

I would like to switch between cases by IRremote controller. but the program allow me only one time select a case. hopefully i have enough explained other wise i record a video.

  MagnetometerRaw raw = compass.ReadRawAxis(); 
  MagnetometerScaled scaled = compass.ReadScaledAxis();

Which do you need? There doesn't seem to be a good reason to read both.

    if (irrecv.decode(&results)) {
    unsigned int value = results.value;
    
    delay(500);

There certainly isn't a good reason to wait half a second after receiving an IR signal.

But the program not allowed switch to another cases. if i type irrecv.resume()

You can't just leave it out and expect to receive another signal. If putting the call to the resume() method in causes problems, it is likely because it is in the wrong place.

PaulS:

  MagnetometerRaw raw = compass.ReadRawAxis(); 

MagnetometerScaled scaled = compass.ReadScaledAxis();



Which do you need? There doesn't seem to be a good reason to read both.



if (irrecv.decode(&results)) {
    unsigned int value = results.value;
   
    delay(500);



There certainly isn't a good reason to wait half a second after receiving an IR signal.
You can't just leave it out and expect to receive another signal. If putting the call to the resume() method in causes problems, it is likely because it is in the wrong place.

both of them can stay cos, compass and servo works well each other. i could delete delay(500) but it does not bring the solution.

the problem is in the switch case

both of them can stay cos, compass and servo works well each other.

But, do they need to? Why bother reading the raw data when you never use it?

the problem is in the switch case

I seriously doubt that.

PaulS:
But, do they need to? Why bother reading the raw data when you never use it?
I seriously doubt that.

it has been updated . Thanks for remind me
But cause still there :slight_smile:

it has been updated

So, you changed the code in your first post, that we have been commenting on, making us look like idiots. Well, good luck with your code.

PaulS:
So, you changed the code in your first post, that we have been commenting on, making us look like idiots. Well, good luck with your code.

If i did not respect your word i would not update the first post. The purpose of the update is more clear the coding to understand others. Thanks so far.

You need to debug your code:

I strongly suggest you test your case statement using Serial.println() statements that tell you which one ran, while having the serial console on your PC (look for it in the IDE, and look for examples if you don't know how to code for it. Set the baud rate to 9600).

Instead of feeding your IR codes in the case statement, do a mock where you assign the values by hand before going into the case statement.

That way you will find your bug there.

Then you can remove the mock and feed the real IR code output.

Myself I have not played with that libnrary and do not know what you are expected to get.

while i check the program on serial monitor that shows only which button pressed and the hex code ruining continuously. if i pressed another button from IR remote noting change on the serial monitor

Hello,

Add some debug prints:

unsigned int value = results.value;

Serial.println( value );

does it print the expected result ?

If it doesn't print anything, then it's because irrecv.decode(&results) returned false for some reason.

Also: an unsigned int cannot store a value greater than 65535. So that may be your problem because you are comparing it with a much bigger value (for example 16761405). Try change the type of "value" to unsigned long.

Do not cross-post. Do not cross-post. Do not cross-post. Duplicate removed. Threads merged.

From this page:

https://www.pjrc.com/teensy/td_libs_IRremote.html

irrecv.resume()
After receiving, this must be called to reset the receiver and prepare it to receive another code.

So without a resume call somewhere in there, you’re pretty much limited to only receiving one code and then you’re done with IR until you reset the board.

guix:
Hello,

Add some debug prints:

unsigned int value = results.value;

Serial.println( value );




does it print the expected result ?

If it doesn't print anything, then it's because irrecv.decode(&results) returned false for some reason.

Also: an unsigned int cannot store a value greater than 65535. So that may be your problem because you are comparing it with a much bigger value (for example 16761405). Try change the type of "value" to unsigned long.

It is print the expected result but olny which button pressed first. The hexadecimal number flows endlessly.
I may use irrecv.resume () but it is stoping loop in the cases

cigilgan: It is print the expected result but olny which button pressed first. The hexadecimal number flows endlessly. I may use irrecv.resume () but it is stoping loop in the cases

Without a call to resume, the first one is the only one you can get.

Perhaps you should show the code with the resume call so we maybe see why you think that stops your loop.

Delta_G: Without a call to resume, the first one is the only one you can get.

Perhaps you should show the code with the resume call so we maybe see why you think that stops your loop.

would you mind to have a look at structure of the void loop deeply. I believe that i made mistake on building structure.

i will attached a video then show your demand

Regards

Not much good without the codes to go with them.

Where did you put the resume call?

Looking at your code, it seems to be that it should work.

I notice that you serial print xDegrees. It might help to also print results.value .

I also notice that you have some very specific constants for n/s/e/w

#define on_off 16712445 // code received from button ok
#define east   16761405 // code received from button RIGHT
#define south  16754775 // code received from button DOWN
#define west   16720605 // code received from button LEFT
#define north  16736925 // code received from button UP

These would be much better expressed in hexadecimal as

#define on_off 0xFF02FD // code received from button ok
#define east   0xFFC23D // code received from button RIGHT
#define south  0xFFA857 // code received from button DOWN
#define west   0xFF22DD // code received from button LEFT
#define north  0xFF629D // code received from button UP

And this reveals your first problem. The numeric constants you are using are 6 bytes long! But this is not as big a problem as it seems, because you are putting the result into an unsigned int. These constants are not declared as being of type long, so I imagine the compiler is truncating them in the case statement and the values work ok. Still, it’s weird.

Now, your case statement won’t do anything unless value is exactly one of these numbers.

What I’m thinking is that your IRrecv sends these particular, specific values only the first time it activates, and in subsequent button presses it sends something slightly different.

The cause of this is probably that certain bits in the value represent the button that was pressed, and certain other bits represent “oh, and by the way, I have counted X button presses so far” or other things.

Let’s have a look at the documentation - silly me, you didn’t say what hardware you were using. I’m going to have to guess. Accoding to google, you might be using this one: A Multi-Protocol Infrared Remote Library for the Arduino .

Ok, it seems to me that you need to look more at the details of what codes the particular IR transmitter you are using sends. But I do notice that the web page for the library (if I have the right one) has this gem:

Troubleshooting
To make it easier to debug problems with IR communication, I have optional debugging code in the library. Add #define DEBUG to the beginning of your code to enable debugging output on the serial console. You will need to delete the .o files and/or restart the IDE to force recompilation.

Why not try that?

Alternatively, just add a

Serial.println(results.value)

To see what is actually going on. It would be much easier to do this in hexadecimal, because hexadecimal exposes the bit patterns. Here’s a sketch for you to try:

#define on_off 16712445 // code received from button ok
#define east   16761405 // code received from button RIGHT
#define south  16754775 // code received from button DOWN
#define west   16720605 // code received from button LEFT
#define north  16736925 // code received from button UP

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(1000);
  Serial.print(on_off); Serial.print(" = "); printHex(on_off); Serial.println();
  Serial.print(east); Serial.print(" = "); printHex(east); Serial.println();
  Serial.print(south); Serial.print(" = "); printHex(south); Serial.println();
  Serial.print(west); Serial.print(" = "); printHex(west); Serial.println();
  Serial.print(north); Serial.print(" = "); printHex(north); Serial.println();
}

void printHex(unsigned int x) {
  for(int i = 0; i<4; i++) {
    Serial.print((char)((x>>12)+((x>>12)<10?'0':('A'-10))));
    x <<= 4;
  }
}

Hi i am responding to PaulMurrayCbr.

sorry for not mention before what kind of IRremote i use.

http://www.ebay.co.uk/itm/New-Infrared-IR-Wireless-Remote-Control-Module-Kits-for-Arduino-/271719947271?pt=LH_DefaultDomain_3&hash=item3f43c55c07

as a library i use that one;

https://github.com/shirriff/Arduino-IRremote

Also i have tried the program with hexadecimal code but failed. i just know that i have to convert from hexadecimal to decimal , if i am wrong pls let me correct.

Regards