Controlling Sony Receiver with IR...not working

I have recently started working with Arduino and have MANY projects I want to attempt. My first one is consolidating my remote controls in my living room.

I’ve had success at controlling my Samsung TV, but my Sony Receiver is not responding. I’ve changed between 12 and and 20 bits. I’ve also try sending the command 3 times. No response.

Any help would be much appreciated! Here’s the code:

#include <IRremote.h>

// Define switch pin
const int switchPin7 = 7;
const int switchPin6 = 6;
const int switchPin5 = 5;
const int switchPin4 = 4;

// Define a variable for the button state
int buttonStatePOW = 0; //Power Button for TV
int buttonStateSWIN = 0; // Switch Input on TV
int buttonStateENTER = 0; // Enter Button on TV
int buttonStateREPOW = 0; // Reciever Power Button

// Create IR Send Object
IRsend irsend;

void setup()
{
// Set Switch pin as Input
pinMode(switchPin7, INPUT);
pinMode(switchPin6, INPUT);
pinMode(switchPin5, INPUT);
pinMode(switchPin4, INPUT);
}

void loop() {

// Set button state depending upon switch position
buttonStatePOW = digitalRead(switchPin7);
buttonStateSWIN = digitalRead(switchPin6);
buttonStateENTER = digitalRead(switchPin5);
buttonStateREPOW = digitalRead(switchPin4);

// If button is pressed send power code command
if (buttonStatePOW == HIGH) {
irsend.sendSAMSUNG(0xE0E040BF, 32); // TV power code

}

if (buttonStateSWIN == HIGH) {
irsend.sendSAMSUNG(0xE0E0807F, 32); // Switch Input on TV

}

if (buttonStateENTER == HIGH) {
irsend.sendSAMSUNG(0xE0E016E9, 32); // Enter Button on TV
}

if (buttonStateREPOW == HIGH) {
irsend.sendSony(0x540C, 12); // Receiver Power Button`

}

// Add a small delay before repeating
delay(200);

}

when putting code use the code tags enter your code this puts your code in a code box makes it easier to read I assume your switches are taking the pins high you could put in a Serial.print(buttonStateREPOW); in your function and same for other functions to check that the switch is being read correctly but how did you know how many bits each remote code is and what the code is? I read mine with a nano conected to an ir receiver using the ArduinoIRremote example irrecvdump. You can get an IR receiver out of any old ir equipment, they have 3 pins signal vcc and gnd usualy 3.3-5v tollerance, but its best to look up the type you have, as there are different pin configs. Also you could see if there is anything being sent by using a digital cam or phone to look at you transmitter, they will pick up the flicker of ir if anything is being sent. That would be my first step acctually.

What is the make and model of your sony receiver? also the codes are often shorter than the number of bits that are actually required so it could be 32 bits like your samsung but if you are getting a flicker on a camera looking at ir led whilst button is pressed then it must be the code or number of bits you are sending thats why an ir sensor connected to any arduino with irrcvdump on serial would be a great help providing you have a remote that works. Else I suggest trying all the various sony codes till you get one that works or use a universal remote that goes through the codes till it turn off your set then detect that code and use it.

if the ir led only flickers when using other switches you pin4 may have a problem or even your switch just change to one of the samsung switches in the code to test it. ie

  // Set button state depending upon switch position
  buttonStatePOW = digitalRead(switchPin7);
   buttonStateSWIN = digitalRead(switchPin6);
    buttonStateREPOW = digitalRead(switchPin5);
     // buttonStateREPOW = digitalRead(switchPin4);

and try button 5

Thank you Tronicycle. By the way Tron Legacy is one of my favorite movies. :slight_smile:

Any way I used DroneBot's tutorial to build an IR receiver using a IR module and Arduino Mega to figure out what codes I needed. And tore that apart to build an IR blaster which I am working on now.

And yes I used my phone to see if the IR LED was actually working and it flickered just like the other buttons that control my TV. The funny thing is I do have a working remote for my receiver and used the IR receiver to detect what the code is. But that code doesn't seem to work. Like you I thought it was the bits but I tried 12, 15, or 20 and none of them work.

According to this website those are the only 3.

https://www.sbprojects.net/knowledge/ir/sirc.php

My receiver is a Sony STR-K9900P and the remote is a RM-AAP001. when I google it I find the codes are in different format compared to what I am using.

