SIRC and RF Transmission

Status
Not open for further replies.

denny9167

Member level 1
Joined
Apr 23, 2022
Messages
35
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
170
I'm trying to implement SIRC protocol using OOK transmission, Has it been attempted before,or any drawbacks? Ive posted my TX/RX below. The decoder works great using a 40Khz carrier, but Im not sure what, if any changes are needed using ON/OFF keying. I welcome any input. BTW the transmitter has been built and tested with a logic analyzer. The receiver has only been built and not tested.

Code:
/* 
 * File:         TX_SIRC.c
 * Author:       Denny Brown
 * Description:  Handheld RF Transmitter
 * Device: PIC12F615
 */

#include <xc.h>
#include <stdint.h>


//Configuration Bit Settings



// CONFIG
#pragma config FOSC = INTOSCIO  
#pragma config WDTE = OFF       
#pragma config PWRTE = OFF      
#pragma config MCLRE = OFF      
#pragma config CP = OFF
#pragma config IOSCFS = 8MHZ    
#pragma config BOREN = ON      



#define _XTAL_FREQ 8000000			// required for delay routines. 


#define RF_OUT 	GPIObits.GPIO2		// RF Data IN is conntected to this port
	
#define KEY_1	GPIObits.GPIO0		//Switch pin definitions
#define KEY_2	GPIObits.GPIO1
#define LED     GPIObits.GPIO5

#define ADDRESS 1

#define DATA_KEY_1 2
#define DATA_KEY_2 3


