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

Infrared receiver for SONY remotes
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

Infrared receiver for SONY remotes
PostPosted: Sun Mar 05, 2006 6:09 am     Reply with quote

I've seen some requests for infrared receivers on this forum, so here is my code. It works flawlessly with a remote from a SONY KV-21T3K television and cheap cloned remotes. The range is very good.

Code:
/******************************************************************/
/*                                                                */
/*      Infrared Receiver for SONY 12-bit protocol (SIRC)         */
/*                                                                */
/*  Compiler:     CCS PCH 3.242                                   */
/*  Processor:    PIC18F452 @ 32MHz                               */
/*  IR Sensor:    TSOP1738                                        */
/*  Circuit:      Standard from TSOP1738 Datasheet, OUT to RB0    */                                         
/*                Requires LCD on port D, LED+resistor on RC2     */
/*                LED blinks when a command is recognised.        */
/*  Author:       Aurelian Nichita     [email protected]    */
/*  Based on:     http://www.xs4all.nl/~sbp/knowledge/ir/sirc.htm */
/*                                                                */
/******************************************************************/

#define CLKSPEED 32000000
#include <18F452.h>
#fuses H4,NOPROTECT,NOOSCSEN,BROWNOUT,BORV45,NOWDT,WDT128,PUT,NOSTVREN,NODEBUG,NOLVP,WRT,NOCPB,WRTB,WRTC,NOCPD,NOWRTD,NOEBTR,NOEBTRB
#use delay(clock=CLKSPEED)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#ignore_warnings none

#zero_ram

/* TIMER0 configuration */
#define TIMER0_CONFIG   RTCC_INTERNAL | RTCC_DIV_1

/* Interrupt rate:                     */
/* 4/32000000*65536*1 = 8.192 ms       */
/*                                     */
/*     Start: 3.0 ms (ignored)         */
/*     "1":   1.8 ms (14400)           */
/*     "0":   1.2 ms  (9600)           */

#define ONE_MIN  13400
#define ONE_MAX  15400
#define ZERO_MIN 8600
#define ZERO_MAX 10600

#include "lcd.c"


/* irframes[0] (start) will be garbage, ignore it...  */
int16 irframes[13];
int8 ircount = 0;
int1 irdone = FALSE;


#int_ext
void ext_isr() {
  if (irdone) return;
  irframes[ircount++] = get_timer0();
  if (ircount >= 13)
    irdone = TRUE;
  set_timer0(0);
  enable_interrupts(INT_TIMER0);
}


#int_timer0
void timer0_isr() {
  disable_interrupts(INT_TIMER0);
}


#separate
int1 decode_ir(int8 &addr, int8 &cmd) {
  int8 i;
  int8 mask;
  int8 bits[13];

  addr = 0;
  cmd = 0;

  for (i=1; i<=12; i++) {
    if ((ONE_MIN <= irframes[i]) && (irframes[i] <= ONE_MAX))
      bits[i] = 0x01;
    else
      if ((ZERO_MIN <= irframes[i]) && (irframes[i] <= ZERO_MAX))
        bits[i] = 0x00;
      else        // Error
        return FALSE;
  }

  mask = 0x01;
  for (i=1; i<=7; i++) {
    if (bits[i])
      cmd = cmd | mask;
    mask <<= 1;
  }

  mask = 0x01;
  for (i=8; i<=12; i++) {
    if (bits[i])
      addr = addr | mask;
    mask <<= 1;
  }

  return TRUE;
}


void start_ir() {
  memset(irframes, 0x00, sizeof(irframes));
  ircount = 0;
  irdone = FALSE;
}