Maybe I should try irrecvdump to see more information.

Yes I am fairly convinced its the code format with the extra info you gave. Most ir remotes run on 38khz If my memory serves correct but there are variations. I will try find time to research how the frequency is set to 40khz. the irrcvdump tells you the number of bits which will sort that bit out. I was wondering if there was even a pause between the two sets of bits but it appears not so hopefully it will be a straight 12 or 15 bits.
You could try adding the 10ms pause or even make it 12ms so you are not firing bursts too close together for receiver to understand. Quote from your link "After counting 12 or 15 bits the receiver must wait at least 10ms to make sure that no more pulses follow." a delay() in the function would be ok for this test and if it works you could convert to millis(), if you have other code that needs the time.
So

 }

 
  if (buttonStateREPOW == HIGH) {
    irsend.sendSony(0x540C, 12); // Receiver Power Button`
    delay(12);//give receiver a chance to accept that code 

 
 }

Although there is probably a break built in with the IR library anyway. I would be interested to know the result you get with the irrcvdump as it trys to identify the protocol ie nec samsung etc aswell as giving the number of bits, and the raw data which can help in understanding the format.
I came up with tronicycle because i like recycling old electronics and reusing parts that I can't afford to buy. I Might have to check that movie see what its about. I watch very little TV my family does plenty of that for me.

I was looking at the github for the arduino version of ir remote because i switched to the esp8266 version as that allows for Alexa control and web control through phone or pc here is the link github irremote If you scroll down to ir_Sony.cpp you can see it says Fix coding error in send loops (specify bit size of literal) that may be the problem if you are using an older library

I just realized the dronebot workshop is the guy who's videos I have seen many of. Very educational its a shame he has a lisp because his writing and punctuation is way better than mine, the post he has up on the page you referenced is over a year old so not sure if that library you have is after the issue or not! I am sure you have enough info and knowledge to sort this. It has got to be what you are sending or what the library is sending where the problem lies if you are seeing the flicker the rest of the code works fine.

Andy

That library is Version - 2.2.3 what version are you using?

Andy

This is the ir_Sony.cpp with fix

#include "IRremote.h"
#include "IRremoteInt.h"

//==============================================================================
//                           SSSS   OOO   N   N  Y   Y
//                          S      O   O  NN  N   Y Y
//                           SSS   O   O  N N N    Y
//                              S  O   O  N  NN    Y
//                          SSSS    OOO   N   N    Y
//==============================================================================

#define SONY_BITS                   12
#define SONY_HDR_MARK             2400
#define SONY_HDR_SPACE             600
#define SONY_ONE_MARK             1200
#define SONY_ZERO_MARK             600
#define SONY_RPT_LENGTH          45000
#define SONY_DOUBLE_SPACE_USECS    500  // usually ssee 713 - not using ticks as get number wrapround

//+=============================================================================
#if SEND_SONY
void  IRsend::sendSony (unsigned long data,  int nbits)
{
 // Set IR carrier frequency
 enableIROut(40);

 // Header
 mark(SONY_HDR_MARK);
 space(SONY_HDR_SPACE);

 // Data
 for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
 if (data & mask) {
 mark(SONY_ONE_MARK);
 space(SONY_HDR_SPACE);
 } else {
 mark(SONY_ZERO_MARK);
 space(SONY_HDR_SPACE);
     }
   }

 // We will have ended with LED off
}
#endif

//+=============================================================================
#if DECODE_SONY
bool  IRrecv::decodeSony (decode_results *results)
{
 long  data   = 0;
 int   offset = 0;  // Dont skip first space, check its size

 if (irparams.rawlen < (2 * SONY_BITS) + 2)  return false ;

 // Some Sony's deliver repeats fast after first
 // unfortunately can't spot difference from of repeat from two fast clicks
 if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) {
 // Serial.print("IR Gap found: ");
 results->bits = 0;
 results->value = REPEAT;

# ifdef DECODE_SANYO
 results->decode_type = SANYO;
# else
 results->decode_type = UNKNOWN;
# endif

    return true;
 }
 offset++;

 // Initial mark
 if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK))  return false ;

 while (offset + 1 < irparams.rawlen) {
 if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE))  break ;

 if      (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK))   data = (data << 1) | 1 ;
 else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK))  data = (data << 1) | 0 ;
 else                                                           return false ;
 offset++;
 }

 // Success
 results->bits = (offset - 1) / 2;
 if (results->bits < 12) {
 results->bits = 0;
 return false;
 }
 results->value       = data;
 results->decode_type = SONY;
 return true;
}
#endif