// The function takes two arguments, these get assigned to command and address
void sendFrame(uint8_t command,uint8_t address)
{   // Move / mask the bits around, so that we have 7 bits of command, then 5 bits of address
    uint16_t u16Send=(((uint16_t)(address&0x1F))<<7)|(command&0x7F);
    uint8_t uBitLoop;

    //Start bit 2.4ms time
    RF_OUT=1;
    LED=1;
    __delay_us(2400);
    RF_OUT=0;
    LED=0;
    __delay_us(600);

    // Start with u16Test having bit 11 set, then walk down to bit 0, when u16Test reaches 0 we're all done
    for(uBitLoop=12 ; uBitLoop!=0 ; uBitLoop--,u16Send>>=1)
    {   // Turn PWM on
        RF_OUT=1;
        LED=1;
        __delay_us(600);
        // If (u16Test&u16Send)!=0 then the bit to send is a 1, so send a long on pulse, otherwise send a short one
        if (u16Send&0x01)
        {   // It's a 1 so extend to a long pulse
            __delay_us(1200-600);
        }
        // Either short or long pulse done, turn off pulse
        RF_OUT=0;
        LED=0;
        // Wait gap (same for a 1 or 0)
        __delay_us(600);
    }
    
}
void __interrupt() swInt(void)		
{	
   
	 if (INTCONbits.GPIF)					// check the interrupt on change flag
	{	
		__delay_ms(2);						//check for key de-bounce			
	
		if(!KEY_1)				//check if the Key_1 is pressed (GPIO is low)
		{
	sendFrame(DATA_KEY_1,ADDRESS);	//send the frame
	 		while(!KEY_1)		//if the key is still pressed 
			{
   sendFrame(DATA_KEY_1,ADDRESS);	//repeat the frame
          
			}
        INTCONbits.GPIF =0;	
	  if(!KEY_2)					//check if the Key_2 is pressed
		{
	sendFrame(DATA_KEY_2,ADDRESS);	//send the frame
			while(!KEY_2)		//if the key is still pressed 
			{
	sendFrame(DATA_KEY_2,ADDRESS);	//repeat the frame
			}
		
		INTCONbits.GPIF =0;					// clear the interrupt on change flag
	}
}
void main()
{
	CMCON0bits.CMON	=0;		// disable the comparator 
   ANSEL		= 0x00;		// all pin are Digital
   TRISIO		= 0x3; 	// Only GP2 is set to output rest are input
	OPTION_REG 	= 0x5F;		//pull-ups are enabled	                      //timer0 clock source is internal
							   //timer0 pre-scaler is 1:1 (disabled "assigned to WDT")
   WPU 	= 0x3;			//week pull-ups are enabled for all switches.
	GPIO 	= 0x3;			//put hight to the latch value of each GPIO
	IOC 	= 0x3; //interrupt on change 
   INTCONbits.GPIE = 1;	
	INTCONbits.GPIF = 0;	// clear the external interrupt flag	INTCONbits.PEIE = 1;    // peripheral interrupt enable
   INTCONbits.GIE 	= 1;    // GLOBAL interrupt enable
    
   
	
	for(;;)
	{
		SLEEP();
    }
}


Code:
/*
 * File:   RX_SIRC.c
 * Author: Denny Brown
 *
 * Created on June 1, 2022, 8:12 PM
 */

#include <xc.h>
#include <stdint.h>


// PIC12F615 Configuration Bit Settings


// CONFIG
#pragma config FOSC = INTOSCIO  
#pragma config WDTE = OFF       
#pragma config PWRTE = OFF      
#pragma config MCLRE = OFF       
#pragma config CP = OFF         
#pragma config IOSCFS = 8MHZ
#pragma config BOREN = ON     

#define _XTAL_FREQ 8000000

#define LED1     GPIObits.GPIO5		// RF receive status indicator 
#define LED2     GPIObits.GPIO4

#define RF_IN   GPIObits.GPIO3		// RF DATA PORT 

//=============================================================================
//   RECEIVE_RF_PACKET
//=============================================================================

unsigned int overflow=0;


void receive_rf_packet(void)
{
  //-------------------------------------------------------
  // This function receives an RF packet of bytes in the pulse period
  // encoded format. The packet must have 2 valid contiguous bytes
  // global variables; address_byte and command_byte hold the byte result.
 // Note: TMR0 runs at 500kHz frequency, That is why 200uS = 100 TMR0 pulse_time
  
  //-------------------------------------------------------
  
  unsigned int pulse_time;
  unsigned char bitcount;
  unsigned char command;
  unsigned char address;
  
  while(1){   // loop until it has received 2 contiguous RF bytes
  command=0;
  address=0;
     //-----------------------------------------
    // Get preamble - 2.4mS pulse,1.2mS space
    
      while(RF_IN);    // wait for input / edge
      overflow =0;
      TMR0 = 0;                    // and ready to record next period
      while(!RF_IN);     // wait for input \ edge
      pulse_time=(overflow >>8) +TMR0;
      if ((pulse_time > 0x80) && (pulse_time <0xB0)){  // grab the pulse time
      
           
    //-----------------------------------------
    // now we had a start pulse, record 7 command bits
    
    for(bitcount = 0 ; bitcount < 7; bitcount++){    // 8 address bits
    
      while(RF_IN);    // wait for input / edge
      overflow =0;
      TMR0 = 0;
      while(!RF_IN);     // wait for input \ edge
      pulse_time = (overflow >>8) + TMR0;           // grab the pulse time!
      command >>= 1;                              // shift
      command &= 0x7F;                            // top bit zero
      if (pulse_time> 0x40){
      command ^= 0x80;                        // top bit 1
                }
           }
      command >>=1;                   // shift 1 unused bit
      command &= 0x7F;                // clear top bit
    //-----------------------------------------
    // now record 5 address bits
    
    for(bitcount = 0 ; bitcount < 5; bitcount++){    // 8 command bits
    
      while(RF_IN);    // wait for input / edge
      overflow =0;
      TMR0 = 0;
      while(!RF_IN);     // wait for input \ edge
      pulse_time = (overflow >>8) + TMR0;           // grab the pulse time!
      address >>= 1;                              // shift
      address &= 0x7F;                            // top bit zero
      if (pulse_time> 0x40){
      address ^= 0x80;                        // top bit 1
                }
           }
      address >>= 3;                    // shift 3 unused bits
      address &= 0x1F;                  // clear top 3 bits
      

      if(address == 1){
      if(command == 2){
                LED1 = ~LED1;
              __delay_ms(100);
                       }
      if(command == 3){
          LED2=~LED2;
              __delay_ms(100);
      } 
    }
    }
  }
}
//-----------------------------------------------------------------------------
// Timer0 interrupt

void __interrupt() ISR(void){

    if (INTCONbits.T0IF) {
        overflow++;                    // increment overflow
        INTCONbits.T0IF = 0;                 // Clear Timer0 overflow interrupt flag
    }
}


/* THE main source code starts here*/
void main()
{
    CMCON0=0x7;				// disable the comparator 
    ANSEL =0x00;
    TRISIO3=1;   			// Only GP3 is set to input rest are out
    TRISIO5=0;
    OPTION_REG=0x81;        //pull-ups disabled, 1:4 pre-scaler = 500kHz
    INTCONbits.GIE = 1;               // Global interrupt enable
    INTCONbits.T0IE =1;               // Timer0 interrupt enable
    GPIO =0;
    
    receive_rf_packet();
}
 
Last edited:

Hello!

I'm trying to implement SIRC protocol using OOK transmission,

One good thing to start when you ask a question would be to decipher what you say.
I have implemented many remote control systems using a microcontroller, but I didn't know
until now what SIRC means, neither OOK. I checked for SIRC and found out that it lloks like
a plain remote control.

Has it been attempted before,or any drawbacks?

So to answer your first question, yes, it has been successfully attempted in my case and I
suppose by zillons of other engineers.
Now sorry for my non-native english, but I don't understand how the above sentence articulates.
What do you mean by "or any drawbacks"? Do you want to know if there are any drawbacks in
implementing what you say? Of course there are. In the real world, whatever you do, there are
drawbacks.

Now it would be good to specify what kind of hardware you are using, and possibly what you
want to do with it (not necessarily details about your application, but details like how many bytes
you want to send / receive.

And about your question, what exactly do you want to know? Does your code work and you want
to improve it? Or it doesn't work? In this case what exactly doesn't work? If somebody wants to
spend time debugging your code, he has to have some hints about the actual problem.

Dora
 

Ive just recently started working with RF modules , and there are many variaties. A lot of superregenerative types mostly, and for them the timing is critical for both the range and consistent AGC lock. Ive heard that Manchester coding would be best. So to be more specific, would SIRC timing allow the AGC to adjust its gain to decode it properly?
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…