void main() {
  int8 addr, cmd;
  int1 ok;
 
  delay_ms(100);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  set_tris_a(0b11111111);
  set_tris_b(0b11111111);
  set_tris_c(0b11111011);  // PIN_C2 used for the LED
  set_tris_d(0b00000000);  // LCD
  set_tris_e(0b11111111);
  setup_spi(FALSE); 
  setup_wdt(WDT_OFF);

  lcd_init();
  output_bit(PIN_C2, 0);
  delay_ms(100);

  lcd_putc("\fWaiting...");

  setup_timer_0(TIMER0_CONFIG);
  setup_timer_1(T1_DISABLED);
  setup_timer_2(T2_DISABLED, 255, 1);
  setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
  ext_int_edge(0, L_TO_H);
  enable_interrupts(INT_EXT);
  enable_interrupts(GLOBAL);

  start_ir();
#ignore_warnings 203
  while(TRUE) {
#ignore_warnings NONE
    if (irdone) {
      ok = decode_ir(addr, cmd);
      printf(lcd_putc, "\fCmd  %3u\nAddr %3u", cmd, addr);
      if (!ok)
        lcd_putc("  ERROR");
      else
        output_bit(PIN_C2, 1);
      delay_ms(50);
      output_bit(PIN_C2, 0);
      start_ir();
    }
  }
}


Last edited by VanHauser on Wed Aug 24, 2016 4:24 am; edited 1 time in total
HOHOHAHA



Joined: 13 Apr 2007
Posts: 24

View user's profile Send private message AIM Address

PostPosted: Tue Jan 01, 2008 11:11 am     Reply with quote

great work ...
Lucidan



Joined: 05 Feb 2008
Posts: 7

View user's profile Send private message

Thanks!
PostPosted: Fri Feb 08, 2008 12:00 pm     Reply with quote

Thanks! I've been looking for something like this for a while....I'll let you know whether it works with my Sony remotes (VCR, CD players, Amplifier, minidisc). Or is it supposed to work with ANY Sony remote?
HTAluvBeBeo



Joined: 23 Feb 2008
Posts: 35

View user's profile Send private message

PostPosted: Thu Jul 03, 2008 9:22 pm     Reply with quote

I converted this code for 16F877A and send data to rs232
but there is something wrong.
Plz help me to check the code, sory if it was too long.
Code:

#include <16F877A.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


/* TIMER0 configuration */
#define TIMER1_CONFIG   T1_INTERNAL | T1_DIV_BY_1

/* Interrupt rate:                     */
/* 4/20000000*65536*1 = 13.1 ms       */
/*                                     */
/*     Start: 3.0 ms (ignored)         */
/*     "1":   1.8 ms (9000)           */
/*     "0":   1.2 ms  (6000)           */

#define ONE_MIN  8000
#define ONE_MAX  10000
#define ZERO_MIN 5000
#define ZERO_MAX 7000

//#include "lcd.c"


/* irframes[0] (start) will be garbage, ignore it...  */
int16 irframes[13];
int8 ircount = 0;
int1 irdone = FALSE;



#int_ext
void ext_isr() {output_bit(PIN_A5, 0);
  if (irdone) return;
  irframes[ircount++] = get_timer0();
  if (ircount >= 13)
    irdone = TRUE;
  set_timer0(0);
  enable_interrupts(INT_TIMER1);
}


#int_timer1
void timer_isr() {
  disable_interrupts(INT_TIMER1);
}


#separate
int1 decode_ir(int8 &addr, int8 &cmd) {
  int8 i;
  int8 mask;
  int8 bits[13];

  addr = 0;
  cmd = 0;

  for (i=1; i<=12; i++) {
    if ((ONE_MIN <= irframes[i]) && (irframes[i] <= ONE_MAX))
      bits[i] = 0x01;
    else
      if ((ZERO_MIN <= irframes[i]) && (irframes[i] <= ZERO_MAX))
        bits[i] = 0x00;
      else        // Error
        return FALSE;
  }

  mask = 0x01;
  for (i=1; i<=7; i++) {
    if (bits[i])
      cmd = cmd | mask;
    mask <<= 1;
  }

  mask = 0x01;
  for (i=8; i<=12; i++) {
    if (bits[i])
      addr = addr | mask;
    mask <<= 1;
  }

  return TRUE;
}


void start_ir() {
  memset(irframes, 0x00, sizeof(irframes));
  ircount = 0;
  irdone = FALSE;
}


