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 support@ccsinfo.com

Measure pulse width with dsPIC

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



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

Measure pulse width with dsPIC
PostPosted: Sat Feb 01, 2020 1:29 pm     Reply with quote

Hi
I want to measure pulse width (between 0 and 800 us) for 16 signal.
I used below method but pulse width is not correct.
I wrote code for 4 signals and then stop because result is not ok!
For example pulse width for 1st signal=35993 !!!
Can you help me to solve problem ?
Code:

void main()
{

// setup_pll();
  set_ticks(0);
  while(true)
   {   
     for (int i=0;i<=4;i++) {done[i]=0;}
     set_ticks(0);
   
     while (done[0]==0 || done[1]==0 || done[2]==0 || done[3]==0 || done[4]==0)
     {
         // tssp0
         if(TSSP0==0 && Pre_Edge[0]==1  ) {start_time[0]=get_ticks();Pre_Edge[0]=0;}  // Start time
    else if(TSSP0==1 && Pre_Edge[0]==0  )
           {
           end_time[0]=get_ticks();
        if(end_time[0]>start_time[0]) pulsewidth[0]=end_time[0]-start_time[0];
        else pulsewidth[0]=65535-(start_time[0]-end_time[0]);
       // if(pulsewidth[0]>800)  pulsewidth[0]=0;
           done[0]=1;}   
          // tssp1
         if(TSSP1==0 && Pre_Edge[1]==1  ) {start_time[1]=get_ticks();Pre_Edge[1]=0;}  // Start time
    else if(TSSP1==1 && Pre_Edge[1]==0  )
           {
           end_time[1]=get_ticks();
        if(end_time[1]>start_time[1]) pulsewidth[1]=end_time[1]-start_time[1];
        else pulsewidth[1]=65535-(start_time[1]-end_time[1]);
         done[1]=1;} 
         // tssp2
          if(TSSP2==0 && Pre_Edge[2]==1  ) {start_time[2]=get_ticks();Pre_Edge[2]=0;}  // Start time
    else if(TSSP2==1 && Pre_Edge[2]==0  )
           {
           end_time[2]=get_ticks();
        if(end_time[2]>start_time[1]) pulsewidth[2]=end_time[22]-start_time[1];
        else pulsewidth[2]=65535-(start_time[2]-end_time[2]);
         done[2]=1;} 
         
       // tssp3
         if(TSSP3==0 && Pre_Edge[3]==1  ) {start_time[3]=get_ticks();Pre_Edge[3]=0;}  // Start time
    else if(TSSP3==1 && Pre_Edge[3]==0  )
           {
           end_time[3]=get_ticks();
        if(end_time[3]>start_time[3]) pulsewidth[3]=end_time[3]-start_time[3];
        else pulsewidth[3]=65535-(start_time[3]-end_time[3]);
           done[3]=1;} 
           
        // tssp4
         if(TSSP4==0 && Pre_Edge[4]==1  ) {start_time[4]=get_ticks();Pre_Edge[4]=0;}  // Start time
    else if(TSSP4==1 && Pre_Edge[4]==0  )
           {
           end_time[4]=get_ticks();
        if(end_time[4]>start_time[4]) pulsewidth[4]=end_time[4]-start_time[4];
        else pulsewidth[4]=65535-(start_time[4]-end_time[4]);
           done[4]=1;} 
         
    }   
    printf("p0=%lu , p1=%lu ,p2=%lu , p3=%lu,  p4=%lu , \r\n",pulsewidth[0],pulsewidth[1],pulsewidth[2],pulsewidth[3],pulsewidth[4]);
    set_ticks(0);
      } 
   }



Code:

#Include<33ep128gp506.h>
#include <math.h>
#include<ConfigureClock.h>
/#pin_select
#pin_select U1TX=PIN_a4
#pin_select U1RX=PIN_c7   //no rx//just a useless pin
#use rs232(UART1,baud=9600)
#use i2c(SLAVE,I2C1,address=0xA2,stream=I2C_PORT1)
#use timer(timer=1,tick=4us,bits=16,isr)
//#use rs232(baud=38400,parity=N,xmit=PIN_a4,rcv=pin_c7,bits=8,stream=blt)

