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

Linear actuator - Sinusoidal motion

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



Joined: 10 Nov 2005
Posts: 11

View user's profile Send private message

Linear actuator - Sinusoidal motion
PostPosted: Tue Jul 31, 2007 9:06 am     Reply with quote

Hi, I'm using a linear stepper motor (stepper motor coupled to a lead screw) to drive a certain load and everything is working fine, however I'm getting a triangular wave when I am really interested in a sinusoidal pattern. Right now the pattern is doing different displacements per time (but the time is limited to around 1 second). So I'm basically making the motor take 350 steps (which gives me a displacement of 1 mm) in one sec, and then it goes reverse, but this gives me a triangular wave. Is there any routine available or easily implemented so that I can have the motor take a series of faster single steps in order to approach a sinusoidal wave? Thanks in advance.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 31, 2007 11:31 am     Reply with quote

Look at the various CCS examples that use a lookup table to generate
a sine function:
c:\program files\picc\examples\ex_usb_scope.c
c:\program files\picc\examples\ex_dtmf.c
c:\program files\picc\examples\ex_sine.c
misaeldv



Joined: 10 Nov 2005
Posts: 11

View user's profile Send private message

PostPosted: Wed Sep 12, 2007 7:40 pm     Reply with quote

Ok, I finally got it to approximate a sinusoid, however my current test code is giving me some problem which I cannot reason out. Basically the curve going down is just the opposite of the one up, so I decided to make a lookup table with only half of the values that I need for the one going up, then I have a loop that calls values from 0-14 (forward), then another loop calling values from 14-0, but somehow that second loop does not drive my motor. I know for a fact that it is running thru the loop because it goes up, then it delays for the amount of time it should be going down, then it goes up again. Here is the code that currently does work (i.e. it only goes up and down). However I have four lookup tables instead of just two.

Code:

#include <16F874A.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode FOR ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES BROWNOUT                 //Reset when brownout detected
#use delay(clock=10000000)
      #use fast_io (A)
      #use fast_io (B)
      #include <math.h>
      #define RAND_MAX 1000 //Rand_max needs to be defined before stdlib.h is inserted
      #include <stdlib.h>     
     
      INT16 i, index, index2, steps, delay;
     
      INT16  CONST delay_default[15] = {
1219, 1233, 1261, 1304, 1367, 1452, 1567, 1722, 1935, 2236, 2683, 3399, 4706, 7786, 23274};

      INT16  CONST steps_default[15] = {
41, 41, 40, 38, 37, 34, 32, 29, 26, 22, 19, 15, 11, 6, 2};

      INT16  CONST delay_default2[15] = {
23274, 7786, 4706, 3399, 2683, 2236, 1935, 1722, 1567, 1452, 1367, 1304, 1261, 1233, 1219};

      INT16  CONST steps_default2[15] = {
2, 6, 11, 15, 19, 22, 26, 29, 32, 34, 37, 38, 40, 41, 41};


/*INT16  CONST sin_default[15] [2] = {
1219, 1233, 1261, 1304, 1367, 1452, 1567, 1722, 1935, 2236, 2683, 3399, 4706, 7786, 23274,
41, 41, 40, 38, 37, 34, 32, 29, 26, 22, 19, 15, 11, 6, 2
};*/

     
           VOID move (INT16 delay, INT16 steps)
     {
           //Motor motion (forward and reverse)
           FOR (i = 0; i <= steps; ++i)
           {
           //Pin B2 provides the clock (f = 1/T)
           //T = 2 * delay
           output_high (PIN_B2);
           delay_us (delay);
           output_low (PIN_B2);
           delay_us (delay);
           } //end FOR CW

     }//end move
       
      VOID main ()
     {
        setup_adc_ports (NO_ANALOGS);
        setup_adc (ADC_OFF);
        setup_psp (PSP_DISABLED);
        setup_spi (FALSE);
        setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_1);
        setup_timer_1 (T1_DISABLED);
        setup_timer_2 (T2_DISABLED, 0, 1);
        setup_comparator (NC_NC_NC_NC);
        setup_vref (FALSE);
       
        //.0254 mm / step
        // TODO: USER CODE!!
        set_tris_a (0xFF); //sets complete port A as inputs (A0 - A5)
        set_tris_b (0x00); //Makes port b7 - b0 function as outputs
        output_b (0x00); //Makes all of port B outputs low       
       
        output_high (PIN_B5); //Enables the L297 stepper driver chip
        output_high (PIN_B6); //Selects current control to act on ABCD lines, instead of inhibit lines
        output_high (PIN_B1); //Selects half step operation
        output_high (PIN_B0); //Pulls reset input high so driver does not reset by mistake
       
                WHILE (true)
        {
           
           IF (input (PIN_A0))
           {           
                       //---------------Going up----------------------
            output_high (PIN_B4); //selects CW rotation

            for(index=0; index<=14; ++index)
            {
            move(delay_default[index], steps_default[index]);
            }
           
           
            //---------------Going down-----------------------
            output_low (PIN_B4); //selects CCW rotation
           
            for(index2=0; index2<=14; ++index2)
            {
            move(delay_default2[index2], steps_default2[index2]);
            }         
           
           
            //--------------Dead Time-------------------------
            delay_ms (2000);           
           
           }//end if
           
        } //end while       
               
     }//end main
     



What I would like, and tried but did not work is the following


Code:

                       //---------------Going up----------------------
            output_high (PIN_B4); //selects CW rotation

            for(index=0; index<=14; ++index)
            {
            move(delay_default[index], steps_default[index]);
            }
           
           
            //---------------Going down-----------------------
            output_low (PIN_B4); //selects CCW rotation
           
            for(index2=14; index2>=0; --index2)
            {
            move(delay_default[index2], steps_default[index2]);
            }         
           


However the above section of code does not move the motor in the downward direction (second loop).

Am I violating any basic rules or something?
Thanks
libor



Joined: 14 Dec 2004
Posts: 288
Location: Hungary

View user's profile Send private message

PostPosted: Thu Sep 13, 2007 3:56 am     Reply with quote

The index2>=0 condition in your second loop is always true. This loop never ends.
misaeldv



Joined: 10 Nov 2005
Posts: 11

View user's profile Send private message

PostPosted: Thu Sep 13, 2007 7:21 am     Reply with quote

So what you're saying is that I am not allowed to decrement, or that int16 doesn't go negative?
Thanks
kevcon



Joined: 21 Feb 2007
Posts: 142
Location: Michigan, USA

View user's profile Send private message

PostPosted: Thu Sep 13, 2007 7:39 am     Reply with quote

Since index2 is unsigned the answer is no.

but if you change your loop to.

Code:

for(index2=14; index2 != 0xFFFF ; --index2)


it should work
misaeldv



Joined: 10 Nov 2005
Posts: 11

View user's profile Send private message

PostPosted: Thu Sep 13, 2007 9:14 am     Reply with quote

Thanks, just a couple more questions to clarify my issue. I just looked in the compiler help and it says that by default the only signed type is long, but that int16 can also be declared as signed if declared as followed

Code:

signed int16 index2;


So, if I declared my variable as above it should do it, right? I would try it, but do not have my motor with me right now.

Thanks
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