void main() {
  int8 addr, cmd;
  int1 ok;
 
  delay_ms(100);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  set_tris_a(0x00);
  set_tris_b(0b11111111);
  set_tris_c(0b11111011);  // PIN_C2 used for the LED
  set_tris_d(0b00000000);  // LCD
  set_tris_e(0b11111111);
  setup_spi(FALSE);

 output_bit(PIN_A5, 1);
  //lcd_init();
  //output_bit(PIN_C2, 0);
  delay_ms(100);

  //lcd_putc("\fWaiting...");


  setup_timer_1(TIMER1_CONFIG);
  setup_timer_2(T2_DISABLED, 255, 1);
  ext_int_edge(0, L_TO_H);
  enable_interrupts(INT_EXT);
  enable_interrupts(GLOBAL);
delay_ms(100);
  start_ir();
  while(TRUE) {

    if (irdone) {
      ok = decode_ir(addr, cmd);
      printf("%u", cmd);
      printf("%u", addr);
      if (!ok){
        printf("1111");}
      else
        output_bit(PIN_A5, 0);
      delay_ms(50);
      output_bit(PIN_A5, 1);
      start_ir();
    }
  }
}
HTAluvBeBeo



Joined: 23 Feb 2008
Posts: 35

View user's profile Send private message

PostPosted: Thu Jul 03, 2008 9:34 pm     Reply with quote

I think the problem may be in here

my code
Code:
#include <16F877A.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)



/* TIMER0 configuration */
#define TIMER1_CONFIG   T1_INTERNAL | T1_DIV_BY_1

/* Interrupt rate:                     */
/* 4/20000000*65536*1 = 13.1 ms       */
/*                                     */
/*     Start: 3.0 ms (ignored)         */
/*     "1":   1.8 ms (9000)           */
/*     "0":   1.2 ms  (6000)           */

#define ONE_MIN  8000
#define ONE_MAX  10000
#define ZERO_MIN 5000
#define ZERO_MAX 7000


maybe I am wrong when calculate some value with timer ???
I calculated based on value of "1" : 1.8ms and "0" : 1.2 ms ???

original with 18F
Code:
#define CLKSPEED 32000000
#include <18F452.h>
#fuses H4,NOPROTECT,NOOSCSEN,BROWNOUT,BORV45,NOWDT,WDT128,PUT,NOSTVREN,NODEBUG,NOLVP,WRT,NOCPB,WRTB,WRTC,NOCPD,NOWRTD,NOEBTR,NOEBTRB
#use delay(clock=CLKSPEED)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#ignore_warnings none

#zero_ram

/* TIMER0 configuration */
#define TIMER0_CONFIG   RTCC_INTERNAL | RTCC_DIV_1

/* Interrupt rate:                     */
/* 4/32000000*65536*1 = 8.192 ms       */
/*                                     */
/*     Start: 3.0 ms (ignored)         */
/*     "1":   1.8 ms (14400)           */
/*     "0":   1.2 ms  (9600)           */

#define ONE_MIN  13400
#define ONE_MAX  15400
#define ZERO_MIN 8600
#define ZERO_MAX 10600
Pan0ramix



Joined: 06 Apr 2008
Posts: 2

View user's profile Send private message

PostPosted: Wed Jul 16, 2008 6:27 pm     Reply with quote

if i try to change the clock to 48mhz i posted my calculations on the code below.

my pic is the 18f2550.

why does he use the fast_io(a) to e? he doesnt use them all i think?

my pic only has 3 ports from what i can see and then i need to adapt the SET_TRIS to my 3 ports im i wrong?


he got this:
Code:

  setup_spi(FALSE);  -> but i use SPI on my LCD, will this be a problem?
  setup_wdt(WDT_OFF);

I posted my code below where i changed the lcd settings to my lcd.


