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

PIC18F452 PULSE Counter
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 28, 2010 5:09 pm     Reply with quote

You didn't say what model number you have. If you have Model 906,
the sensor data sheet says:
Code:

Wiring code..........906/907:

Red = Supply
Clear = Common
Black = Signal

The Red wire goes to +12v. The Black wire goes to the PIC (and has
the pull-up resistor on it). The Clear wire goes to the ground connection
on your +12v power supply and also it goes to the ground connection on
the PIC board.
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

PostPosted: Thu Oct 28, 2010 5:12 pm     Reply with quote

Sounds good. That is how I had it connected. Just need to add the pull up resistor. Thanks. I will try this out when I get back to the lab.

www.tinyurl.com/gtsavseniordesign --> GA Tech Senior Design Project Page
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

Program Code
PostPosted: Mon Nov 08, 2010 5:42 pm     Reply with quote

I connected everything, and I am getting an accurate signal (high and low sine wave). However, my code recognizing the pulse changes. Is there something wrong with my code? The timer0 counts elapsed time, and timer1 should count pulses. Timer0 accurately flashes the led every second, however, the pulse count/sec never changes.
Code:

#include <18F452.H>
#use delay(clock=20000000) // Frequency set at 20Mhz
#include <flex_lcd.c>
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT,PUT
#use standard_io(b)

// # of Overflows in 1 sec Calculation //
// ----------------------------------------
// 1/((1/(10000000/4)) *256 * 256) = 38.14 overflows in 1 sec
// FCPU = 10Mhz/4

// Time Period = 1/(10Mhz/4)
// Prescaler Period = Timer Period * 256
// Overflow Period = Prescaler Period * 256

// 1/Overflow Period = # overflows in 1 sec
//-----------------------------------------

// SENSOR -> PIN_C0
#define LED1 PIN_a3
int count=0;
int timer_value;
#INT_TIMER0
void timer_irg(){
   count++;
   timer_value = get_timer1();
   //printf(lcd_putc, "\fCount: %d ", timer_value);
   if (count == 38){ // 38 overflows per second
      count = 0; // reset timer0 overflow counter
      set_timer1(0); // reset timer1 counter
      output_toggle(LED1); // turn on/off LED every second
      printf(lcd_putc, "\f%d /sec", timer_value);
   }
}
      

