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

dsPIC33EP Input Capture
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

dsPIC33EP Input Capture
PostPosted: Mon Aug 26, 2019 1:40 am     Reply with quote

Hello All,
I want to set up a simple input capture program. I use IC1 module which is PIN_B2, after I did my research I was able to write this code:
Code:
#include <./33EP64MC206.h>

#use delay(internal=28MHz)     
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC                     
#FUSES NOOSCIO

#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)

#use fast_io(b)

#INT_IC1
void inputcapture_interrupt()
{
    printf("input captured");
 
}

int main()
{

   setup_oscillator(OSC_INTERNAL,28000000);
   setup_capture(PIN_B2, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);

   set_tris_b(0x04);
   enable_interrupts(INT_IC1);
   enable_interrupts(GLOBAL);
 
   while(1)
 
   {
        delay_ms(100);

    }
     
}

I made PIN_B2 as PULL-DOWN, when I push button PIN_B2 will be high, and I thought when this happened, pic will capture this HIGH and it would enter the interrupt function. But it didn't happen. I don't get a message on my serial terminal. What is my wrong in my code?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 26, 2019 2:30 am     Reply with quote

You're missing the #pin_select for IC1.
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Mon Aug 26, 2019 2:32 am     Reply with quote

Okay, I solved my problem. The problem is that:

setup_capture(PIN_B2, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);
writing PIN_B2 here. I use IC1 module and I need to write 1 instead of PIN_B2.
Actually I wrote 1 here at first before PIN_B2 and compiler gave me an error "invalid pin" like this and I changed it to PIN_B2. So, I continued my research on internet and I found this thread:

https://ccsinfo.com/forum/viewtopic.php?p=178309

It solved my problem.

I added this line to the top:
Code:
#PIN_SELECT ic1=PIN_B2

Here is my last code that captures a signal and makes an interrupt:
Code:
#include <./33EP64MC206.h>

#use delay(internal=28MHz)     
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC                     
#FUSES NOOSCIO

#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#PIN_SELECT ic1=PIN_B2


#INT_IC1
void inputcapture_interrupt()
{
    printf("input captured");
 
}

void main()
{

   setup_oscillator(OSC_INTERNAL,28000000);
   setup_capture(1, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);


   enable_interrupts(INT_IC1);
   enable_interrupts(GLOBAL);
 
   while(1)
 
   {
        delay_ms(100);

    }
     
}


Last edited by camleot23 on Mon Aug 26, 2019 3:05 am; edited 2 times in total
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Mon Aug 26, 2019 2:33 am     Reply with quote

Thank you PCM Programmer Smile I realized that, thank you so much:)
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Mon Aug 26, 2019 2:39 am     Reply with quote

That was funny, started typing to point out that IC1 is not PIN_B2, and
needs a PIN_SELECT, and saw that PCM 'beat me to it'. Smile

Actually what you have posted as 'fixed' is wrong. The capture needs to be setup as:

setup_capture(1, CAPTURE_RE | INTERRUPT_EVERY_CAPTURE);

The reason this gave an invalid pin when you tried to use it originally was
because the pin for IC1 was not setup....

Also your 'main' declaration is wrong. It should be 'void', not 'int'.
In CCS, there is no 'operating system' for a 'main' routine to return anything
'to', so the main routine should always be 'void' and return nothing...
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Mon Aug 26, 2019 3:05 am     Reply with quote

Yes Ttelmah, you are right I forgot to change PIN_B2 as 1. Now I edited thank you for your reply too Smile And for "main" point, you are also right too Smile I forgot to change it. Thank you.

Note for other users: The code that I shared above (second one) is corrected/edited according to Ttelmah and PCM Programmer. It is working.
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Tue Aug 27, 2019 8:59 am     Reply with quote

I encounter with a problem. When my input stays high, my interrupt is working. Why? I set my config as Rising Edge. What may be the problem?

Actually, It is strange that when I load this code to pic, I'm having the problem:

Code:
#include <./33EP64MC206.h>

#use delay(internal=42MHz)     
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC                      //internal oscillator icin gerekli
#FUSES NOOSCIO

#use i2c(master,I2C1,STREAM=lcd_kanal)
#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#PIN_SELECT ic1=PIN_B2 //Capture pin icin gereklii

#include <./i2C_Flex_LCD_with_BIGNUMBERS.h>
 int i=0;
 int counter=0;
 
#INT_IC1
void inputcapture_interrupt()
{   
  i++;
 
}
 
void main()
{
   setup_oscillator(OSC_INTERNAL,42000000);
   setup_capture(1, CAPTURE_RE);
   enable_interrupts(INT_IC1);
   enable_interrupts(GLOBAL);
   lcd_init();
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   lcd_gotoxy(1,1);
   lcd_putc("test V0.1");
   delay_ms(1000);     
   lcd_putc("\f");
   while(1)
    {
     
             lcd_gotoxy(1,1);
             printf(lcd_putc,"Yklnn plse %02d",i);
             delay_ms(100);
   
    }
}


But when I load like this, when my input stays high, it doesn't count. It waits to become low and when it becomes high again, it counts normally. However this time there are pulse losses that I miss to capture If I send pulses too fast.
Code:

