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

error in stepper code

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



Joined: 31 Mar 2008
Posts: 29
Location: Mumbai, India

View user's profile Send private message Visit poster's website

error in stepper code
PostPosted: Mon May 12, 2008 9:26 am     Reply with quote

Hello,
Its about microstepping control of stepper motor.. but there's some error and i can not seem to get out of the cycle.. I'm not really good at logic.. please help. full step angle 4 degrees. microstepping it by 1/16 PWM logic on full step.
Code:

#if defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#include <input.c>
/*//int i;
#define button_cnt1_pressed output_high(PIN_B0)
#define button_cnt2_pressed output_high(PIN_B1)
#define forward_1 output_high(PIN_D0)
#define reverse_1 output_low(PIN_D0)
#define forward_2 output_high(PIN_D1)
#define reverse_2 output_low(PIN_D1)
halfstepping(void);
fullstepping(void);
reversestepping(void);*/
#define led_on output_low(PIN_A2);
void main()
{
   int i, full_step, pwm[8] = {50,95,140,177.5,207.5,232.5,245,250};
 
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   set_tris_b(0);
   set_tris_a(0);
   output_high(PIN_B3);
   output_high(PIN_B2);
   setup_timer_2(T2_DIV_BY_1, 250, 1);
   full_step = 0;
   while(full_step != 1)
   {
      set_pwm1_duty(250);
      for(i=0;i<8;i++)
      {
      set_pwm2_duty(pwm[i]);
      delay_us(1000);
      }
      set_pwm2_duty(250);
      for(i=7;i>=0;i--)  \\Getting stuck here..
      {
      set_pwm1_duty(pwm[i]);
      delay_us(1000);
      }
       
      /*
      output_low(PIN_B3);
     
      set_pwm2_duty(250);
      for(i=0;i<8;i++)
      {
      set_pwm1_duty(pwm[i]);
      delay_us(1000);
      }
      set_pwm1_duty(250);
      for(i=7;i>=0;i--)
      {
      set_pwm2_duty(pwm[i]);
      delay_us(1000);
      }
      */
      full_step++;
      led_on;
   }
   
     
}
   
}*/


RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: error in stepper code
PostPosted: Mon May 12, 2008 12:33 pm     Reply with quote

ferrousduke wrote:
..but there's some error and i can not seem to get out of the cycle..

Please explain what cycle you can't get out of.

Robert Scott
Real-Time Specialties
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 12, 2008 2:10 pm     Reply with quote

Code:
      for(i=7;i>=0;i--)  \\Getting stuck here..
In CCS the integers are unsigned by default, this means 'i' will never become smaller than 0 and hence you don't get out of the loop.
A possible solution is:
Code:
      for(i=8;i>0;i--)  \\Getting stuck here..
      {
      set_pwm1_duty(pwm[i-1]);     // note the '-1'
      delay_us(1000);
      }


Apply the same change to the other loop as well.

Code:
   int i, full_step, pwm[8] = {50,95,140,177.5,207.5,232.5,245,250};
You can not use floating point numbers in an integer array. The values will be truncated, so 177.5 becomes 177, 207.5 becomes 207, etc.
ferrousduke



Joined: 31 Mar 2008
Posts: 29
Location: Mumbai, India

View user's profile Send private message Visit poster's website

PostPosted: Mon May 12, 2008 3:05 pm     Reply with quote

thanks ckiestra.. I tried the correction.. but some strange problem is coming up.. before my motor turned a full step in simulation. i.e. 4 degrees.. After the correction in code, it stops at 3.5 degrees..
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 12, 2008 5:45 pm     Reply with quote

Sorry, I don't know anything about microstepping and can't help you. Maybe someone else can jump in?
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Tue May 13, 2008 7:29 am     Reply with quote

ferrousduke wrote:
thanks ckiestra.. I tried the correction.. but some strange problem is coming up.. before my motor turned a full step in simulation. i.e. 4 degrees.. After the correction in code, it stops at 3.5 degrees..

How do you know it stops at 3.5 degrees? It looks to me like your test program goes through 16 microsteps that gradually transition from PWM1=250, PWM2=50 to PWM1=50, PWM2=250. To me that defines one full step. Now if you were to continue on to the next full step you would change the polarity of PWM1 by toggling RB3 and then do another 16 microsteps where you go from PWM1=50, PWM2=250 to PWM1=250, PWM2=50. Then the third full step would be executed by reversing the polarity of PWM2 by toggling RB2, etc. It looks like you are one the right track.

Robert Scott
Real-Time Specialties
ferrousduke



Joined: 31 Mar 2008
Posts: 29
Location: Mumbai, India

View user's profile Send private message Visit poster's website

PostPosted: Tue May 13, 2008 7:47 am     Reply with quote

yup I am planing exactly on what you said. I am using proteus ISIS for simulating the code. I used bipolar stepper motor with step angle 4 degrees.. Now, before the code was corrected, it simulated full step of 4 degrees. but now its coming to 3.5 degrees. the problem was only to get rid of the loop so that I can switch RB3 and go to another full step and so on.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Tue May 13, 2008 9:23 am     Reply with quote

ferrousduke wrote:
yup I am planing exactly on what you said. I am using proteus ISIS for simulating the code. I used bipolar stepper motor with step angle 4 degrees.. Now, before the code was corrected, it simulated full step of 4 degrees. but now its coming to 3.5 degrees. the problem was only to get rid of the loop so that I can switch RB3 and go to another full step and so on.

I still don't understand how you know it is going only 3.5 degrees. Perhaps the simulation is at fault. All I know is, when you run a real motor, it will go through one full step when you do your 16 microsteps.

Robert Scott
Real-Time Specialties
ferrousduke



