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

speed of the DC motor

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



Joined: 25 Nov 2007
Posts: 48

View user's profile Send private message

speed of the DC motor
PostPosted: Sat Dec 01, 2007 8:28 am     Reply with quote

Hi All,
I have a question about the measuring the speed of the DC motor. I am supposed to dsplay the speed of the DC motor on the LCD screen. However, I do not know any formula about calculating the speed of the motor in spite of making research in the google.
Would you please help me ?

Thanks
Ormiga
Guest







PostPosted: Sat Dec 01, 2007 9:11 am     Reply with quote

mcad,

actually you don't have to know any formula. Try to put (if it's pssible) an encoder on the motor, then count the pulses. It's very simple. Wink
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sat Dec 01, 2007 10:22 am     Reply with quote

There are many ways to determine the RPM, it depends of the magnitude of the speed to
be measured, of the required precision and the amount of sensors.
One easy way to implement is using a sensor with 1 pulse per turn (optical, reflective,
magnetic, capacitive, etc) Then you should setup one internal timer to kick every second
and measure the revolutions in this 1 second window, then multiplying the result x 60, you will
get the RPM value to show in the display.
The bigger the amount of pulses per turn, the bigger the obtained precision.


Humberto
mcad



Joined: 25 Nov 2007
Posts: 48

View user's profile Send private message

PostPosted: Sat Dec 01, 2007 11:43 am     Reply with quote

Thank you sir for your clarifications.
But, could you please suggest me a code snippet too ? I understand what you mean but can not implement it with code.

Thanks
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sat Dec 01, 2007 3:15 pm     Reply with quote

Code:

//------------------------------------------------------------------------------
#include <16F628.h>
#device *=16

#FUSES NOWDT      //No Watch Dog Timer
#FUSES XT         //Crystal osc <= 4mhz
#FUSES PUT        //Power Up Timer
#FUSES NOPROTECT  //Code not protected from reading
#FUSES BROWNOUT   //Reset when brownout detected
#FUSES MCLR       //Master Clear pin enabled
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD      //No EE protection

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8)

// Global Variables
unsigned int  loops, meas_done;
unsigned long RPM, sensor_pulses;


#int_EXT
void  EXT_isr(void)
{
  if(!meas_done)
    {sensor_pulses++; } // Sensor pulses (TTL level) must arrieve at PIN_B0
}                     

#int_TIMER2
void  TIMER2_isr(void)
{
  if(loops)
    {loops--;}
  else
    {meas_done=true; }   
}

void start_measurement()
{
   meas_done=false;
   loops = 20;         // 50ms * 20 = 1000ms
                       // This is the measurement window time
   set_timer2(0);       
   enable_interrupts(INT_TIMER2);// To create a measurement window
   enable_interrupts(INT_EXT);   // Generate an interrupt every pulse
}                                // comming from the sensor         


void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_wdt(WDT_288MS);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,194,16);// overflow aprox every 50ms
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   ext_int_edge( H_TO_L );   
   enable_interrupts(GLOBAL);
         
   while(1)
      {
       start_measurement();
     
       do
         {
          //........
          //aprox 1000ms to do other stuff ! 
          //........
         }while(!meas_done);
       
       disable_interrupts(INT_TIMER2);
       disable_interrupts(INT_EXT);
       RPM = sensor_pulses * 60;
       sensor_pulses = 0;
     
       printf("RPM %04lu", RPM);
      }
}

//------------------------------------------------------------------------------


Code compiled but not tested, I can´t test it until Monday.


Humberto
mcad



Joined: 25 Nov 2007
Posts: 48

View user's profile Send private message

PostPosted: Sat Dec 01, 2007 3:20 pm     Reply with quote

Hi Sir,
Thanks a lot for your clarifications.

Regards
mcad



Joined: 25 Nov 2007
Posts: 48

View user's profile Send private message

PostPosted: Sat Dec 01, 2007 4:52 pm     Reply with quote

Sir,
I have some question to you.
My optical sensor is PIN B7, so how can I ensure that when the PIN B7 goes to high, the interrput function works ? Should I do anything extra for this action ?
Another question is that I am using the timer 2 for adjusting the duty cycle in DC motor.
Code:
  setup_timer_2(T2_DIV_BY_4, 255, 1);


So this means that the timer 2 resets after 256 clock cycles. For this reason, I should determine how many times I make timer2 reset to catch one second. Of course, this can be done with the interrupts as you did.
My question is that do I need to use any other timer such as timer0 or timer3 ?
And, a last, I change the clock cycle regularly(as I adjust the duty cycle), so I got confused about determining the 1 second interval.