to PCM_Programmer thank you for your answer to my previous post but i couldnt adapt that stuff to my pic so im trying this one (newbie :( )

thanks a lot guys

here is my code at the moment:
Code:

#define CLKSPEED 48000000

#include <18F2550.h>
#include <string.h>

#fuses NOPROTECT,BROWNOUT,NOWDT,WDT128,PUT,NOSTVREN,NODEBUG,NOLVP,WRT,NOCPB,WRTB,WRTC,NOCPD,NOWRTD,NOEBTR,NOEBTRB,HSPLL,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=CLKSPEED)

#define  RS_LCD  PIN_A0
#define  CSB_LCD  PIN_A1

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
//#use fast_io(D)
#use fast_io(E)
#ignore_warnings none

#zero_ram

/* TIMER0 configuration */
#define TIMER0_CONFIG   RTCC_INTERNAL | RTCC_DIV_1

/* Interrupt rate:                     */
/* 4/48000000*65536*1 = 5.461 ms       */
/*                                     */
/*     Start: 3.0 ms (ignored)         */
/*     "1":   1.8 ms (21601)           */
/*     "0":   1.2 ms  (14400)           */

#define ONE_MIN  20601
#define ONE_MAX  22601
#define ZERO_MIN 13400
#define ZERO_MAX 15400


char string[16];

void lcd_write_byte(unsigned char data,int1 rs){
    setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);
    output_low(CSB_LCD);
    if(rs==1)
        output_high(RS_LCD);             /* envia data */
    else
        output_low(RS_LCD);             /*envia comando*/
    delay_us(50);
    spi_write(data);
    delay_us(10);
    output_high(CSB_LCD);
}

void lcd_clear(void){
    lcd_write_byte(0x01,0);
    delay_ms(1);
}

void lcd_linha(int8 line){
    if(line==1)            //linha 1
      lcd_write_byte(0x80,0);
    if(line==2)            //linha 2
      lcd_write_byte(0xC0,0);
}

/*programa para escrever uma string*/
void lcd_string(void){
   int i;
   for(i=0;;i++)
      if(string[i]!='\0')
         lcd_write_byte(string[i],1);
      else
         return;
}

void lcd_setup(void){
    LCD_write_byte(0x39,0);   // Function set; 8 bit Datenlänge, 2 Zeilen, Instruction table 1
    delay_us(30);              // mehr als 26,3µs warten
    LCD_write_byte(0x1C,0);   // Bias Set; BS 1/5; 2 zeiliges Display /1d
    delay_us(30);              // mehr als 26,3µs warten
    LCD_write_byte(0x52,0);   // Kontrast C3, C2, C1 setzen /7c
    delay_ms(200);              // mehr als 200 ms warten
    LCD_write_byte(0x69,0);   // Booster aus; Kontrast C5, C4 setzen /50
    delay_us(30);              // mehr als 26,3µs warten
    LCD_write_byte(0x74,0);   // Spannungsfolger und Verstärkung setzen /6c
    delay_ms(200);           // mehr als 200ms warten !!!
    LCD_write_byte(0x0C,0);   // Display EIN, Cursor EIN, Cursor BLINKEN /0f
    delay_us(30);              // mehr als 26,3µs warten
    LCD_write_byte(0x01,0);   // Display löschen, Cursor home
    delay_ms(200);           // mehr als 200ms warten !!!
    LCD_write_byte(0x06,0);   // Cursor auto increment
    delay_us(30);              // mehr als 26,3µs warten
}
/* irframes[0] (start) will be garbage, ignore it...  */
int16 irframes[13];
int8 ircount = 0;
int1 irdone = FALSE;


#int_ext
void ext_isr() {
  if (irdone) return;
  irframes[ircount++] = get_timer0();
  if (ircount >= 13)
    irdone = TRUE;
  set_timer0(0);
  enable_interrupts(INT_TIMER0);
}


#int_timer0
void timer0_isr() {
  disable_interrupts(INT_TIMER0);
}


