CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Decoding Sony RM-D420 using a TSOP1738

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ymoona



Joined: 20 Mar 2005
Posts: 32
Location: Heiloo, the Netherlands

View user's profile Send private message Visit poster's website

Decoding Sony RM-D420 using a TSOP1738
PostPosted: Fri Jul 29, 2005 2:01 am     Reply with quote

hai

I would like to use my cd player remote to control my PIC18F252 controller.
ik cant use port B for my LCD uses it.
I'm now using pin_A0 but doesnt maken any sense to me.
the problem is that this remote doesnt use RC5.

does anyone has a sample code so I can decode my remote signals

thanx in advance
_________________
checkout my site: www.ymoona.com/wiki
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Fri Jul 29, 2005 4:23 am     Reply with quote

I experimented with several remotes I had around the house
I used a radio shack part to demodulate the infra red carrier.

Issues to watch for:
1)There is more than one carrier freq 38khz 40khz etc.
2)Each remote can and often does have its own way of encoding the signal.
3) Some have ways of detecting a button held down all try to reject a false signal from flourescent lights by repeating or complementing the key press code.
4) some remotes use space coding others pulse coding

Life would have been simpler and everyone wouldn't have a dozen different remotes had there been some industry agreement or government specification but it was urban sprawl and anything that works goes.

A scope is very helpful to probe into the specific formats

This code might help you tease out the specifics of the remote you have.

Code:
//// working with toshiba and magnavox  and leadtek 6/19/04
///  format is byte0 is address and byte1 its complement
//    byte 2  is the key scan code byte3 its complement

#include <18F452.h>
#fuses HS,noWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#device *=16 CCSICD=TRUE

#use delay(clock=20000000)
#use rs232 (debugger)

#define IR input(PIN_A0)
#define LED PIN_D0         //// flash led on valid code received
/////////////////////////////////////////////////////////////////////////////
////                        notes         ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//// a long 9ms pulse is sent for AGC followed by a 4 ms space
///  the bits are code as follows
//// space coded  .... zero and one is encoded by the length of the space
///                    pulse=600us and fixed  space varies  0= 600us 1=1500us
//// pulse coded  .... zero and one is encoded by the length of the pulse
///  shift coded  .... zero =short pulse long space  one =long pulse short space
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////
///// constants to filter glitches as from flourescent lights
//////////////////////////////////////////////////////////////////////////////


///// toshiba  agc_time 30000   bit_time 1000  space coded
///// leadtek  agc_time 30000   bit_time 1000  space coded


//#define AGC_time 1000    /// 30k*.2=6 ms  AGC is typically 9ms

#define MAX_DURATION 5    //// 10ms
#define TOSHIBA 1
#define MAGNAVOX 1
#define LEADTEK 1
/////        globals //////////////////////
int16 AGC_pulse ;   /// 30k*.2=6 ms  AGC is typically 9ms
int16  AGC_space ;
int16 BIT_time  ;
int8 timed_out,duration,index,str_index,space_terminated,maker;
int16 pulse_width,space_width,pulse_adj;
char model[21]; //// FTER IDENTIFICATION WILL HOLD MODEL NAME EX TOSHIBA-TV
struct {
        int8 byte0;
        int8 byte1;
        int8 byte2;
        int8 byte3;
        int8 byte4;
        int8 byte5;
       } code;
char binstr[49]; // 48 char buffer of 0 or 1 bits as ascii


/////////////////////////////////////////
/////////   isr /////////////////////////
/////////////////////////////////////////
#int_RTCC
isr_timer0()
{
/// the timer overflows every 256 counts
/// a count occurs every 4 * 4 =16 cycles at  20MHZ or 8us
/// so we get here every 256*8 =2048 us approx
/// longest pulse or space is approx 10ms ...max duration of 5
duration++;
if (duration>=MAX_DURATION)
  {
    duration=0;
    timed_out=true;
  }

}