Thanks
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

rpm
PostPosted: Sat Dec 01, 2007 5:09 pm     Reply with quote

I am measuring rpm as bellow and it works. For higher or lower resolution change the timer prescaller value:
//to capture the rpm, timer1 with prescaller 1:8 to get 1us resolution
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
//(can be other timer)
//with ccp1 capture unit (can be ccp2),
setup_ccp2(CCP_CAPTURE_FE); can be RE
//timer1 increment is 1us
//timer1 overflow is 65.536ms
//1,000ms/65.536=15.259 RPS (rate per second)
//15.259*60=915.5 RPM minimum
//10,000 limiting RPM maximum
//(1,000,000us/6,000)*60=10,000 RPM
//if CCP_1<6,000, rpmtime=6,000
//the rpm calculations are made in
//the main to avoid the compiler to make delays during interrupts
while(1)
{
//calculations
}
If you will calculate just ones per second and no every pulse, your display will not be real time
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

frequency
PostPosted: Sat Dec 01, 2007 5:13 pm     Reply with quote

I forget to mention
1us from timer1/pre 1:8 if frequency 32Mhz (PC=125ns)
for other controllers speed, have to calculate accordingly
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sat Dec 01, 2007 7:45 pm     Reply with quote

I would like that you take in mind that I wrote this code for you, trying to give a push in
your project, keeping the code more didactic than efficient. By no way is the only nor
the best way to do an RPM measurement, but is very easy to debug and understand.

Quote:

My optical sensor is PIN B7, so how can I ensure that when the PIN B7 goes to high,
the interrput function works ? Should I do anything extra for this action ?

1) You never mentioned what type of sensor you are using.
2) We do not have any hardware detail of your project.
3) We do not know what MCU are you using.
4) We do not know what is the expected Max RPM value.
5) The posted code should work only if the incoming pulses trigger the External Interrupt pin.


Quote:

My question is that do I need to use any other timer such as timer0 or timer3 ?

The posted code needs a 1000ms time-window to acquire pulses, you can generate such
period using any internal timer module of the MCU.

Quote:

And, a last, I change the clock cycle regularly(as I adjust the duty cycle), so I got confused
about determining the 1 second interval.

The time-base is generated by internal timers interrupts, hence is inmune to cycle changes.


Humberto
mcad



Joined: 25 Nov 2007
Posts: 48

View user's profile Send private message

PostPosted: Sun Dec 02, 2007 11:55 am     Reply with quote

Hi Sir,
I sm using optical sensor. So, does this mean that I should make some shanges on the code about this ?

And also, do I have to use the below code ? If yes, would you please tell me why ?

Code:
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   ext_int_edge( H_TO_L ); 

Code:

 set_timer2(0);


Thanks
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sun Dec 02, 2007 6:12 pm     Reply with quote

mcad,

I like to help you, but I don´t want to do your job. Cool

Im going to answer your question only for clarifications.
Quote:

I sm using optical sensor. So, does this mean that I should make some shanges on the code about this ?

An optical sensor is ok, whenever its output swing between 0-5V.
It is clearly in the code that is expecting the sensor pulses in an External Interrupt pin.

Quote:

And also, do I have to use the below code ? If yes, would you please tell me why ?

These are the initialization setup for the MCU I used in the example.

Pls download the PIC16F62x Datasheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/40300C.pdf

Read Chapter 9.0 COMPARATOR MODULE

Quote:

setup_comparator(NC_NC_NC_NC);

This line tell the compiler to NoConnect the PORTA shared pins to the built-in Comparator Module.
This is only applicable to the MCU used in the example, you should know if it is applicable
in your application.

Read Chapter 10.0 VOLTAGE REFERENCE MODULE
Quote:

setup_vref(FALSE);

This line tell the compiler to NoConect the PORTA Pin2 to the internal reference voltage.
This pin is shared for multiple uses. Also keep the VREF internal module disconnected to
minimize current consumption.

Read Chapter 14.6.1 RB0/INT INTERRUPT
Quote:

ext_int_edge( H_TO_L );

The external interrupt is edge triggered. This line tell the compiler how to setup the OPTION
register to generate an interrupt only in a High-TO-Low transition of the external interrupt pin.

Pls read the CCS Compiler Manual.


Humberto
mcad



Joined: 25 Nov 2007
Posts: 48

View user's profile Send private message

PostPosted: Mon Dec 03, 2007 5:00 am     Reply with quote

Thank you sir, for your all clarifications.

Regards
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