#separate
int1 decode_ir(int8 &addr, int8 &cmd) {
  int8 i;
  int8 mask;
  int8 bits[13];

  addr = 0;
  cmd = 0;

  for (i=1; i<=12; i++) {
    if ((ONE_MIN <= irframes[i]) && (irframes[i] <= ONE_MAX))
      bits[i] = 0x01;
    else
      if ((ZERO_MIN <= irframes[i]) && (irframes[i] <= ZERO_MAX))
        bits[i] = 0x00;
      else        // Error
        return FALSE;
  }

  mask = 0x01;
  for (i=1; i<=7; i++) {
    if (bits[i])
      cmd = cmd | mask;
    mask <<= 1;
  }

  mask = 0x01;
  for (i=8; i<=12; i++) {
    if (bits[i])
      addr = addr | mask;
    mask <<= 1;
  }

  return TRUE;
}


void start_ir() {
  memset(irframes, 0x00, sizeof(irframes));
  ircount = 0;
  irdone = FALSE;
}


void main() {
  int8 addr, cmd;
  int1 ok;
 
  delay_ms(100);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  set_tris_a(0b11111111);
  set_tris_b(0b11111111);
  set_tris_c(0b11111011);  // PIN_C2 used for the LED
  //set_tris_d(0b00000000);  // LCD
  set_tris_e(0b11111111);
  setup_spi(FALSE);
  setup_wdt(WDT_OFF);

  lcd_setup();
  output_bit(PIN_C2, 0);
  delay_ms(100);

   lcd_linha(1);
   lcd_clear();
  sprintf(string,"\fWaiting...");

  setup_timer_0(TIMER0_CONFIG);
  setup_timer_1(T1_DISABLED);
  setup_timer_2(T2_DISABLED, 255, 1);
  setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
  ext_int_edge(0, L_TO_H);
  enable_interrupts(INT_EXT);
  enable_interrupts(GLOBAL);

  start_ir();
 
#ignore_warnings 203
  while(TRUE) {
#ignore_warnings NONE
    if (irdone) {
      ok = decode_ir(addr, cmd);
      lcd_linha(1);
      lcd_clear();
      sprintf(string, "\fCmd  %3u\nAddr %3u", cmd, addr);
      if (!ok){
      lcd_linha(1);
      lcd_clear();
        sprintf(string, "  ERROR");}
      else
        output_bit(PIN_C2, 1);
      delay_ms(50);
      output_bit(PIN_C2, 0);
      start_ir();
    }
  }
}
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

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

SIRC modified
PostPosted: Fri Aug 15, 2008 9:15 am     Reply with quote

Hey all, just tried out the code in the first post of this discussion. It's good for a start, but I had my share of problems with it. One of the things I did was to get it to work with a 12F675. Another problem I had was that the TSOP is an active low device; so I dont really think that configuring the edge triggered interrupt as L_to_H would work properly. I've modified it suitably in my code. But in doing so (ie making it trigger as H_to_L) I had to make the array irframes with 14 int16's. However, I managed to reduce bits[13] from an int8 to a more compact int1.

Hardware: TSOP1738 on GP2; LEDs on GP4 and GP5; internal osc.

It works perfectly (or so I think) with a Sony RM952 remote. I suppose it'll work with most other Sony remotes. I used the PICKit2 Logic Analyser software to verify IR codes. Man! I love Microchip!...and CCS :-)


Two issues:
-I had to add a reset_cpu() statement (in bold below) in the while loop of the main function. This was because the PIC seemed to 'get out of sych' with the IR after a while.It would receive the first few (about 50) codes really well, and then it would 'lose' IR bits. Don't know why.

-Second problem:
I had to comment out the memset statement in start_ir(). When compiled memset kept putting a CLRF GPIO into the assembly code. Why is this happening? Ideas? Suggestions? (CCS compiler v4.057)

Please excuse the undocumented code....didnt really have time...will add documentation shortly.

(code edited...next post please :-) )
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

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

PostPosted: Sun Aug 17, 2008 9:29 am     Reply with quote

Hey all, below is documented code. Hope the brief explanations help.
Cheers,
Rohit

Code:

// This is code for an IR remote control decoder
// using the 12 bit SIRC protocol. Based on code
// by Aurelian Nichita.
// Hardware - TSOP1738 to GP2 of 12F675. Two LEDs
// on GP4 and GP5 as indicators.

