Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Sony SIRC Code Problem...

Status
Not open for further replies.

metal

Full Member level 6
Joined
Dec 21, 2004
Messages
364
Helped
19
Reputation
38
Reaction score
6
Trophy points
1,298
Activity points
3,834
use delay sirc

Hello all,

I have been watching the RC5 C codes, and they are nice. Any way, I am mainly inetredted in Sony SIRC remote controls, because I already have a spare unit.

The story began when I found a working code in PIC Basic Pro, It uses PULSIN command to measure the IR pulses.

I have already written the C codes for Sony SIRC, but it never works, never... I thought there might be someone who can help in finding out whats really going on.

I have uploaded both the PIC Basic Pro codes, and PICC code that I wrote today.
 

use delay sirc sony

The method has been mentioned in
So post a working one here. Actually, they are similar, just a bit of change for this SIRC.
Same hardware platform: PIC12F629 @ int. 4MHz RC OSC, GPIO2=IR, GPIO0=TX
No any true interrupt be used, all of them by polling.
SIRC.h
Code:
#include <12F629.h>

#FUSES NOWDT                 	//No Watch Dog Timer
#FUSES INTRC_IO              	//Internal RC Osc, no CLKOUT
#FUSES NOCPD                 	//No EE protection
#FUSES NOPROTECT             	//Code not protected from reading
#FUSES NOMCLR                	//Master Clear pin used for I/O
#FUSES PUT                   	//Power Up Timer
#FUSES NOBROWNOUT            	//No brownout reset

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A0,rcv=PIN_A1,bits=8)
SIRC.c
Code:
#include "SIRC.h"

typedef unsigned int8 U8;
typedef unsigned int16 U16;
typedef          int1 BIT;
#define VOID void

#pragma use fast_io (A)

#pragma byte GPIO = 0x05
#pragma byte TMR0 = 0x01
#pragma byte INTCON = 0x0B
#pragma byte PIR1 = 0x0C
#pragma bit TMR1F = PIR1.0
#pragma byte IOC = 0x96

#pragma bit IR_IOC = IOC.2
#pragma bit IR_PIN = GPIO.2
#pragma bit IR_INT = INTCON.0
#define IR_TIME TMR0

#define enable_INT_IR() IR_IOC = 1
#define clr_INT_IR() IR_PIN = 1; IR_INT = 0
#define is_INT_IR() (IR_INT != 0)

#define is_SIGNAL_IR() (IR_PIN==0)
#define is_IDLE_IR() (IR_PIN==1)
#define set_TIME_IR(tm) IR_TIME=tm
#define get_TIME_IR() IR_TIME
#define nIRtimeBase 32 // 32uS
#define nIRtolerance 30 // +/- 30%
#define defIRlead1time 2400 // 2400uS Sony SIRC leading physical 1 (mark/signal) bit time
#define defIRlead0time 600 // 600uS Sony SIRC leading physical 0 (space/idle) bit time
#define defIRdata1time 600 // 600uS Sony SIRC data physical 1 (mark/signal) bit time as 1T for logic bit
#define defIRdata0time 600 // 600uS Sony SIRC data physical 0 (space/idle) bit time
#define minIRtime(tm) ((((((100-nIRtolerance)*(tm))*10)/(nIRtimeBase*100))+5)/10)
#define maxIRtime(tm) ((((((100+nIRtolerance)*(tm))*10)/(nIRtimeBase*100))+5)/10)

   U8 gIRstat; // IR state number
enum { stIR_NONE=0, stIR_IDLE, stIR_SIGNAL };
   U16 gIRdata; // IR data b[11...7]=address, b[6..0]=command
#define nIRdataLength 12 // 12 bits data
#define add_Data_0_IR()  gIRdata >>= 1
#define add_Data_1_IR()  gIRdata >>= 1; gIRdata |= (1<<(nIRdataLength-1))
   U8 gIRcount; // IR bit counter
#define    nIRcount   (1*2+nIRdataLength*2-1) // 1 leading + 12 logic bits = 26 physical bits
//-U8 gIRruntime; // IR running time (counting only if gIRstat != stIR_NONE)
#define    nIRruntime 30000 // 25mS: 3.0+12*1.8=24.6mS
//#define timeout_RUNTIME_IR() (get_timer1() > nIRruntime)
#define timeout_RUNTIME_IR() (TMR1F != 0)
#define set_RUNTIME_IR(tm) set_timer1(65536UL-(tm)); TMR1F = 0
   BIT bIRgoLeadingBit; // 0:data bit, 1:leading bit
   BIT bIRnewHit; // 1:new IR code is received

VOID InitIR( VOID ) // initial IR engine
{
  gIRstat = stIR_NONE;
  bIRnewHit = FALSE;
  // hardware dependent: set correct snapped interrupt edge setting
  enable_INT_IR();
  clr_INT_IR();
}

VOID TimeoutIR( VOID ) // check IR running timeout
{
   if( gIRstat != stIR_NONE) {
      if( timeout_RUNTIME_IR() ) { // timeout
         InitIR();
      }
   }
}