Joined: 31 Mar 2008
Posts: 29
Location: Mumbai, India

View user's profile Send private message Visit poster's website

PostPosted: Sat May 17, 2008 12:45 pm     Reply with quote

Hello
can you please check whats wrong with the code? If you have proteus ISIS installed on ur comp, I can send the simulation files and source.
regards.
ferrousduke



Joined: 31 Mar 2008
Posts: 29
Location: Mumbai, India

View user's profile Send private message Visit poster's website

PostPosted: Sat May 17, 2008 2:00 pm     Reply with quote

ferrousduke wrote:
Hello
can you please check whats wrong with the code? If you have proteus ISIS installed on ur comp, I can send the simulation files and source.
regards.


Yup I have solved that problem. It was a little bit of sequencing problem. I have encountered one more problem while toggling switch CNT1 and CNT2. Logic seems all ok but code does not work. I'm not good at C. Please help.

code:
Code:
#if defined(__PCH__)
#include <18F4550.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#include <input.c>

/*********************************************************/
/********* ÎÏÐÅÄÅËÅÍÈß ÈÑÏÎËÜÇÓÅÌÛÕ ÍÀÈÌÅÍÎÂÀÍÈÉ *********/
/*********************************************************/

#define led_on output_high(PIN_E0)
#define led_off output_low(PIN_E0)
#define CNT1 PIN_D0
#define CNT2 PIN_D1
void change_polarity(void);
void indicate(void);
void main()
{
   int i, full_step, pwm[8] = {0,50,95,140,177.5,207.5,232.5,245};
 
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   set_tris_d(0);
   output_high(CNT1);
   output_high(CNT2);
   setup_timer_2(T2_DIV_BY_1, 250, 1);
   full_step = 0;
   
   //**ÖÈÊË ÏÎËÍÎÃÎ ØÀÃÀ**
   
   while(full_step != 1)
   {
     
      //****** ÏÅÐÂÛÉ ÏÎËÓØÀÃ *******
     
      set_pwm1_duty(250); //**ÓÑÒÀÍÎÂÊÀ "ØÈÌ 1" ÍÀ 100% ÄÎ ÇÀÂÅÐØÅÍÈß ÏÎËÓØÀÃÀ**
      delay_us(200);
      for(i=1;i<=8;i++)
      {
         //**ÏÎÂÛØÅÍÈÅ ØÈÌ 2**
         set_pwm2_duty(pwm[i-1]);
         delay_us(200);
      }

      //****** ÂÒÎÐÎÉ ÏÎËÓØÀÃ *******
     
      set_pwm2_duty(250); //**ÓÑÒÀÍÎÂÊÀ "ØÈÌ 2" ÍÀ 100% ÄÎ ÇÀÂÅÐØÅÍÈß ÏÎËÍÎÃÎ ØÀÃÀ**
      delay_us(200);
      for(i=8;i>0;i--)
      {
         //**ÏÎÍÈÆÅÍÈÅ ØÈÌ 1**
         set_pwm1_duty(pwm[i-1]);
         delay_us(200);
      }
     
      ++full_step; // Ñ×ÅÒ×ÈÊ ÏÎËÍÛÕ ØÀÃÎÂ
      change_polarity();   
     
      delay_us(200);
      for(i=1;i<=8;i++)
      {
         //**ÏÎÂÛØÅÍÈÅ ØÈÌ 1**
         set_pwm1_duty(pwm[i-1]);
         delay_us(200);
      }
      set_pwm1_duty(250);
      delay_us(200);
      for(i=8;i>0;i--)
      {
         //**ÏÎÍÈÆÅÍÈÅ ØÈÌ 2**
         set_pwm2_duty(pwm[i-1]);
         delay_us(200);
      }
     
   }
       
}

void change_polarity(void)
{
   if(CNT1 == 1 && CNT2 == 1)
      {
      output_low(CNT1);
      output_high(CNT2);
      }
   else
      if(CNT1 == 0 && CNT2 == 1)
      {
      output_low(CNT1);
      output_low(CNT2);
      }
      else
         if(CNT1 == 0 && CNT2 == 0)
         {
         output_high(CNT1);
         output_low(CNT2);
         }
         else
            if(CNT1 == 1 && CNT2 == 0)
            {
            output_high(CNT1);
            output_high(CNT2);
            }
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat May 17, 2008 3:45 pm     Reply with quote

First... Why do you still have the floating point items in the integer array that I told you to get rid of?

Code:
#define CNT1 PIN_D0
#define CNT2 PIN_D1
...
   if(CNT1 == 1 && CNT2 == 1)
This is not going to work. CNT1 and CNT2 are hard coded values while you want them to return the pin status. To achieve that you can change the code to
Code:
if ( (input_state(CNT1) == 1) && (input_state(CNT2) == 1) )
But this approach could introduce a problem known as the 'read-modify-write problem'. Writing a value to the output and reading it back again might give wrong results if the capacitance on the line is high. With a large capacitance on the line it can take a long time for the voltage to reach the desired output level so you are reading back the wrong value.

Best is to introduce an extra variable to remember the output state:
Code:
void change_polarity()
{
  static int8 OutState = 0;   // Note the 'static' keyword to make the variable is remembered in between function calls.

  OutState++;
  if (OutState >= 4)
    OutState=0;

  switch(OutState)
  {
    case 0:
      output_high(CNT1);
      output_high(CNT2);
      break;
    case 1:
      output_low(CNT1);
      output_high(CNT2);
      break;
    case 2:
      output_low(CNT1);
      output_low(CNT2);
      break;
    case 3:
      output_high(CNT1);
      output_low(CNT2);
      break;
  }
}
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