#define TSSP0 input(pin_b1)
#define TSSP1 input(pin_e15)
#define TSSP2 input(pin_a8)
#define TSSP3 input(pin_b7)
#define TSSP4 input(pin_b10)

unsigned int16 Pulsewidth[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},start_time[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned int16done[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, end_time[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Ttelmah



Joined: 11 Mar 2010
Posts: 19258

View user's profile Send private message

PostPosted: Sat Feb 01, 2020 2:01 pm     Reply with quote

Use the input capture peripherals.
You don't tell us which PIC, but most DsPIC's support separate input
capture on almost all pins.
The peripheral will record the value from the selected clock at the
moment the 'event' occurs. You can program it to just capture on rising
edges, falling edges or both. The values are buffered recording up to
four edge times each.
Far faster, and more accurate than your polling approach can ever be.
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

PostPosted: Sat Feb 01, 2020 9:33 pm     Reply with quote

Mcu: dsPIC33EP128GP506 and I need to measure 16 pulse width signals but
dsPIC33EP128GP506 only has 4 input capture.
Ttelmah



Joined: 11 Mar 2010
Posts: 19258

View user's profile Send private message

PostPosted: Sun Feb 02, 2020 1:09 am     Reply with quote

OK.
In fact the input capture is still the better way to go.

Now the reason your existing code has problems is it is not actually
detecting the 'edge' of the signal. You have to sit while the signal is low,
then read when it _changes_ to high, to read the rising edge. This is not
happening with what you are doing on the first edge, so it can actually
start counting at the wrong place in the signal....

However the key is that the input capture can be dynamically moved from
pin to pin, using PPS, so much simpler to setup the input capture from
a suitable clock, attach it to the first pin, take a reading, then attach to
the second, take a reading, etc. etc.. Now if you use two input capture
units, set one to capture the rising edge, and one the falling, then you
have two counts for the two edges. If you wait for one on the rising edge
detector, and then one on the falling detector, you then have the values
you need.
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

PostPosted: Sun Feb 02, 2020 4:43 am     Reply with quote

i write code in other form
pulse width=600 us
measure with micro controller is = 10677!!
tick time is 1.06 us then pulse width measure with micro=11317 us !!

Code:

  while(true)
   {   
     
        if (TSSP0==0) {if(Pre_Edge[0]==1) edgeLH0++;}
       
        if (edgeLH0==2){start_time[0]=get_ticks();Pre_Edge[0]=0;edgeLH0=0;led2_high;}  // Start time
       
        if(TSSP0==1){if(Pre_Edge[0]==0) edgeHL0++;}
        if (edgeHL0==2)
           {
           end_time[0]=get_ticks();led2_high;
        if(end_time[0]>start_time[0]) pulsewidth[0]=end_time[0]-start_time[0];
        else pulsewidth[0]=65535-(start_time[0]-end_time[0]);
           done[0]=1;edgeHL0=0; } 
          if(done[0]==1) {printf("p0=%lu ,p1=%lu ,p2=%lu \r\n",pulsewidth[0],start_time[0],end_time[0]); done[0]=0;set_ticks(0);}//set_ticks(0);} 
          else printf("doing..\r\n");
    }
Ttelmah



Joined: 11 Mar 2010
Posts: 19258

View user's profile Send private message

PostPosted: Sun Feb 02, 2020 4:59 am     Reply with quote

The way you have to do this (pseudo code), is:
Code:

while(signal_is_high)
   ;

while (signal_is_low)
   ;

record_ticks

while(signal_is_high)
   ;

record_ticks;


You must do the double test at the start, or if the pulse is in a 'low' when
you start, you will record the starting edge at the wrong point.

Also (honestly), I don't trust the #use timer setup. Setup the timer to
simply free-run directly from the processor clock. Much more likely to
give accurate results.
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