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

Wind speed counter

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



Joined: 22 Apr 2009
Posts: 14

View user's profile Send private message

Wind speed counter
PostPosted: Fri Apr 24, 2009 11:18 am     Reply with quote

So I'm using IR and phototransistor and writing a program to count the wind speed. Counting process is simple detecting first low input and then second. Then getting result and of the time distance is known so we know and the speed.
So maybe anyone can help figure out how to make cycle like this and how the pic16f877a timer1 get second value?
Code so far:
Code:
#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include <stdlib.h>
#include <lcd.c>

#include <ctype.h>

void wait_for_low1() {

   while(input(PIN_C1));       /* if it's high, wait for a low */
   delay_us(3);                 /* account for fall time */

   while(!input(PIN_C1 ));    /* wait for signal to go high */
   }


void wait_for_low2() {

   delay_us(3);                 /* account for rise time */
   while(input(PIN_C1));        /* wait for signal to go low */
   lcd_init();
}
   
   //int16 time;
   float distance,mph,time;


void main() {
   
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);

   distance = 500;
   lcd_init();

   do {
      wait_for_low1();
      set_timer1(0);
      wait_for_low2();
      time = get_timer1();
     
      mph = 0.0000016*(float)time/3600.0;  // calculate the time in hours
      mph = distance/(63360.0*mph);

      printf(lcd_putc "value: %3.1fn\n\r",(float) time);

   } while (TRUE);         
}
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri Apr 24, 2009 11:36 am     Reply with quote

This would be a good one to use an interrupt on. Tie your input to a pin with an interrupt. The first time the interrupt is entered, zero a variable that is incremented by a timer (that way you know the frequency the counter is incremented at). The next time the interrupt is entered, see how high the counter variable is and you can calculate your speed from that. Zero your counter again and it's ready for the next pulse. This will free up your program to do other things.

Ronald
snooer



Joined: 22 Apr 2009
Posts: 14

View user's profile Send private message

PostPosted: Fri Apr 24, 2009 11:48 am     Reply with quote

I'am new in C so maby can you show in code? Ore some example
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 24, 2009 11:52 am     Reply with quote

Quote:
void wait_for_low1() {

while(input(PIN_C1)); /* if it's high, wait for a low */
delay_us(3); /* account for fall time */

while(!input(PIN_C1 )); /* wait for signal to go high */
}

You have modified the CCS routine "wait_for_low_to_high()" from the
Ex_Pulse.c example file. The new name you have given it is not very
good. You should use the CCS function name, or maybe call it
"wait_for_rising_edge()"


Quote:
void wait_for_low2() {
delay_us(3); /* account for rise time */
while(input(PIN_C1)); /* wait for signal to go low */
lcd_init();
}

This routine also comes from the Ex_Pulse.c example. CCS calls it
"wait_for_low()". You have added a call to the lcd_init() routine.
That's not necessary. You should only call lcd_init() one time, at the
start of main(). If you need to clear the lcd, then do this:
Code:
lcd_putc('\f');   

or this:
Code:
printf(lcd_putc, "\f");



Quote:

Counting process is simple detecting first low input and then second.

So you want to count negative-going (falling) edges on the signal.

You can do this by modifying the CCS "wait_for_low_to_high()" routine
and make a wait_for_high_to_low() routine. Then call it 2 times, in a
similar way as the code at the start of your do-while loop. Set the timer
to 0 after the first call. Then read the timer after the 2nd call.
snooer



Joined: 22 Apr 2009
Posts: 14

View user's profile Send private message

PostPosted: Fri Apr 24, 2009 11:59 am     Reply with quote

I was thinking about that and yes it's redone code from examples because i need to count from low to low input.
Code:
void wait_for_low1() {

   while(input(PIN_C1));       /* if it's high, wait for a low */
   delay_us(3);                 /* account for fall time */

   while(!input(PIN_C1 ));      /* wait for signal to go high */
   
   }

void wait_for_low2() {

   delay_us(3);                 /* account for rise time */
  while(input(PIN_C1));         /* wait for signal to go low */
  delay_us(3);
 
  while(!input(PIN_C1));
 
   
}

But in this case the phototransistor has to be trigered two times. It's not a big problem the bigest problem is that i dont know how to timer1 reult convert to S in diferent osilator
snooer



Joined: 22 Apr 2009
Posts: 14

View user's profile Send private message

PostPosted: Fri Apr 24, 2009 1:55 pm     Reply with quote

Can anyone tell me why can't I get seconds in LCD getting numbers from 500 to 11000?
Code:
do {
   
      wait_for_low1();
      set_timer1(0);
      wait_for_low2();
      time = get_timer1();
     
      time_s = 0.0000016*(float)time*63360.0;  // calculate the time in hours
     // mph = distance/(63360.0*mph);
     
      printf(lcd_putc "value: %3.2f s\r\n", time_s);

   } while (TRUE);         
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 24, 2009 2:26 pm     Reply with quote

1. Use a printf statement after you get the Timer1 value, and display it.
Use "%ld" or "%lx" to display an int16 value. What values do you see ?

2. Also post the frequency of the input signal.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: Wind speed counter
PostPosted: Sat Apr 25, 2009 5:42 pm     Reply with quote

snooer wrote:
So I'm using IR and phototransistor...

Your job in software will be made much easier if you put some hysteresis in hardware when detecting the phototransistor. A little noise in the phototransistor can make several logic transitions which you may incorrectly count as separate pulses unless you ensure each pulse of light produces one clean on transition and one clean off transition. Look for comparator circuits with hysteresis.

If you are unable to add hardware hysteresis, then you can do some software debouncing. Look up debouncing algorithms, many of which have been discussed in this and the Microchip forum.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
snooer



Joined: 22 Apr 2009
Posts: 14

View user's profile Send private message

PostPosted: Sun Apr 26, 2009 5:53 am     Reply with quote

Yes I was thinking about this but so far the problem is not in hardware design. The problem is all about timer1. I still can't find the problem why I can't get 1 second when I'm using 1 Hz in input signal. Using Comparator difference will be converted logical 1 and more clear signal but so far I'm testing on virtual mode so.
snooer



Joined: 22 Apr 2009
Posts: 14

View user's profile Send private message

PostPosted: Sun Apr 26, 2009 8:18 am     Reply with quote

So is it possible to count how much time passed between timer start and stop? Converting result in seconds? Or counting frequency?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 26, 2009 11:49 am     Reply with quote

Quote:

#use delay(clock=20000000)

setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);

I still can't find the problem why I can't get 1 second when I'm using 1 Hz in input signal.

Read the data sheet for the 16F877A.

Timer1 is clocked by Fosc/4, divided by the Timer1 Prescaler.
With your 20 MHz clock, this becomes 5 MHz / 8, which is 625 KHz.
This means in one second, there are 625000 clocks applied to the Timer.
Timer1 is a 16-bit counter, which can count up to 65535. So, it will count
up to its maximum value in about 1/10 of a second. It can't possibly
count up to 1 second. The clock is too fast.

You could add a Timer1 interrupt routine and increment a global byte
variable inside the interrupt routine to extend Timer1 to 24-bits. Then
you would have enough resolution to count a 1 Hz input signal.
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