Samsung Remote Protocol

Hi, I have been trying to control my samsung television using arduino.. so I wrote a program to decode the protocol according to the application note from samsung..

Application note: http://www.samsung.com/global/business/semiconductor/products/microcontrollers/downloads/S3F80KB_RemoteController_AN_REV000_090108.pdf

the decoding part was pretty easy.. i got the address and data bits from my remote.. then, i tried to program an IR transmitter.. reverse engineering... :wink: I guess the logic is correct because when i transmitted the power key data from one board(tx), i got the same data on another board(rx), as i got from my tv remote.. but when is used it on my tv it didnt work... :frowning: :frowning:

if there is someone who has worked with samsung remote protocols, help me out..

here go the codes of receiver and transmitter

Receiver:

/* 
This sketch reads info from a samsung remote..
and the address and data are extracted
*/

#define tsop_pin 15
#define led_pin 13

void setup()
{
  Serial.begin(9600);
  pinMode(tsop_pin,INPUT);
  pinMode(led_pin,OUTPUT);
}

void loop()
  {
  boolean bin[32];                    //boolean consumes less space
  int addr=0, data=0;
  
  while(pulseIn(tsop_pin,LOW)<4000);  //wait for start bit
  digitalWrite(led_pin,HIGH);                 //turn on an led
  for(int i=0; i<32; i++)
  {
    if(pulseIn(tsop_pin,HIGH)>1000)   //store binary values
      bin[i]=1;
    else
      bin[i]=0;
  }

  Serial.print("Bit Stream = ");
  for(int i=0;i<32;i++)            //print bit stream
  {
    Serial.print(bin[i],BIN);
  }
  Serial.println();
  
  Serial.print("Address = ");
  for(int i=0;i<8;i++)            //extract addr bits
  {
    Serial.print(bin[i],BIN);
    if(bin[i]==1)
      addr+=1<<i;
  }
  Serial.print("   ");
  Serial.println(addr);
  
  
  Serial.print("Data = ");
  for(int i=0;i<8;i++)            //extract data bits
  {
    Serial.print(bin[i+16],BIN);
    if(bin[i+16]==1)
      data+=1<<i;
  }
  Serial.print("   ");
  Serial.println(data);
  Serial.println();
  
  delay(50);                      //some time to breathe ;)
  digitalWrite(led_pin,LOW);      //turn off the led
}

Transmitter:

`#define ir_led 14
int address = 7;
int data = 2;        //2 = power button 

boolean bin[8],Data[32];

void setup()
{
  Serial.begin(9600);
  pinMode(ir_led,OUTPUT);
  pinMode(7,INPUT);        //a toggle switch
  digitalWrite(7,HIGH);
  
  dec_to_bin(address);      //convert the address into binary
  for(int i=0;i<8;i++)
  {
    Data[i]=bin[i];
    Data[i+8]=bin[i];
  }
}

void loop()
{
  if(digitalRead(7)==0)    //transmit data when a swtich is pressed
  {
    data=2;
    dec_to_bin(data);      //convert data into binary
    for(int i=0;i<8;i++)
    {
      Data[i+16]=bin[i];
      Data[i+24]=!bin[i];
    }

/*  for(int i=0;i<32;i++)
  {
    Serial.print(Data[i],BIN);
  }
  Serial.println();
*/
  
    transmit();          //transmit
    delay(54);
  }
}

void dec_to_bin(int dec)
{
  for(int i=0;i<8;i++)
  {
    bin[i]=dec%2;
    dec=dec/2;
  }
}

void transmit()                  //carrier = 37.9 KHz
{
  burst(173);                    // start bit = 4500/26=170
  digitalWrite(ir_led,LOW);
  delayMicroseconds(4500);       //start bit
  for(int i=0;i<32;i++)
  {
    if(Data[i]==1)
    {
      burst(22);
      digitalWrite(ir_led,LOW);
      delayMicroseconds(1690);      //high bit
    }
    else
    {
      burst(22);
      digitalWrite(ir_led,LOW);
      delayMicroseconds(560);      //low bit
    }
  }
  burst(22);
  digitalWrite(ir_led,LOW);        //stop bit
  delayMicroseconds(560);      
}

void burst(int pulses)
{
  for(int i=0;i<pulses; i++)
  {
    digitalWrite(ir_led,1);
    delayMicroseconds(9);
    digitalWrite(ir_led,0);
    delayMicroseconds(17);
  }
}

Do you have compared the timing, as that might be critical,
also the power can be an issue. How close to the tv have you tested the transmitter.

i think the timing is correct.. but i am not sure.. i took the values from the application note..

i tried it placing very close.. i don't think distance is a problem.

i think the timing is correct

try if you can compare it, the difference may be just a few% , also check for if both have same number of startbits ( I lost some hours on such one)

the difference may be just a few%

actually yeah, i modified the carrier frequency a bit.. instead of 8.8 uS, i programmed it as 9uS and instead of 17.4uS, i made it 17uS.. this changed the carrier frequency from the required 37.9 to 38.4 KHz. will this affect..??

how do i give delay of 8.8 uS..
the delayMicroseconds() takes only integer values.. :frowning:

is there any kind of delay around nanoseconds? :smiley:

how do i give delay of 8.8 uS..
the delayMicroseconds() takes only integer values..

And only has resolution of 4 usec steps.

Returns the number of microseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four).

is there any kind of delay around nanoseconds?

None avalible or really possible as basic single instruction timing is around 64 nsec.

Are you using a simple IR LED, and generating the carrier frequency with the Arduino?

If so, I'd try using one of the little modules which will take care of that for you... you'll send the "slow" "ons" and "offs", and the module will send out a stream of ons and offs of a beam pulsed at the much higher carrier frequency.

I have a page about RECEIVING data from IR controllers. Some of what's there....

... might be helpful to beginners reading this, but I suspect from what you've written above, you already know most of what's on that page... I only offer it if you are very frustrated!

@retrolefty

And only has resolution of 4 usec steps.

you made my day.. i never knew about this 4uSec step thing..
now, i calculated all the program flow timing into the protocol and it works.. Awesome.! :slight_smile: :slight_smile:

thanks a ton, mate.. :slight_smile:

@tkbyd:

that is a nice page.. it did help me a bit.. :slight_smile:
thanks to you too, mate..

this is awesome.. lol.. controlling tv with my laptop...
people wondering how channels are changing..! :stuck_out_tongue:
suspecting flaws in tv... :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley:

The tv b gone does something simular. I am not sure about samsung.

http://www.tvbgone.com/cfe_tvbg_faq.php?PHPSESSID=f089a1a127571e58bb26305577e38ad6

adafruit links for turning a tv off.

http://www.adafruit.com/products/75&zenid=39a5381ed5706171b010630c3b7bcb4c

look through her forum for a few minutes.

http://forums.adafruit.com/viewforum.php?f=23&sid=556b89b25d25735e22ad10e72672bd74

I got one a while back. I love it. Turning off the damn box while I eat is just so cool to me no matter where I am at.

you may be able to download their code and spot something or look over their design to assist in your own project.

There's some code pasted into the comments on the bottom of Ken Shirriff's page about his infrared remote library. Do a search fo sendsamsung on there. Ken has done 99.99% of the legwork on infrared remotes for us all.....