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

Tachometer

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



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

Tachometer
PostPosted: Tue Sep 02, 2014 4:53 pm     Reply with quote

Hi guys. I am trying to build a tachometer by pic16f877a with IR sensor.
I think i have trouble with interrupts. Timer stops in the middle...
This is the code i wrote.
Thanks.
Code:

#include <16f877a.h>

#fuses hs,nowrt,nowdt,nodebug,brownout,nolvp,nocpd,put,noprotect
#use delay (clock=20000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors)

#define LCD_ENABLE_PIN  PIN_B0            //#define use_portb_lcd TRUE                   
#define LCD_RS_PIN      PIN_B1                                   
#define LCD_RW_PIN      PIN_B2                                     
#define LCD_DATA4       PIN_B4                                     
#define LCD_DATA5       PIN_B5                                   
#define LCD_DATA6       PIN_B6                                   
#define LCD_DATA7       PIN_B7

#include <lcd.c>     // For LCD and has to be after #use delay()

unsigned int16 i=0,t1=0,t2=0;
unsigned int x=0,y=0,t=0;
float32 pulse_width=0;

#int_TIMER1
void one_minute()
{
   ++i;
   if (i==600) // 60 sec.
   {
      output_toggle(PIN_D1);
      t=0.1*i;
      x=1;
   }
   set_timer1(3035);
}



void main ()
{
set_tris_a(0xff);
set_tris_d(0x00);
output_d(0x00);
lcd_init();
delay_ms(100);
printf(lcd_putc,"\fREADY");
delay_ms(500);
printf(lcd_putc,"\nWAITING...");


setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
set_timer1(3035);                   //========> 1/(20.000.000)*8*4(65535-3035)=0.1 sec. 
enable_interrupts(int_timer1);
enable_interrupts(GLOBAL);

output_toggle(PIN_D1);

while (TRUE)
{
   if (input (pin_A4) && y==0 )
   {
      while (input (pin_A4));
      t1=get_timer1();
      while (!input (pin_A4));
      t2=get_timer1();
      setup_timer_1(T1_DISABLED);
      printf(lcd_putc,"\fCalculating...");
      delay_ms(100);
      pulse_width=(0.1*(t1-t2)/(65535-3035))+t;
      printf(lcd_putc,"\fPulse width \n%f seconds",pulse_width);
      delay_ms(500);

      y=1;
   }
   
 
   if (x==1)
   {
      setup_timer_1(T1_DISABLED);
      printf(lcd_putc,"\fTimer Stopped in \n%u seconds",t);
      x=0;
   }
 
}

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 12:49 am     Reply with quote

Without even looking at the main:

1) i==600 - what then sets i back to 0?.
2) float maths in the interrupt - don't do this. Multiple problems:
First interrupts will be disabled in float multiplies in the main.
Second it takes an age.
Third it is large.

Avoid float maths in anything if you can.
Think about it. Just have an int16 or int32, that is in 0.1 sec 'counts'. Then use %l5.1w in the printf, which will display this as xxx.x seconds. No need to ever involve float. Code will be smaller, faster, and more reliable (fp suffers from routing errors, which integers don't have...).

I didn't look further.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 2:23 am     Reply with quote

Thanks for reply.
I have changed the code but now counter goes up not only high to low but also low to high.
Code:

#include <16f877a.h>

#fuses hs,nowrt,nowdt,nodebug,brownout,nolvp,nocpd,put,noprotect
#use delay (clock=20000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors)

#define LCD_ENABLE_PIN  PIN_B0            //#define use_portb_lcd TRUE                   
#define LCD_RS_PIN      PIN_B1                                   
#define LCD_RW_PIN      PIN_B2                                     
#define LCD_DATA4       PIN_B4                                     
#define LCD_DATA5       PIN_B5                                   
#define LCD_DATA6       PIN_B6                                   
#define LCD_DATA7       PIN_B7

#include <lcd.c>     // For LCD and has to be after #use delay()

unsigned int16 i=0;
unsigned int x=0;

#int_TIMER0
void one_minute()
{
      output_toggle(PIN_D1);
      ++i;
      x=1;
      set_timer0(255);
}



void main ()
{
set_tris_a(0xff);
set_tris_d(0x00);
output_d(0x00);
lcd_init();
delay_ms(100);
printf(lcd_putc,"\fREADY");
delay_ms(500);
printf(lcd_putc,"\nWAITING...");


setup_timer_0 (RTCC_DIV_2|RTCC_EXT_H_TO_L);
set_timer0(255);                 
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);

output_toggle(PIN_D1);

while (TRUE)
{
   if (x==1 )
   {
      printf(lcd_putc,"\fRPM %Lu",i);
      set_timer0(255);
      enable_interrupts(int_timer0);
      enable_interrupts(GLOBAL);
      x=0;
   }
   
 
}}
     
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 2:48 am     Reply with quote

It'll trigger almost instantly....

Timer0, is an 8bit timer. Counts to 256. You are setting it to 255, so it'll trigger just two edges later.....
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 10:34 am     Reply with quote

Please explain EXACTLY how you are trying to achieve a display of RPM.

I can't understand your code at all.

Mike
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 1:02 pm     Reply with quote

Hi. This is only the first part i wrote. I want to calculate time between two pulses. But the problem is timer interrupts also when it goes low to high.
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 1:24 pm     Reply with quote

While not your current problem, I would give serious consideration to looking at at least 10 pulses (and then applying some form of averaging) or you are more than likely to get numbers that jump all over the place and not be readable. If you are looking at a fan for example with IR and the blades are not symmetrically placed, you will get strange results.

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Sep 03, 2014 3:54 pm     Reply with quote

Ruby wrote:
Hi. This is only the first part i wrote. I want to calculate time between two pulses. But the problem is timer interrupts also when it goes low to high.

So, what EXACTLY were you trying to do.
To me, your code bears no relation to any of your explanations.
We can better help when you provide more information.

Mike
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Thu Sep 04, 2014 12:11 pm     Reply with quote

Ok. I have two options for diy tachometer.
1) Calculate time between two pulses
2) Calculate how many pulses in a minute.

I tried the first one. Without calculating time.
Ps: Do I have to use ccp?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Thu Sep 04, 2014 1:45 pm     Reply with quote

OK. Let's be serious.

Tell us:-

1) What kind of pulses you are trying to measure.
2) The expected frequency range of your pulses.

Maybe then we can start to do sensible design.

Mike
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Sat Sep 06, 2014 9:30 am     Reply with quote

Poblem solved.
I change two things.
1)setup_timer_0 (RTCC_DIV_2|RTCC_EXT_H_TO_L);  ==> DIV_1
2)The most important ; my sensor has two outputs. Analog and digital. Pic was connected to digital so I swaped it , it works perfect.

Now I did counter but when motor runs fast sensor can't catch the black spot.
And how can I calculate the time between two pulses?
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