// Sample signal at TSOP data output (taken using
// PICKit2 as a logic analyzer):
//
// ֿֿֿֿֿֿ\________/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿ\____/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿ\__/ֿֿֿֿֿ
// (idle)|  (start) | bit0| bit0| bit0|bit0| bit0| bit0| bit0| bit1 | bit0| bit0| bit0|bit0|(idle)
//
// example for remote button "1"
//
// TSOP data is inverted; it idles high.
// [ֿֿ\_ : negative going edge; _/ֿֿ : positive going edge]
//
// Rohit de Sa
// 15Aug08
// v1.0


#include <12f675.h>

#fuses INTRC_IO,NOWDT,NOCPD,NOPROTECT,PUT,NOMCLR,NOBROWNOUT
#use delay(clock=4000000)

#use fast_io(a)                           
#zero_ram

#define one_min 1450               //no of counts to safely detect bit1
#define one_max 2200               //optimal @4 MHz is 1800
#define zero_min 600               //no of counts to safely detect bit0
#define zero_max 1440               //optimal @4 MHz is 1200


int16 irframes[14];                  //holds incoming IR data
int8 ircount =0;                  //counts no if bits received
int1 irdone=false;                  //flag bit

#int_timer1                        //(is this isr necessary? I dont really know)
void timer1_isr()
{
   disable_interrupts(int_timer1);
}


#int_ext                        //IR bits detected by edge triggering
void ext_isr()
{
   if(irdone) return;
   irframes[ircount++]=get_timer1();
   if(ircount>=13)                  //if 13 triggers(ie 12 bits+start) found
      irdone=true;               //set "done" flag
   set_timer1(0);                  //restart timer for new bit
   enable_interrupts(int_timer1);      //(is this necessary? I dont really know)
}


int1 decode_ir(int8 &addr,int8 &cmd)   //IR decoding function
{
   int8 i;
   int8 mask;
   int1 bits[12];
   
   addr=0;
   cmd=0;
   
   irframes[13]=1200;               //last bit is always zero
   
   for(i=2;i<=13;i++)
   {
      if((one_min<=irframes[i])&&(irframes[i]<=one_max))
         bits[i-2]=0x01;            //if the sampled signal lies within limits
      else                     //set to 1
      if((zero_min<=irframes[i])&&(irframes[i]<=zero_max))
         bits[i-2]=0x00;            //if the sampled signal lies within limits
      else                     //set to 0
      return false;               //otherwise clear flag
   }
   
   mask=0x01;                     //format command
   for (i=0;i<=6;i++)
   {
      if (bits[i])
      cmd=cmd|mask;
      mask<<=1;
   }
   
   mask=0x01;                     //format address
   for (i=7;i<=11;i++)
   {
      if(bits[i])
      addr=addr|mask;
      mask<<=1;
   }
   
   return true;                  //set flag
}


void start_ir()
{
   ircount=0;
//   memset(irframes,0x00,sizeof(irframes));
   irdone=false;
}

void main()
{
   int8 addr, cmd;
   int1 ok;
   
   delay_ms(100);                  //setting up PIC
   setup_adc_ports(no_analogs);
   setup_adc(adc_off);
   set_tris_a(0b00000100);
   
   delay_ms(100);
                              //timer prescaler dependent on oscillator speed
   setup_timer_1(t1_internal|t1_div_by_1);
   ext_int_edge(0,h_to_l);
   enable_interrupts(int_ext);
   enable_interrupts(global);
   
   start_ir();
   while(1)
   {
      if (irdone)
      {
         ok= decode_ir(addr,cmd);
         if(!ok)                  //if bad bits or out of synch, reset processor
            reset_cpu();         //(can I avoid this?)
         else
         {
            if (addr==1)
            {
               switch (cmd)
                  {            
                     case (0x07)://Remote button "8"
                         {
                           output_high(pin_a5);
                           output_low(pin_a4);
                           break;
                        }
                     case (0x04)://Remote button "5"
                         {
                           output_high(pin_a4);
                           output_low(pin_a5);
                           break;
                        }
                     case (0x01)://Remote button "2"
                         {
                           output_high(pin_a5);
                           output_high(pin_a4);
                           break;
                        }
                     default:   //any other button
                        {
                           output_a(0x00);
                           break;
                        }
                  }
            }   
         }
         start_ir();
      }
   }
}
pyu



