Replacing my Sony remote with Arduino. Can't input code from console.

Hello all,

I received a Sony amplifier/receiver from a friend, but I didn’t get the remote control for it.
I really need the remote as there are some important functions that I can’t access without it. So I dedided to replace the remote with an Arduino+IR LED.
So far so good, I had some progress.
Using the IRRemote library I can test with the example sketch IRsendDemo. It uses the Sony protocol that is explained here:
http://www.sbprojects.com/knowledge/ir/sirc.php

I managed to find the device type as Cassete Deck/Tuner as it responded to the Power on/off commands. And some muting/volume commands.

I can construct the command in HEX format and I send it to the Sony unit via that sketch that sends it once every 5 seconds.

Now, since this is so time consuming finding (calculating) the right codes to get me into the menu, I decided it’s best if I manage to input the codes in HEX format from the console, and then the Arduino would send them via the IR LED.

This is where I am stuck. Because the code is 12bit long, and I have no idea on how to read these 12bits from the console and send them to the IR.

This is the code for the example sketch:

#include <IRremote.h>

IRsend irsend;

void setup()
{
}

void loop() {
	for (int i = 0; i < 3; i++) {
		irsend.sendSony(0x481, 12);
		delay(40);
	}
	delay(5000); //5 second delay between each signal burst
}

The arguments for the irsend.sendSony function are code in HEX (0x481) and number of bits (12 always in this case).

Anyway, this should be a great tutorial on how to replace your lost remotes! Sadly I can’t even borrow one to “steal” the codes but there’s a few lists with the most common functions, and anyway I can test for codes. But putting one in the sketch, then uploading it every time I test a code is time consuming. Would be great to input the codes from the console.
Also it would be useful to input the code in binary as well (I think it’s more recommended actually in this testing phase).
Later on, I might get a keypad and make a more permanent setup but I only really need to adjust a few settings regarding the output levels on each speaker etc. I can move my ass and manually adjust the volume, but no way I can access those configuration items without a remote (I’ve checked).
So, any ideas on how to read bytes from the console and send them to the IR LED?

I just found the codes for my remote! At this website they have loads of codes for remote controls:

Now, I have used the older AV1 format for my tests, but it seems these are AV2 format in 15bits.
So I prefer to use this format so I can make use of all these codes. The whole remote control is mapped, so I only need to use the codes to browse the menus.
Now, I need a way to input the codes from console, as the menu has a time-out usually and it's a pain to navigate up/down and make settings with having to upload each time I change a code.

begin codes
          BTN_SLEEP                0x030C
          BTN_POWER                0x540C
          BTN_VIDEO1               0x220C
          BTN_VIDEO2               0x3C0C
          BTN_VIDEO3               0x210C
          BTN_DVD                  0x5F0C
          BTN_SAT                  0x600D
          BTN_TV                   0x2B0C
          BTN_SA_CD                0x520C
          BTN_TUNER                0x420C
          BTN_2CH                  0x410D
          BTN_AFD                  0x210D
          BTN_MOVIE                0x610D
          BTN_MUSIC                0x490D
          KEY_1                    0x000C
          KEY_2                    0x400C
          KEY_3                    0x200C
          BTN_AMP_MENU             0x770D
          KEY_4                    0x600C
          KEY_5                    0x100C
          KEY_6                    0x500C
          KEY_7                    0x300C
          KEY_8                    0x700C
          KEY_9                    0x080C
          KEY_0                    0x480C
          BTN_DVD_MENU             0x5A0D
          BTN_DISPLAY              0x690C
          BTN_MUTING               0x140C
          BTN_LEFT                 0x2F0D
          BTN_UP                   0x0F0D
          BTN_RIGHT                0x6F0D
          BTN_DOWN                 0x4F0D
          BTN_SELECT               0x180C
          BTN_VOLUME_UP            0x240C
          BTN_VOLUME_DOWN          0x640C
      end codes

So, how do I input 15bit info into the console, so it's passed to the function?

And this is my code, but it's not working:

int x;
String str;
int y;

#include <IRremote.h>

IRsend irsend;

void setup() {

 Serial.begin(9600);

}

void loop() {
    if(Serial.available() > 0)
    {
        str = Serial.readStringUntil('\n');
        x = Serial.parseInt();

        remo();
    }


}

void remo () {
  for (int i = 0; i < 3; i++) {
		irsend.sendSony(str, 15);
		delay(40);
  }
}

