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

TSOP 1740 & pic 16F887

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



Joined: 04 Feb 2009
Posts: 51

View user's profile Send private message Yahoo Messenger

TSOP 1740 & pic 16F887
PostPosted: Sat Feb 21, 2009 5:32 pm     Reply with quote

Hi.
I have a ir sensor on my pickit2 board, but it isn't working.
The code I used:
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 <16f887.h>

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

#use fast_io(B)                           
#zero_ram

#include "Flex_LCD.c"

#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_RB                       //IR bits detected by edge triggering
void ext_isr()
{
   if(irdone) return;
   for(ircount=0;ircount<=13;ircount++)
   {
      irframes[ircount]=get_timer1();
   }
   //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_b(0b00000011);
    lcd_init();

   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_RB1);
   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();
      }
   }
}


The problem is here:
Code:
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

It always return false.
Here are some print's debugging.




[/img]
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Feb 22, 2009 3:25 pm     Reply with quote

The code - as shown in the listing and the debug dump - can't work, cause it fills irframes in a loop following a single interrupt.

Don't know, if you also tried a meaningful bittime measurement? If so, you should dump the irframes array for debug purposes rather than complaining that it does not met some expected criterion.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Feb 22, 2009 3:44 pm     Reply with quote

Also, in your #INT_RB function, you need to read Pin B1 to clear the
"mismatch" condition. The "mismatch" condition is what generates
the INT_RB interrupt. You need to clear it so the PIC will be ready
to detect the next "change" (edge) tha occurs on pin B1. It's cleared
by reading the pin. Add the lines shown in bold below.
Quote:

#INT_RB
void ext_isr()
{
int8 temp;

if(irdone) return;
for(ircount=0;ircount<=13;ircount++)
{
irframes[ircount]=get_timer1();
}
//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);

temp = input(PIN_B1);
}

I didn't look at your code and try to figure out what you're doing.
I just wanted to mention this one thing.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Feb 23, 2009 3:23 am     Reply with quote

Yes, a very important hint by PCM Programmer. I wrongly assumed, you would be using an external edge sensitive interrupt. Cause you are actually using RB interrupt, do you intend to detect both edges? If not, the code has to be corrected to ignore the other edge for timing measurement.
pyu



Joined: 04 Feb 2009
Posts: 51

View user's profile Send private message Yahoo Messenger

PostPosted: Mon Feb 23, 2009 4:07 am     Reply with quote

Thanks for reply FvM and PCM programmer Smile

Quote:
You need to clear it so the PIC will be ready
to detect the next "change" (edge) tha occurs on pin B1. It's cleared
by reading the pin.

I had made some corrections in my code.
Code:

#INT_RB                       //IR bits detected by edge triggering
void ext_isr()
{
   int8 temp;
   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)
    temp = input(PIN_B1);
}

The result is better than the first time.


Quote:
Cause you are actually using RB interrupt, do you intend to detect both edges? If not, the code has to be corrected to ignore the other edge for timing measurement.

Yes, I want to detect both edges, from tsop1740 ir sensor.

Now, I have some timing problems. irframes[2], irframes[3] are bigger than expected, and irframes[8], irframes[9], irframes[10] and irframes[11] are smaller. I don't know why this is happening, I will do some research.

pyu



Joined: 04 Feb 2009
Posts: 51

View user's profile Send private message Yahoo Messenger

PostPosted: Wed Feb 25, 2009 1:32 am     Reply with quote

Doesn't anybody know why I get this timers?



Because I use TSOP1740 and the source code was for 1738? My timer is not set correct?
pyu



Joined: 04 Feb 2009
Posts: 51

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Mar 08, 2009 9:20 am     Reply with quote

Anyone? Sad
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