Joined: 04 Feb 2009
Posts: 51

View user's profile Send private message Yahoo Messenger

PostPosted: Sat Feb 21, 2009 11:08 am     Reply with quote

Is the last program really working?
longtdbk



Joined: 17 Apr 2010
Posts: 1

View user's profile Send private message

PostPosted: Sat Apr 17, 2010 10:42 am     Reply with quote

Thanks Vanhaser, Rohit! Your posts help me so much!
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

16F877a - sony remote
PostPosted: Mon Jul 05, 2010 10:20 am     Reply with quote

I have the same questions as HTAluvBeBeo above...

I have tried his code and get nothing.

In fact when I replace main with:
Code:

void main () {

while(1){
output_high(pin_b1);
}

}

and place an led/res on b1 I still get nothing.

Could it be placed continually in reset or something odd with this code?

I am using a 16F877A and a TSOP1138. When I put an LED on the output pin of the TSOP1138 I do see flashing, so I know that this works... but I get no interrupt.
07ee17



Joined: 04 Jul 2010
Posts: 1

View user's profile Send private message

PostPosted: Tue Jul 13, 2010 11:40 am     Reply with quote

Hi!
I tried the code given by Rohit de Sa. Code is same except some minor changes. My problem is same as of Rohit de Sa. It looks like PIC freezes after receiving some bits. Does anybody able to solve this?

If I uncomment memset() command PIC seems to decode fine but then it automatically clears the output even if I remove reset_cpu()??? Plz help me with this.

I am not pasting the code because it is given above as in Rohit De Sa's post.


Edit:
I think the problem might lies in timeout. I am unable to develop reset irframes[14] functions within interrupts in case of TIMEOUT.
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

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

PostPosted: Tue Jul 13, 2010 8:33 pm     Reply with quote

07ee17:

I was initially having that problem. Once I added a 4k7 pullup on the TSOP output, it started behaving itself. I have not had any problems till now.

Quote:
I had to comment out the memset statement in start_ir(). When compiled memset kept putting a CLRF GPIO into the assembly code.

Regarding the memset() issue, I haven't really spent much time on it. It seemed like a compiler issue to me at that time. I will check it out and let you know (umm, forum heavyweights, please help here :-P) Maybe its been resolved in compiler updates.

Rohit
sahu77



Joined: 08 Sep 2011
Posts: 202

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 12:35 pm     Reply with quote

Rohit de Sa wrote:
Hey all, below is documented code. Hope the brief explanations help.
Cheers,
Rohit

Code:

// This is code for an IR remote control decoder
// using the 12 bit SIRC protocol. Based on code
// by Aurelian Nichita.
.
.
.



I want change this code with RC5 code pl help me...
_________________
sahu
umairnaeem



Joined: 13 Nov 2011
Posts: 1

View user's profile Send private message Send e-mail

Changing interrupt from EXT_INT to int_rb
PostPosted: Sun Nov 13, 2011 11:58 am     Reply with quote

I am trying to change your code from external interrupt to interrupt on
change but it is not working or doing nothing at all. I need ext_int for
zero-crossing so I need ext_int free for that. Help me! Thanks. My code is:
Code:

#include <16f877A.h>
#fuses HS,NOWDT,NOCPD,NOPROTECT,PUT,NOBROWNOUT
#use delay(clock=4M)

//------------------------------------------------------------------------------
#use fast_io(A)                           
#use fast_io(B)                           
#zero_ram

//-----------------------------------------------------------------------------------#define one_min 1450               //no of counts to safely detect bit1
#define one_max 2200               //optimal @4 MHz is 1800
#define zero_min 600               //no of counts to safely detect bit0
#define zero_max 1440               //optimal @4 MHz is 1200