///////////////////////////////////////
int16 pulse()
{
  int16 time;
/// measure time the carrier is high
/// carrier high means the demodulator is low
/// a glitch can not interrupt a carrier

/// set up the interrupt timeout clock timer0
/// if timeout is exceeded interrupt sets timed_out to true
   timed_out=false;
   duration=0;
   set_timer0(0);
loop:
  time=0;

  while((IR==1)&& (timed_out==false)); //wait for low

  if (timed_out==true) return(0xFFFF); /// timed out

  set_timer1(0); /// start timing


  while(IR==0); /// hold till low ends ...low will always end since the carrier pulse is always a burst
  time=get_timer1();
  //// ignore a short carrier pulse as a glitch
  if (time<BIT_time) goto loop; //// 200 us = .2ms  or shorter are ignored
  return (time);
}

////////////////////////////////////////////////
int16 space()
{
  int16 time;
/// measure time the carrier is absent
/// carrier absent means the demodulator is high
/// the space is vunerable to a noise glitch



  while(IR==0); //wait for high it will always go high since carrier is aburst
  /// set up the interrupt timeout clock timer0
  /// if timeout is exceeded interrupt sets timed_out to true
  timed_out=false;
  duration=0;
  set_timer0(0);
  time=0;
  set_timer1(0); /// start timing

 loop:
  while((IR==1) && (timed_out==false)); /// hold till high ends
  if(timed_out==true) return(0xFFFF);
  time+=get_timer1();
/// there could be a short duration noise glitch or a truly valid pulse beginning
/// so we encroach a short time on a valid pulse when testing to see if it was a glitch
 set_timer1(0); /// start timing possible glitch .. a very short duration low ( carrier burst)
  while((IR==0) && (get_timer1()<BIT_time)); // start of a new pulse but it could be just a glitch
  // we got to this point if IR went high or we glitched low
   if (IR==1) goto loop; /// ignore glitch of 1000*.2us or less and continue to time till high ends
   /// this is the true end to the space since we have gone low for at least BIT_time
   pulse_adj=get_timer1(); /// we encroached a wee bit into a valid pulse so we adjust
 return(time);
}

/////////////////////////////////////////////////////////////
translate(int8 mode, int16 pulse, int16 space)
{
///// *code points to the code structure of 48 bits s points to the binstr
///// rotate the bit into the 48 bit structure
/////// code is the 48 bit global structure
/////// binstr is a 49 char string to hold the binary digits
/////// index is where  we are in the translation
if ((mode==1) || (mode==2) )
         {
         //toshiba VC459 T space encoded or magnavox universal
         // each byte of the 32 bit code is sent LSB first
         // 8 bit address ex 0x44 and its complement 0xbb
         // followed by key press code byte  0x01 for key '1' and lastly the inverse of the key byte  0xFe
         if (space>2*pulse) {
                              shift_right(&code,6,1); /// goes in lsb first
                              binstr[str_index--]='1';
                             }
         else                {
                             shift_right(&code,6,0);
                             binstr[str_index--]='0';
                             }

         }
if(mode==3)
          {
          // pulse encoded
          if (pulse>2*space) {
                              shift_right(&code,6,1); /// goes in lsb first
                              binstr[str_index--]='1';
                             }
         else                {
                             shift_right(&code,6,0);
                             binstr[str_index--]='0';
                             }
         ;
          }
}

////////////////////////////////////////////////////////////
int8 validate(int8 mode)
{
if ((mode==1) || (mode==2))
            {
            // toshiba or magnavox byte3 is complement of byte 2 and byte 1 complement of byte 0
            if (code.byte3 != (~code.byte2)) return false;
            if (code.byte1 != (~code.byte0)) return false;
            }



return(true);
}

///////////////////////////////////////////////////
init_IR_control( int8 mode)
{
 if ( mode==1) {
                //// typical 9ms agc pulse 4ms AGC space
                ///  600us pulse eithet 600us space or 1500 us space
                AGC_pulse=30000 ;   /// 30k*.2=6 ms  AGC is typically 9ms
                AGC_space=12000 ;
                BIT_time=100;
                space_terminated=true;
                return;
               }
 if (mode==2)
                {
                /// leadtek
                AGC_PULSE=30000;
                AGC_space=12000;
                BIT_time=100;
                space_terminated=false;
                return;
                }
 return;
}







