Go Down

Topic: IRremoteNEC library problem (Solved) (Read 236 times) previous topic - next topic

IamFof

Jun 23, 2019, 11:42 am Last Edit: Jun 24, 2019, 12:47 am by IamFof
Guys
Working on a project that uses an NEC coded remote.
Originally I was using a different IR library but it gave me a problem, as it used Timer2, which disabled some of the PWM pins.  Larryd gave me a link to this library, which uses interupts instead.

The only changes I have made to the original sketch are:-
Changed the first 3 values in the buttonCode[] array, to match my remote and added some Serial.print commands.  I also changed the baud rate to use the serial monitor

I can see that myRemote.getIRflag() changes state when I press a button, however, the variable byteRX never gets anything other than 0.

Any ideas?
Code: [Select]
//*****************************************************************************
//17 button IR remote
//NEC - IR code
//By: LarryD
//
//This sketch demonstrates interfacing to a 17 button IR remote. http://goo.gl/Jk79FM
//These are commonly available on eBay for $2 USD.
//The remote usually comes with a controller.
//It is an all in one IR detector/amplifier similar to TSOP38238, yours may vary
//**Always confirm the detector/amplifier you have is wired as per YOUR data sheet**
//Remove the detector from the controller for this discussion and wire it to +5V and GND.
//Datasheet for the IR detector: https://www.sparkfun.com/datasheets/Sensors/Infrared/tsop382.pdf
//For wiring, see:               https://learn.sparkfun.com/tutorials/ir-control-kit-hookup-guide
//Interrupt 0 (pin D2) is used to achieve fast receive response.
//See also:                      http://forum.arduino.cc/index.php?topic=289446.msg
//

//**************************************

#include <IRremoteNEC.h>
//We must use an interrupt pin, 2 or 3 on an UNO, Ethernet or ATmega1284
//connect this pin to the IR Receiver Module
//#define interruptPin 3  

#define interruptPin 2

//confirm the correct interrupt pin has been selected
#if interruptPin != 2 && interruptPin != 3
#error interruptPin must be 2 or 3!
#endif
IRremoteNEC myRemote(interruptPin); //create the object using this pin

//**************************************

#define tonePin 7            //Piezo speaker is connected to this pin

//*****************************************************************************
//17 button Keypad
const byte buttonCode[18] = {
  0x97,0xCF,0xE7,                  // My amended values
  0x43,0x15,0x00, //0X00 is not defined
  0x16,0x19,0x0D,
  0x0C,0x18,0x5E,
  0x08,0x1C,0x5A,
  0x42,0x52,0x4A
}; //END of buttonCode Array

const byte ASCIIcode[18] = {
  // ^    <   New line  
  0x5E,0x3C,0x0A,
  // >    v  nul
  0x3E,0x76,0x00,
  // 1    2    3
  0x31,0x32,0x33,
  // 4    5    6
  0x34,0x35,0x36,
  // 7    8    9
  0x37,0x38,0x39,
  // *    0    #
  0x2A,0x30,0x23
}; //END of ASCIIcode Array

//*****************************************************************************

void setup(void)
{
  Serial.begin(9600);              // Baud changed from 115200

  myRemote.beginIR();

}
//************************** E N D   s e t u p ( ) *****************************

void loop(void)
{
  //**************************************
  //Check if we have received a valid IR code yet.
  if(myRemote.getIRflag())
  {
     Serial.print("I'm in and the Flag is ");
     Serial.println(myRemote.getIRflag());
     delay(50);
    byte byteRX = myRemote.checkCode();
     Serial.print("byteRX = ");
     Serial.println(byteRX);
     delay(50);
    //If we get a verified button code, convert it to an ASCII code.
    if(byteRX)
    {          
      //Scan through the buttonCode Array.
      //NOTE: IR remote repeat codes are not returned.
      for (int i = 0; i < 18; i++)
      {
        if (buttonCode[i] == byteRX)
        {
          tone(tonePin,3400,100);
          Serial.print(char(ASCIIcode[i])); //get the ASCII code

          //We found it, no need to continue looking.
          break;
        }
      }
    } // END of if(byteRX)

    //Get ready for the next falling edge.
    myRemote.resetIRflag();

  } // END of if(myRemote.getIRflag())
  //**************************************

  // Other loop stuff goes here

}
//************************** E N D   l o o p ( ) *****************************






//=============================================================================
//                             END OF CODE
//=============================================================================

6v6gt

This looks remarkably like https://forum.arduino.cc/index.php?topic=622733.msg4219212#msg4219212 which you appear to have abandoned.

Where did you get the library? Are you sure a single byte is long enough for the code you are receiving ? An NEC device normally returns a 32bit value.

IamFof

6v6gt
As the focus of the problem moved from the array to the library, I thought I had better start a new thread.  I did amend the other thread to say it was closed and a new thread started, and linked to this one.

The library came from larryd, who is also the auther.  I did wonder about that, but I couldn't see larryd making a basic mistake like that.  As I said, I made no functional changes to the code.

I will try changing to long and see what we get.

IamFof

#3
Jun 23, 2019, 01:02 pm Last Edit: Jun 23, 2019, 01:07 pm by IamFof
Changing byteRX to long still returned 0.

I assumed byteRX, being a byte, would only return the least significant byte of the NEC code.

6v6gt

It is still not clear which library you are using.
I don't really want to risk getting you into a bigger mess but this library, which I wrote recently, does work and does not use a timer and is very simple:
https://forum.arduino.cc/index.php?topic=619622.0