void main(){
   int counter;
   lcd_init();
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); // Set up timer 1 (counter);
   set_timer1(0); // Reset timer1 counter
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT); // Set up timer0 to use internal clock, 8bit mode, and prescale of 256;
   set_timer0(0); // Reset timer0
   enable_interrupts(INT_TIMER0); // interrupt on every timer0 overflow
   enable_interrupts(GLOBAL);
   for(;;){
   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 08, 2010 6:41 pm     Reply with quote

1. What's the frequency of the pulses coming from the sensor ?

2. What are the voltage levels (high and low) of the pulses, as measured
with an oscilloscope ?

3. Are the pulses really a sinewave, or are they rectangular waveforms ?
Is it like the upper waveform in the link below, which has sharp edges,
or is it like the lower one, with slow edges ?
http://phoenix.phys.clemson.edu/labs/223/rc/longperiod.gif

4. What is resistance value of the pull-up resistor on the output of the sensor ?

5. What is the version of your compiler ? It's given at the top of the .LST
file, which will be in your project directory after a successful compilation.
It's a 4 digit number (only), in this format: x.xxx
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

PostPosted: Tue Nov 09, 2010 6:17 pm     Reply with quote

1. What's the frequency of the pulses coming from the sensor ?

I can answer this tomorrow

2. What are the voltage levels (high and low) of the pulses, as measured
with an oscilloscope ?

I can answer this tomorrow

3. Are the pulses really a sinewave, or are they rectangular waveforms ?
Is it like the upper waveform in the link below, which has sharp edges,
or is it like the lower one, with slow edges ?
http://phoenix.phys.clemson.edu/labs/223/rc/longperiod.gif

The pulses are really a sine wave

4. What is resistance value of the pull-up resistor on the output of the sensor ?

1 kHz

5. What is the version of your compiler ? It's given at the top of the .LST
file, which will be in your project directory after a successful compilation.
It's a 4 digit number (only), in this format: x.xxx[/quote]

3.084

** Do you see any problem with my CCS code? Particularly the timer1 code.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 09, 2010 6:54 pm     Reply with quote

I can't really do anything until I know what the waveform really looks like
and what the voltage levels are. Example of sine wave:
http://ocw.mit.edu/ans7870/SP/SP.764/imagegallery/lab5/images/3.jpg
That signal goes above and below ground. Presumably your signal
goes from 0v to 5v, but I need a confirmation.
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

PostPosted: Wed Nov 10, 2010 5:02 pm     Reply with quote

My results are at the link below. is this enough information to help me? Images are included.

http://dl.dropbox.com/u/10133862/Sensor%20Readings.docx
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 10, 2010 5:38 pm     Reply with quote

I don't see any digital signals. It looks like steady state low level noise.
Where are the 0v to +5v digital pulses ? I don't see any.

Look at the oscilloscope waveforms in the section where he says it's
typical of Hall Effect sensors. It shows pulses:
http://www.molla.org/DIY-CDI/DIY-CDI-Trigger/SC-DIY-TCI-Trigger.htm


Last edited by PCM programmer on Wed Nov 10, 2010 5:42 pm; edited 1 time in total
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

PostPosted: Wed Nov 10, 2010 5:41 pm     Reply with quote

The pulses change whenever a magnet polarity is switched. We didn't have a constant pulse going, so the screenshots are from a positive polarity magnet, then the next screenshot is the signal when the polarity is switched.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 10, 2010 5:49 pm     Reply with quote

My advice is, get rid of the Hall Effect sensor for now. Set it aside.
Get a function generator. Set it to whatever pulse repetition rate is
expected from the sensor, let's say 100 Hz, with 50% duty cycle.
Set the output voltage levels to be +5v CMOS levels (0v to 5v).
Apply this signal to your PIC board. Does it now work ?

If not, get rid of most of your code, including all interrupt code.
Setup Timer1 for external input, and create a continuous while() loop
in main(), and set Timer1 to 0, then wait some suitable number of
seconds, and read Timer1 (use CCS functions for all of this), and
display it with printf. In other words, get down to basics, and prove
that it can work with a known-good input, and without interrupts.
Prove that Timer1 can be made to count pulses, and that you can
read and display the count.

If you can get that working, then substitute the Hall Effect sensor
for the Function Generator. Make it work with that.

Then go back to the Function Generator and change the code to use
interrupts. Make that work, if possible.

Finally, try it with the Hall Effect sensor.
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

PostPosted: Sat Nov 20, 2010 7:21 pm     Reply with quote

Thanks for your help. We decided to use PortB Interrupts instead, and were successfully able to count the number of pulses, and display our miles/hour. I don't know why our Timer1 counter would not work, but our alternative works nonetheless. Below is my code. Thanks a lot.
Code:

#include <18F452.H>
#use delay(clock=20000000) // Frequency set at 20Mhz
#include <flex_lcd.c>
#include <string.h>
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT,PUT
#use standard_io(b)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, parity=n, stream=SERIAL, bits=8)

// # of Overflows in 1 sec Calculation //
// ----------------------------------------
// 1/((1/(10000000/4)) *256 * 256) = 38.14 overflows in 1 sec
// FCPU = 10Mhz/4

// Time Period = 1/(10Mhz/4)
// Prescaler Period = Timer Period * 256
// Overflow Period = Prescaler Period * 256

// 1/Overflow Period = # overflows in 1 sec
//-----------------------------------------

// SENSOR -> PIN_C0
// Interrupt Pin -> PIN_B4

// Speed Sensor & LEDS
#define LED1 PIN_A3
#define LED2 PIN_A2
#define SENSOR_PIN PIN_B4
#define MAGNETS 4

// H Bridge
#define ENABLE PIN_B0
#define BRAKE1 PIN_B5
#define BRAKE2 PIN_B3
#define GAS1 PIN_B2
#define GAS2 PIN_B1

// Misc Variables
int overflow=0;
float count = 0;
float speed;
int last;
char color;

#INT_TIMER0 // Timer 0 Interrupt Function
void timer_irg(){
   overflow++;
   if (overflow == 38){ // 38 overflows per second
      overflow = 0; // reset timer0 overflow counter
      output_toggle(LED1); // turn on/off LED1 every second
      speed = (7.93*count*3600)/(MAGNETS*10*10*10*10);
      printf(lcd_putc, "\f%f", speed);
      printf(lcd_putc, "\nmph");
      count = 0; // reset magnet count
   }
}

#INT_rb // PortB Interrupt Function
void magnet_count(){
   if (input(SENSOR_PIN) != last){
      count=count+1;
      output_toggle(LED2); // turn on/off LED2 every magnet oscillation
      last = input(SENSOR_PIN);
   }
}

#int_rda // Serial Interrupt Function
void handle_data(void) {
   if (kbhit(SERIAL)){
      color=fgetc(SERIAL); // RS232 Serial Character Received
   }
}

void main(){
   speed = 0;
   char green[] = "GRE";
   char red[] = "RED";
   char blue[] = "BLU";
   last = input(SENSOR_PIN);
   lcd_init(); // Initialize LCD Screen
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT); // Set up timer0 to use internal clock, 8bit mode, and prescale of 256;
   set_timer0(0); // Reset timer0
   enable_interrupts(INT_TIMER0); // interrupt on every timer0 overflow   
   enable_interrupts(int_rb); // interrupt on every sensor pulse
   enable_interrupts(INT_RDA); // interrupt on every serial connect change
   enable_interrupts(GLOBAL); // Global Interrupts have to always be enabled

   for(;;){
      if (strcmp(color,red) == 0){
         printf(lcd_putc,  "\fRed");
      }
      else if (strcmp(color,blue) == 0){
         printf(lcd_putc, "\fBlue");
      }
      else if (strcmp(color,green) == 0){
         printf(lcd_putc, "\fGreen");
      }
      else{
         continue;
      }
   }
}
stijn023