how does it compare with yours you could try replacing just the cpp file.

SOLVED!!! :slight_smile: :slight_smile: :slight_smile: !

The timing and bits were wrong.
With the help of my friend Jon and his newly purchased Arduino we figured out the code was not sending correctly. Using DroneBot's IR receiver Demonstration we saw 12 bits only sent out part of the code and 20 bits sent the code but did nothing on the receiver.

So using this website:
https://www.sbprojects.net/knowledge/ir/sirc.php
We learned that Sony also has a 15 bit protocol and the 3 burst need a 10 millisecond delay between them. Success!

Here's the working code:

    if (buttonStateREPOW == HIGH) {

    irsend.sendSony(0x540C, 15); // Receiver Power Button`
    delay(10);
    irsend.sendSony(0x540C, 15); // Receiver Power Button`
    delay(10);
    irsend.sendSony(0x540C, 15); // Receiver Power Button`
    delay(10);
   
  
  }

So now I can turn on my Samsung TV and Sony Reciver at the same time with one button. I also can control the Roku with a fourth button.

My goal is to have one controller that controls my TV, Reciever, and Roku with only the buttons I need.

But this is what I have so far. Here’s my code:

/*
  IR Transmitter Demonstration 1
  IR-Xmit-Demo1.ino
  Control TV using IR Library
  IR LED must use Pin #3
  DroneBot Workshop 2017
  http://dronebotworkshop.com
*/

/*  Kenny "Kdawg"
    1/4/2020
    Using code for a KY-005 IR Emitter
    Works on Samsung
    UNO = PIN 3 and MEGA = PIN 9 for signal wire to IR Emitter
*/

    
// Include IR Remote Library by Ken Shirriff

#include <IRremote.h>

// Define switch pin
const int switchPin7 = 7;
const int switchPin6 = 6;
const int switchPin5 = 5;
const int switchPin4 = 4;


// Define a variable for the button state
int buttonStatePOW   = 0;  //Power Button for TV 
int buttonStateSWIN  = 0;  // Switch Input on TV
int buttonStateENTER = 0;  // Enter Button on TV
int buttonStateREPOW = 0;  // Reciever Power Button


// Create IR Send Object
IRsend irsend;

void setup()
{
  // Set Switch pin as Input
  pinMode(switchPin7, INPUT);
  pinMode(switchPin6, INPUT);
  pinMode(switchPin5, INPUT);
  pinMode(switchPin4, INPUT);
}

void loop() {
  
  // Set button state depending upon switch position
  buttonStatePOW = digitalRead(switchPin7);
   buttonStateSWIN = digitalRead(switchPin6);
    buttonStateENTER = digitalRead(switchPin5);
      buttonStateREPOW = digitalRead(switchPin4);
  
  // If button is pressed send power code command
   if (buttonStatePOW == HIGH) {
   irsend.sendNEC(0x5743C03F, 32); // Roku

   }

 
  if (buttonStateSWIN == HIGH) {
    irsend.sendSAMSUNG(0xE0E0807F, 32); // Switch Input on TV

 }

    
 
  if (buttonStateENTER == HIGH) {
    irsend.sendSAMSUNG(0xE0E016E9, 32); // Enter Button on TV
 }

  
  if (buttonStateREPOW == HIGH) {

    irsend.sendSAMSUNG(0xE0E040BF, 32); // TV power code 
    delay(10); //Just to seperate devices
    irsend.sendSony(0x540C, 15); // Receiver Power Button`
    delay(10);
    irsend.sendSony(0x540C, 15); // Receiver Power Button`
    delay(10);
    irsend.sendSony(0x540C, 15); // Receiver Power Button`
    delay(10);
   
  
  }
    
      
    // Add a small delay before repeating
    delay(200);
   
     }

Great stuff thats the 10 millis delay I was reffering to in post#5 second paragraph, but my suggestion was not the whole of it seemingly. Glad you solved it. I knew you was close. Thanks for posting your working code It may help others who are struggling with sony’s unusual protocol, and frequency.