//-----------------------------------------------------------------------------------int16 irframes[14];                  //holds incoming IR data
int8 ircount =0;                  //counts no if bits received
int1 irdone=false;                  //flag bit 

//-----------------------------------------------------------------------------------#int_timer1                        //(is this isr necessary? I dont really know)
void timer1_isr()
{disable_interrupts(int_timer1);
}

//-----------------------------------------------------------------------------------#int_ext
 void ext_isr()
 {   
   if(irdone) return;
   irframes[ircount++]=get_timer1();
   if(ircount>=13)                  //if 13 triggers(ie 12 bits+start) found
   irdone=true;               //set "done" flag
   set_timer1(0);                  //restart timer for new bit
   enable_interrupts(int_timer1);      //(is this necessary? I dont really know)
 }                                                   

//-----------------------------------------------------------------------------------#int_rb
 void rb_isr()
 {
if(irdone) return;
   irframes[ircount++]=get_timer1();
   if(ircount>=13)                  //if 13 triggers(ie 12 bits+start) found
      irdone=true;               //set "done" flag
   set_timer1(0);                  //restart timer for new bit
   enable_interrupts(int_timer1);      //(is this necessary? I dont really know)
 

 }
                                                   
//------------------------------------------------------------------------------
int1 decode_ir(int8 &addr,int8 &cmd)   //IR decoding function
{
   int8 i;
   int8 mask;
   int1 bits[12];
   
   addr=0;
   cmd=0;
   
   irframes[13]=1200;               //last bit is always zero
   
   for(i=2;i<=13;i++)
   {
      if((one_min<=irframes[i])&&(irframes[i]<=one_max))
         bits[i-2]=0x01;            //if the sampled signal lies within limits
      else                     //set to 1
      if((zero_min<=irframes[i])&&(irframes[i]<=zero_max))
         bits[i-2]=0x00;            //if the sampled signal lies within limits
      else                     //set to 0
      return false;               //otherwise clear flag
   }
   
   mask=0x01;                     //format command
   for (i=0;i<=6;i++)
   {
      if (bits[i])
      cmd=cmd|mask;
      mask<<=1;
   }
   
   mask=0x01;                     //format address
   for (i=7;i<=11;i++)
   {
      if(bits[i])
      addr=addr|mask;
      mask<<=1;
   }
   
   return true;                  //set flag
}
//------------------------------------------------------------------------------
void start_ir()
{
   ircount=0;
//   memset(irframes,0x00,sizeof(irframes));
   irdone=false;
}
//------------------------------------------------------------------------------void main()
{
int8 addr, cmd;
int1 ok;

set_tris_b(0b11111111);
set_tris_c(0b00000000);
setup_timer_1(t1_internal|t1_div_by_1);      //timer prescaler dependent on oscillator speed
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(global);
ext_int_edge(0,h_to_l);

//delay_ms(10);                             

port_b_pullups(true);   // Parameter is a bitmask (for bit 4)
delay_us(10);

//-----------------------------------------------------------------------------   start_ir();
   while(true)
   {
      if (irdone)
      {
         ok= decode_ir(addr,cmd);
         if(!ok)                  //if bad bits or out of synch, reset processor
            reset_cpu();         //(can I avoid this?)
         else
         {
            if (addr==1)
            {
               switch (cmd)
                  {             
                     case (0x00)://Remote button "1"
                         {
                           output_toggle(pin_c0);
                           delay_ms(1000);
                           break;
                        }
                     case (0x01)://Remote button "2"
                         {
                           output_toggle(pin_c1);
                           delay_ms(100);
                           break;
                        }
                     case (0x02)://Remote button "3"
                         {
                      output_toggle(pin_c2);
                  delay_ms(100);
                           break;
                        }
                   
               case (0x03)://Remote button "4"
                         {
                         output_toggle(pin_c3);
                     delay_ms(1000);
                           break;
     
                        }
                   
                default:   //any other button
                        {
                           output_c(0x00);
                           break;
                        }
                  }
            }   
         }
         start_ir();
      }
   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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