I get this error:
Applications/Arduino.app/Contents/Java/libraries/Arduino-IRremote-master/IRremote.h:275:10: note: void IRsend::sendSony(long unsigned int, int)
void sendSony (unsigned long data, int nbits) ;
^
/Applications/Arduino.app/Contents/Java/libraries/Arduino-IRremote-master/IRremote.h:275:10: note: no known conversion for argument 1 from 'String' to 'long unsigned int'

Parsing (hex and binary) with test program

class MiniParser {
  public:
    byte bMax;  // last index
    byte bRS;   // record seperator
    byte bPos;  // next write position
    byte *pBuf; // workspace
    MiniParser(byte* extBuffer, byte bLen, byte bDlm = '\r') {
      pBuf = extBuffer;
      bMax = bLen - 1;
      bRS = bDlm;
      bPos = 0;
    };
    int parse() {
      if (Serial.available()) {
        byte bCurr = Serial.read();
        if (bCurr == bRS) {
          if (0 == bPos) return 0;  // empty line suppression
          pBuf[bPos] = 0;
          bPos = 0;
          return 1;
        }
        if (bPos == 0 && (bCurr == ' ' || bCurr == '\t' || bCurr == '\n')) return 0;  // skip WS in front
        if (bPos >= bMax) return -1;  // guard buffer, signal overrun
        pBuf[bPos++] = bCurr;
      }
      return 0;
    };
};

const byte bBufferLen = 16;
byte bBuffer[bBufferLen] = { 0, };

MiniParser mini(bBuffer, bBufferLen);

void setup() {
  Serial.begin(115200);
  Serial.println("Enter hex values (12A 0x12A 0b111011), one per line");
}
unsigned long rValue;
void loop() {
  char* eoParse;
  if (mini.parse() == 1) {
    if (bBuffer[0] == '0' && (bBuffer[1] == 'b' || bBuffer[1] == 'B')) {
      rValue = strtoul((char*)bBuffer + 2, &eoParse, 2);
      Serial.print("bin ");
    } else {
      rValue = strtoul((char*)bBuffer, &eoParse, 16);
      Serial.print("hex ");
    }
    Serial.print("line '");
    Serial.print((char*)bBuffer);
    Serial.print("' hex 0x");
    Serial.print(rValue, 16);
    Serial.print(" bin 0b");
    Serial.println(rValue, 2);
    if (*eoParse) {
      Serial.print("*** undecoded '");
      Serial.print(eoParse);
      Serial.println("'");
    }
  }
}

Should be easy to implant. :wink:

0x denotes the value as hex.

It is already "binary".

a long unsigned int = 4 bytes of RAM = 0000-0000-0000-0000

A code of say (0x)300C is 30 0C. 30 0C in decimal is 12300. In binary it is 0011-0000-0000-1100.

0x denotes hex.
0b denotes binary.

The computer can not tell the difference...you can give it a binary number as:

byte a = 0b00000001

which is the same as

byte a = 0x1

which is the same as:

byte a = 1

@Johnny010: How does this information help in converting a serial ascii stream containing hexadecimal or binary values?

Since you know all the codes I suggest baking them into the program and making up key commands that you type into the console, using your keyboard as a remote.

I found a sketch that I made early in a project to test out sending codes to my Blu-ray player. It interprets 'a' and 's' as volume up /down and 'l' and 'r' as remote arrows left and right.

It sure seem easier than typing in commands.

/*
    IR Remote
 */

#include <IRremote.h>

IRsend irsend;

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

}

byte inKey;

void loop() {

  if( Serial.available() )
  {

    inKey = Serial.read();

    switch(inKey)
    {
    case 's':
    case 'S':
      // volume up
      for (int i = 0; i < 3; i++) {
        irsend.sendNEC(0x20df40bf, 32);  // volume up
        delay(40);
      } // for

      break;

    case 'a':
    case 'A':
      // volume down
      for (int i = 0; i < 3; i++) {
        irsend.sendNEC(0x20dfc03f, 32);  // volume down
        delay(40);
      } // for

      break;

    case 'l':
    case 'L':
      // left
      irsend.sendNEC(0x20dfE01F, 32);  // arrow left
      delay(40);
      break;

    case 'r':
    case 'R':
      // right
      irsend.sendNEC(0x20df609F, 32);  // arrow right
      delay(40);
      break;

    case 'o':
    case 'O':
      // OK
      irsend.sendNEC(0x20df22DD, 32);  // OK
      delay(40);
      break;

    case 'u':
    case 'U':

      irsend.sendNEC(0x20df827D, 32);  // arrow down
      delay(40);
      break;

    case 'b':
    case 'B':
      // back
      irsend.sendNEC(0x20df14EB, 32);  // go back
      delay(40);
      break;


    default:
      Serial.println(inKey);
      break;

    } // break

  } // if

}