VOID PollIR( VOID ) // put it in ISR (trigger when IR_PIN edge is changed)
{
   U8 mIRtime;

   mIRtime = get_TIME_IR(); set_TIME_IR(0);
   switch( gIRstat ) { 
      case stIR_NONE: 
           if( is_SIGNAL_IR() ) { // leading bit 
              // IR engine is starting
              gIRstat++; //  gIRstat =  stIR_IDLE; 
//----------- gIRruntime = 0; // IR running time is counting
              set_RUNTIME_IR(nIRruntime); // IR running time is counting
              gIRdata = 0; // it is not necessary if mask unused bits before using it
              gIRcount = 0; // starting
              bIRgoLeadingBit = 1; // ready to process leading bit 
              return; 
           } 
           return; 
      case stIR_IDLE: // now is IR.IDLE signal (process last SIGNAL)
           if( bIRgoLeadingBit ) { // now is leading bit
              if( mIRtime > 1*maxIRtime(defIRlead1time) ) { // time > max. leading.1
                 goto _error_IDLE_PollIR; // last signal too long 
              }
              if( mIRtime < 1*minIRtime(defIRlead1time) ) { // time < min. leading.1 
                 goto _error_IDLE_PollIR; // last signal too short 
              } 
           } else { // now is data bit
              if( mIRtime > 2*maxIRtime(defIRdata1time) ) { // time > max. logic.1.data.1 ie: max(logic1data1time,logic0data1time)
                 goto _error_IDLE_PollIR; // last signal too long
              }
              if( mIRtime < 1*minIRtime(defIRdata1time) ) { // time < min. logic.0.data.1 ie: min(logic1data1time,logic0data1time)
                 goto _error_IDLE_PollIR; // last signal too short 
              } 
              if( mIRtime < 2*minIRtime(defIRdata1time) ) { // time < min logic.1.data.1 as logic 0
//----------- if( mIRtime < 1*maxIRtime(defIRdata1time) ) { // time < max logic.0.data.1 as logic 0
                 add_Data_0_IR(); // add logic 0 
              } else {
                 add_Data_1_IR(); // add logic 1
              }
           }
           break;    
      case stIR_SIGNAL: // now is IR.SIGNAL signal (process last IDLE)
           if( bIRgoLeadingBit ) { // now is leading bit
              if( mIRtime > 1*maxIRtime(defIRlead0time) ) { // time > max. leading.0
                 goto _error_IDLE_PollIR; // last signal too long 
              }
              if( mIRtime < 1*minIRtime(defIRlead0time) ) { // time < min. leading.0
                 goto _error_IDLE_PollIR; // last signal too short 
              } 
              bIRgoLeadingBit = 0; // ready to process data bit 
           } else { // now is data bit
              if( mIRtime > 1*maxIRtime(defIRdata0time) ) { // time > max. logic.x.data.0
                 goto _error_IDLE_PollIR; // last signal too long
              }
              if( mIRtime < 1*minIRtime(defIRdata0time) ) { // time < min. logic.x.data.0
                 goto _error_IDLE_PollIR; // last signal too short 
              } 
           }        
           break;    
   } 

   // ready to process next physical bit 
   if( ++gIRcount < nIRcount ) { // the 1~24th physical bit 
      // the 1~24th physical bit 
      gIRstat = gIRstat == stIR_IDLE ? stIR_SIGNAL : stIR_IDLE; // swap state
      // hardware dependent: toggle snapped interrupt edge setting
//----clr_INT_IR();
      return; 
   }
//_complete_check_PollIR: // 25th phyiscal bit (26th one will be hidden)
   InitIR(); 
   // ex: translate Address/Command Bits.... 
   bIRnewHit = TRUE; 
   return; 
_error_IDLE_PollIR:
_error_SIGNAL_PollIR: 
   InitIR(); 
   return; 
} 

void main()
{
   port_a_pullups(0xFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);

   // TODO: USER CODE!!
   printf( "IR\n" );
   InitIR();
   while(TRUE) {
      if( is_INT_IR() ) {
         clr_INT_IR();
         PollIR();
         if( bIRnewHit == TRUE ) { // new IR code is coming
            bIRnewHit = FALSE;
            // process IR event here
            printf( "%4lX\n", gIRdata );
         }
      }
      TimeoutIR();
   }
}
Here is the whole project file which you can build it with CCS v4.012.
Just build or burn & play.
 

Hello Yager,

Thanks alot for your reply. I have solved my problem indeed, spent the whole last night and it worked.

I have also solved the timeout problem, instability, and other issues.

I used RB0 interrupt, because its much better in my case.

Here I will upload the working code, also in the main.c I mentioned what remote control I am using.

Thanks for trying to help yager. I will experiment with your code tonight to see the differences, and whether I can make use of your code to optimize mine more and more. I also want you to try my code as well, and see what can be done further. As a matter of fact, my code is very simple and yeilds the same results.

I have only Shown the resulting command on PORTA in order to test the stability of the receiver code, as a matter of fact, I noticed that when I heavily swing the remote control, the receiver does confuse and when I stop swinging heavily it gives me the right command, but when I am steady, or swinging the remote slightly, there are no confusions, I have also noticed this problem with all codes around for SIRC, and RC5. I don't know how to solve this problem, but I think we must receive the same command 5 times at least before showing it on PORTA. Any suggestions are welcome.


Kind day
 

Hello guys,

Im using a Sony Remote control (RM-836) and i want to see in a LCD the buttons i push so that i get in the result and place it on a array the rest of the project is done.

I tryed Yager´s SIRC code but im having troubles adapting it to my PIC 18f2550 can u guys give me a hand?

Cheers from Portugal
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top