#include <./33EP64MC206.h>

#use delay(internal=42MHz)   
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES FRC                      //internal oscillator icin gerekli
#FUSES NOOSCIO

#use i2c(master,I2C1,STREAM=lcd_kanal)
#use rs232(baud=9600,parity=N,stop=1,xmit=PIN_G7 ,rcv=PIN_G6)
#PIN_SELECT ic1=PIN_B2 //Capture pin icin gereklii

#include <./i2C_Flex_LCD_with_BIGNUMBERS.h>
 int i=0;
 int counter=0;
 
#INT_IC1
void inputcapture_interrupt()
{   
  i++;
   lcd_gotoxy(1,1); ///MOVED HERE
   printf(lcd_putc,"Yklnn plse %02d",i);//MOVED HERE
}
 
void main()
{
   setup_oscillator(OSC_INTERNAL,42000000);
   setup_capture(1, CAPTURE_RE);
   enable_interrupts(INT_IC1);
   enable_interrupts(GLOBAL);
   lcd_init();
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   lcd_gotoxy(1,1);
   lcd_putc("test V0.1");
   delay_ms(1000);     
   lcd_putc("\f");
   while(1)
    {
     
             delay_ms(100);
   
    }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Tue Aug 27, 2019 12:07 pm     Reply with quote

You must not have slow things like the print in your ISR.

Your original code is the better starting point except you probably
don't want to actually print unless the count has incfremented.

However the reason it hangs is because you are not reading the
capture buffer. This must be read in the ISR. If it is not read after
four captures the buffer will overflow. It'll also keep interrupting till
it is read. Because the signal is high, the capture gets set, and then
you are stuck.
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Tue Aug 27, 2019 11:42 pm     Reply with quote

Thank you Ttelmah. I understand you but how can I read capture buffer? What is its function?
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Tue Aug 27, 2019 11:47 pm     Reply with quote

I found these in device header file;

_bif unsigned int16 get_capture(unsigned int8 module);
_bif unsigned int16 get_capture(unsigned int8 module, int1 wait);
_bif unsigned int32 get_capture32(unsigned int8 module);
_bif unsigned int32 get_capture32(unsigned int8 module, int1 wait);
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Wed Aug 28, 2019 12:53 am     Reply with quote

Code:
int1 NewCapture = FALSE;

#INT_IC1
void inputcapture_interrupt()
{   
   
   if(!NewCapture)
   {
      FirstCapture = get_capture(1,FALSE);   //Read first capture event.
      NewCapture = TRUE;
   }
   else
   {
      dummy = get_capture(1,TRUE);  //The TRUE causes the last capture event to
                                    //be retrieved from the capture FIFO buffer 
                                    //and to clear out any previous captures.
                                    //This is used to keep the FIFO buffer from
                                    //overflowing while calculating and
                                    //displaying the time.  If an overflow
                                    //occurs it will cause any further Input
                                    //Capture interrupts form occuring.
   } 
    i++;

}
 
void main()
{
   setup_oscillator(OSC_INTERNAL,42000000);
   setup_capture(1, CAPTURE_RE |INTERRUPT_EVERY_CAPTURE );
   enable_interrupts(INT_IC1);
   enable_interrupts(GLOBAL);
   lcd_init();
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   output_toggle(pin_b5);
   delay_ms(100);
   lcd_gotoxy(1,1);
   lcd_putc("test V0.1");
   delay_ms(1000);     
   lcd_putc("\f");
   
   while(1)
    {
      if(NewCapture)
      {
       
        lcd_gotoxy(1,1);
        printf(lcd_putc,"Yklnn plse %02d",i);
        NewCapture = FALSE;
       
       
      }
    }
}

It is reading more pulses than I send. Also, I can generate the pulses with mechanically so I can adjust my pulses' width and can send them too fast or
too slow.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Wed Aug 28, 2019 1:32 am     Reply with quote

OK.

'reading more pulses than I send'. Are you sure?. If the pulses are from a
mechanical source then I have to say that _bounce_ is the most likely
problem. You need to look at cleaning up the input signal (small capacitor).
The CCP is both reliable, and very fast.

You are making it lose counts, by throwing events away, while waiting
for the slow LCD. Don't do this. Just record the 'i' value, and leave the
capture buffer filling. This should raise the speed supported enormously.
camleot23



Joined: 16 Aug 2019
Posts: 52

View user's profile Send private message

PostPosted: Wed Aug 28, 2019 3:21 am     Reply with quote

What do you mean by the bounce ? You mean a square wave signal something like this. (Normally It should be straight)
..... .... __
........_|.. |
____|..... |_____
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 28, 2019 3:39 am     Reply with quote

Go to Google image search and search for this:
Quote:
switch contact bounce

You'll see many scope diagrams showing switch bounce.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Wed Aug 28, 2019 4:57 am     Reply with quote

A very good little summary is at:

<http://rsrelectronics.com/t_bounc.htm>

You can debounce by simply not counting if the change from the last
capture value is less than some figure. However this will slow the maximum
rate that can be captured.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion 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