If you want to try it, I will help you to get started.

IamFof

Thanks.  I'll give it a try, later.
I would still like to understand why this doesn't work.
The library came from  https://forum.arduino.cc/index.php?topic=317625.0 
This link was supplied by larryd in older thread.

6v6gt

OK. One advantage of keeping a thread together is that you don't need to repeat such details.

Anyway, the NEC remote control units I have used do not fulfill this prerequisite in the library you have used:

Code: [Select]


      //This remote always sends: 0x00 as Address and  0xFF as ~Address
      //Example: 0x00  0xFF  0x04  0xFB would be a valid message
      //Was this a valid IR code?  i.e. Address = ~Address && Data = ~Data

      if((data[0] == (~data[1] & 0xFF)) && (data[2] == (~data[3] & 0xFF)))
      {
           //data[2] contains the valid IR button code
           byteRecived = data[2];
       }


If that is the case for you, i.e. your remote control uses extended NEC protocol, you could try changing the if clause to:

Code: [Select]

      // if((data[0] == (~data[1] & 0xFF)) && (data[2] == (~data[3] & 0xFF)))
      // {
           //data[2] contains the valid IR button code
           byteRecived = data[2];
      // }


to disable the check. Only the statement  byteRecived = data[2];  is active.

If you change libraries, it is usually better to copy them, that is the .h and .cpp part into the sketch folder and change the #include statement  in the sketch to this format:

Code: [Select]
#include "IRremoteNEC.h"

instead of:

Code: [Select]
#include <IRremoteNEC.h>






IamFof

@6v6gt

Interesting.  I did wonder if the remote might not be sending real NEC codes.  It did, however, work with the previous library.  I do have another remote coming and I'll see if that works, but I doubt it.

I modified the .cpp file in the zip file, deleted the library, then reinstalled the modified version.  No difference, unfortunately.  It'll be interesting to see any comments from larryd, if he picks up on the thread.

Well, I guess your IRremote library will be the third :)  :)  :)

Thanks for the input.

Fof

IamFof

Well I have down loaded your library.  Haven't tried it yet - soon.
When I looked at the file, my first thought was, gulp!!, but once I actually read it, I understand (I think) what you are doing.  I'll soon find out when I start merging the two. :)
I have 2 questions
a) you use a baud rate of 19200 and writing to the serial monitor which uses 9600.  Nearly every sketch I have seen use 9600, but while trying to get an IR remote library, they all use 19200 or greater.  What should the baud rate be set at?
b) In this line.
Code: [Select]
      if ( (i+1) % 8 == 0  ) Serial.print(' ' ) ;
you are inserting a space every 8 bits, but I don't understand the use of the % (remainder) operator.
Thanks

IamFof

I hang my head in shame. :smiley-eek-blue:  :smiley-roll-blue:   After all this time I didn't realise I could change the monitor baud rate.  Duhhhh!!

6v6gt

OK. Good. Did that solve all your problems ?
The % operator is modulus division and I am testing the remainder. I'm simply using a trick to make some spaces in the serial output for readability.

IamFof

Nearly.  :)

I have run the example program.
When you print the raw data,
Code: [Select]
    for ( uint8_t i = 0 ; i < 32 ; i++ )   {
      Serial.print( bitRead( nsIrNec::dataRaw, i ) ) ;
      if ( (i+1) % 8 == 0  ) Serial.print(' ' ) ;
    }

it gives me 0000 0000 0000 0000.  It then prints the interpreted data.
Here in lies another puzzle.
I have a list of the NEC codes I transmit.  These came from on line and from a sketch I found.
With the first library I tried, these codes worked perfectly, but used Timer2.
The second library was written for 17 or 44 button remotes and their NEC code allocations appear to be different, and probably, as you suggest, use a different protocol.
With this one, the interpreted value does not agree with my transmitted value.  My Tx for 1 = FF30CF, the interpreted value returned is FF0CF3.  my Tx for 9 = FF52AD, the interpreted value returned is FF4AB5.
Somehow the bit  bashing  over bashed. :)
I can use it happily, by remapping what the library thinks I've sent.


IamFof

Just reread the line inserting spaces.  Need to ponder it.  You aren't inserting a space after every 8 bits, are you, as I suggested? Research needed.

6v6gt

don't worry about this piece of code:

 
Code: [Select]
 
   // print raw data
   for ( uint8_t i = 0 ; i < 32 ; i++ )   {
     Serial.print( bitRead( nsIrNec::dataRaw, i ) ) ;
     if ( (i+1) % 8 == 0  ) Serial.print(' ' ) ;
   }
   Serial.println();


That is simply to show the received data in another format.
It worries me that you are seeing all 0s though. You should see a bit map of the 32 bit value returned.

Important is what you get back with this statement:

 
Code: [Select]
  Serial.println(nsIrNec::dataOut,HEX) ;

Are you getting back some more or less plausible looking codes  from this one ?

For example. when you say this:

Quote
My Tx for 1 = FF30CF, the interpreted value returned is FF0CF3.
Does the FF0CF3 come from my library ?  If so, I'll investigate that. However, you can still ma to the expected results.

IamFof

I realised what it was, just suprised it returned 0s.
The FFC053 I get, comes back from you.  I looked at the binary and it appears that each byte is transposed.
Now to remap my remote and do the merge.

Many thanks.  Mucho kudos.

Go Up