Joined: 28 Sep 2010
Posts: 49

View user's profile Send private message

PostPosted: Wed Mar 09, 2011 3:09 pm     Reply with quote

On which pin is your sensor connected because here stands
Code:
// SENSOR -> PIN_C0
.

Thanks for the help
rgraham8



Joined: 28 Oct 2010
Posts: 16

View user's profile Send private message

Sensor Pin
PostPosted: Wed Mar 09, 2011 3:41 pm     Reply with quote

It should have said Pin_B4. The project has been completed. Here is the final code we used utilizing the port b interrupts. The project page with videos is here: http://www.ece.gatech.edu/academic/courses/ece4007/10fall/ECE4007GTS/em1/
Code:

#include <18F452.H>
#use delay(clock=10000000) // Frequency set at 10Mhz
#include <flex_lcd.c>
#include <string.h>
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT,PUT
#use standard_io(b)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=n, stream=SERIAL, bits=8)

// Speed Sensor & LEDS & Pushbutton
#define LED1 PIN_A3
#define LED2 PIN_A2
#define LED3 PIN_A1
#define LED4 PIN_A4 // LOW to turn on
#define SENSOR_PIN PIN_B4
#define MAGNETS 8
#define PUSHBUTTON1 PIN_D3

// H Bridge
#define ENABLE PIN_B0 // HIGH
#define BRAKE1 PIN_B5
#define BRAKE2 PIN_B3   // LOW for extend
#define GAS1 PIN_B2 
#define GAS2 PIN_B1  // LOW for extend

// Misc Variables
int overflow;
float count;
float speed;
int last;
int color;
char color2;
int seconds;
int minute;
int half_second;
signed int gas_position;
int counter;
int counter2;
int counter3;
int last_color;
#INT_TIMER0 // Timer 0 Interrupt Function
void timer_irg(){
   overflow++;
   if ((overflow % 19) == 0){ // 19 overflow = 1/2 sec
      half_second++;
      speed = (2*7.93*count*3600)/(MAGNETS*10*10*10*10);
      printf(lcd_putc, "\f%f/%d", speed,gas_position);
      if (color == 114){
         printf(lcd_putc, "\nRED");
      }
      else if (color == 98){
         printf(lcd_putc, "\nBLUE");
      }
      else if (color == 103){
         printf(lcd_putc, "\nGREEN");
      }
      else if (color == 99){
         printf(lcd_putc, "\nBLACK");
      }
      else{
         printf(lcd_putc, "\nN/A");
      }
      count = 0;
   }
   if (overflow == 38){ // 38 overflows per second
      seconds++;
      overflow = 0; // reset timer0 overflow counter
      output_toggle(LED1); // turn on/off LED1 every second

      if ((seconds % 60) == 0){
         minute++;
      }
   }
}