main() {
int8 i,j,success;

   int16 pulse_table[49],space_table[49];

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);    /// start timer over flows 4*4*256 cycles =800us
   setup_timer_1(T1_INTERNAL|T1_div_by_1);    // Start timer 1 tick every 4 cycles or .2us at 20mhz


/// all tv remotes send out pulses of the carrier 38kz of various durations
/// pulses are separated by spaces (no carrier) of varying duration
/// the code will measure the pulse and space intervals in a train of pulses
/// the ir is demodulated so as to have a logic high when no carrier is detected
/// a timeout is used to  end a pulse train
maker=TOSHIBA;
printf("\n\r start maker=%d",maker);
 enable_interrupts(INT_timer0);
 enable_interrupts(global);

///// initialize AGC pulse and space
//init_IR_control(TOSHIBA);
init_IR_control(maker);


start:
  for(j=str_index;j>0;j--)binstr[j]='X';
  for(j=0;j<50;j++){ pulse_table[j]=0;space_table[j]=0;}
  code.byte0=0;
  code.byte1=0;
  code.byte2=0;
  code.byte3=0;
  code.byte4=0;
  code.byte5=0;
  for(j=0;j<48;j++)binstr[j]='X';
  binstr[48]=0;

  ////////////// transmission is assumed to be lsb first
  str_index=47; /// string is filled lsb first so lasb goes to pos 48

  pulse_width=pulse(); /// get the beginning agc pulse

  if( (pulse_width<AGC_pulse) || (pulse_width==0xFFFF))  goto start; /// 30k*.2 =6 ms min for AGC

 re_start:



  pulse_table[0]=pulse_width; /// slot 0 is for the agc
  space_width=space();

  if ((space_width<AGC_space) || (space_width==0xFFFF)) goto start;  /// to short a AGC space

  space_table[0]=space_width; /// slot 0 is for the AGC
  index=1;
  next_bit:
  /// pick up the data payload usually 48 bits


  pulse_width=pulse_adj+pulse(); /// in testing for glitches we can encroach on a little into a valid pulse

  //// payload can be pulse terminated

  if(pulse_width>AGC_pulse)  goto exit;
  pulse_table[index]=pulse_width; // time of high part of bit
  space_width=space();
  if(space_width>AGC_space) goto exit;
  space_table[index]=space_width;

  translate(maker,pulse_width,space_width); //// space or pulse encoded translation


  if (index<49) {index++; goto next_bit ;}
exit:

  for (j=index;j<49;j++) shift_right(&code,6,0);//// need to fill in the remaining bits

  success=validate(maker);
  if (success==true) {
                     /// flash led
                     output_high(LED);
                     delay_ms(100);
                     output_low(LED);
                     delay_ms(100);
                    }
  binstr[48]=0; //// just in case 49 get overwritten
  for(j=index+1;j<49;j++){ pulse_table[j]=0xFFFF;space_table[j]=0xFFFF;}

 // for (j=0;j<index;j++) printf("\n\r %02u %05lu  %05lu ",j,pulse_table[j]/5,space_table[j]/5);


  printf("\n\r %2x:%2x:%2x:%2x:%2x:%2x",
            code.byte5,code.byte4,code.byte3,code.byte2,code.byte1,code.byte0);

  if (code.byte0==0x40 ) printf(" TOSHIBA_TV \n\r");
  else if (code.byte0==0x44 ) printf(" TOSHIBA_VCR \n\r");
  else if (code.byte0==0x04 ) printf(" MAGNAVOX_TV\n\r");
  else if (code.byte0==0x03 ) printf(" LEADTEK \n\r");
  else printf(" UNKNOWN \n\r");

  for(i=0;i<6;i++)
                  {
                   for(j=0;j<8;j++)printf("%c",binstr[i*8+j]);
                   printf(":");
                  }
  if (success==true ) printf(" OK bits %d",index-1);
  else printf(" ERR bits %d",index-1);

  goto start;
  while(1);
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group