#INT_rb // PortB Interrupt Function
void magnet_count(){
   if (input(SENSOR_PIN) != last){
      count=count+1;
      output_toggle(LED2); // turn on/off LED2 every magnet oscillation
      last = input(SENSOR_PIN);
   }
}

#int_rda // Serial Interrupt Function
void handle_data(void) {
   output_toggle(LED3);
   color2=fgetc(SERIAL); // RS232 Serial Character Received
   if (color2 == 114){ // RED 'r'
      printf(lcd_putc,  "\fSTOP");
      printf(lcd_putc,  "\nBRAKE");
      color = 114;
   }
   else if (color2 == 98){ // BLUE 'b'
      printf(lcd_putc,  "\f10MPH");
      printf(lcd_putc,  "\nGAS");
      color = 98;
   }
   else if (color2 == 103){ // GREEN 'g'
      printf(lcd_putc,  "\f5MPH");
      printf(lcd_putc,  "\nGAS");
      color = 103;
   }
   else if (color2 == 99){ // BLACK 'c'
      printf(lcd_putc,  "\f13MPH");
      printf(lcd_putc,  "\nGAS");
      color = 99;
   }
}

void main(){
   
   // Important Variables
   lcd_init();
   printf(lcd_putc, "\fPADS");
   printf(lcd_putc, "\nMACH 1.5");
   delay_ms(2000);
   printf(lcd_putc, "\fAaron B.");
   printf(lcd_putc, "\nRobert G.");
   delay_ms(2000);
   printf(lcd_putc, "\fTylor P.");
   printf(lcd_putc, "\nLamar T.");
   delay_ms(2000);
   
   output_high(ENABLE);
   last = input(SENSOR_PIN);
   overflow=0;
   count = 0;
   speed=0;
   color=0;
   seconds=0;
   minute=0;
   half_second=0;
   gas_position=0;

   // MISC Variables
   int time;
    last_color=0;
   counter = 0;
   counter2 = 0;
   counter3 = 0;
   
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT); // Set up timer0 to use internal clock, 8bit mode, and prescale of 256;
   set_timer0(0); // Reset timer0
   enable_interrupts(INT_TIMER0); // interrupt on every timer0 overflow   
   enable_interrupts(int_rb); // interrupt on every sensor pulse
   enable_interrupts(INT_RDA); // interrupt on every serial connect change
   enable_interrupts(GLOBAL); // Global Interrupts have to always be enabled

   for(;;){
      if (input(PUSHBUTTON1) == 0){ // Program Kill Switch
         output_low(pin_a4);
         disable_interrupts(INT_TIMER0);
         disable_interrupts(int_rb);
         disable_interrupts(INT_RDA);
         printf(lcd_putc,  "\fQUIT");
         fputs("QUIT",SERIAL);
         output_high(BRAKE2);
         output_low(BRAKE1);
         output_high(GAS2);
         output_low(GAS1);      
         break;         
      }
         
      if (color == 114){ // RED STOP
         if (last_color == 1){
            continue;
         }
         else if (speed != 0){
            time = seconds;
            while (((seconds - time) <= 6)){
               output_high(BRAKE1);
               output_low(BRAKE2);
               output_high(GAS2);
               output_low(GAS1);
            }
            gas_position = 0;
            last_color = 1;
            output_low(BRAKE1);
            output_low(BRAKE2);
         }               
      }

      else if (color == 98){ // BLUE 10 +- 1
         last_color = 2;
         output_high(BRAKE2);
         output_low(BRAKE1);
         if (speed == 0 && gas_position == 0){
            counter = seconds;
            output_high(GAS1);
            output_low(GAS2);
            while(seconds - counter <6){   
            }
            output_low(GAS1);
            output_low(GAS2);
            gas_position = 6;
         }
         else if (speed > 11){
            counter2 = gas_position;
            if ((gas_position -1 < 0)){
            }
            else{
               output_high(GAS2);
               output_low(GAS1);
               gas_position = counter2 - 1;
               counter = seconds;
               while (seconds-counter<1){   
               }
            }
            output_low(GAS2);
            output_low(GAS1);
            counter = seconds;
            while (seconds - counter <2){      
            }
         }
         else if (speed < 9){
            counter2 = gas_position;
            if ((gas_position +1 > 12)){
            }
            else{   
               output_high(GAS1);
               output_low(GAS2);
               gas_position = counter2 + 1;
               counter = seconds;
               while (seconds-counter<1){
               }
            }      
            output_low(GAS1);
            output_low(GAS2);
            counter = seconds;
            while (seconds - counter <2){   
            }
         }
      }

      else if (color == 103){ // GREEN 5 +- 2
         output_high(BRAKE2);
         output_low(BRAKE1);
         if (speed == 0 && gas_position == 0){
            counter = seconds;
            output_high(GAS1);
            output_low(GAS2);
            while(seconds - counter <4){   
            }
            output_low(GAS1);
            output_low(GAS2);
            gas_position = 4;
            last_color = 3;
         }
         else if (speed > 7){
            counter2 = gas_position;
            
            if (last_color == 4 && gas_position >=5){
               output_high(BRAKE1);
               output_low(BRAKE2);
               output_high(GAS2);
               output_low(GAS1);
               counter = seconds;
               while (seconds-counter<5){   
               }
               gas_position = gas_position -5;
               output_low(BRAKE1);
               output_low(BRAKE2);
               output_low(GAS1);
               output_low(GAS2);
               last_color = 3;
               counter = seconds;
               while (seconds-counter<2){
               }
            }
            
            else if ((gas_position -1 < 0)){
               last_color = 3;
            }
            
            else{
               last_color = 3;
               output_high(GAS2);
               output_low(GAS1);
               gas_position = counter2 - 1;
               counter = seconds;
               while (seconds-counter<1){   
               }
            }
            output_low(GAS2);
            output_low(GAS1);
            counter = seconds;
            while (seconds - counter <2){      
            }
         }
         else if (speed < 4){
            counter2 = gas_position;
            if ((gas_position +1 > 12)){
            }
            else{   
               output_high(GAS1);
               output_low(GAS2);
               gas_position = counter2 + 1;
               counter = seconds;
               while (seconds-counter<1){
               }
            }      
            output_low(GAS1);
            output_low(GAS2);
            counter = seconds;
            while (seconds - counter <2){   
            }
         }
      }

      else if (color == 99){ // BLACK 13 +- 2
         last_color = 4;
         output_high(BRAKE2);
         output_low(BRAKE1);
         if (speed == 0 && gas_position == 0){
            counter = seconds;
            output_high(GAS1);
            output_low(GAS2);
            while(seconds - counter <8){   
            }
            output_low(GAS1);
            output_low(GAS2);
            gas_position = 8;
         }
         else if (speed > 15){
            counter2 = gas_position;
            if ((gas_position -1 < 0)){
            }
            else{
               output_high(GAS2);
               output_low(GAS1);
               gas_position = counter2 - 1;
               counter = seconds;
               while (seconds-counter<1){   
               }
            }
            output_low(GAS2);
            output_low(GAS1);
            counter = seconds;
            while (seconds - counter <2){      
            }
         }
         else if (speed < 11){
            counter2 = gas_position;
            if ((gas_position +1 > 12)){
            }
            else{   
               output_high(GAS1);
               output_low(GAS2);
               gas_position = counter2 + 1;
               counter = seconds;
               while (seconds-counter<1){
               }
            }      
            output_low(GAS1);
            output_low(GAS2);
            counter = seconds;
            while (seconds - counter <2){   
            }
         }
      }

      else{
         continue;
      }
   }
}
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 Previous  1, 2
Page 2 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