![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
error in stepper code |
Posted: Mon May 12, 2008 9:26 am |
|
|
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;
}
}
}*/ |
![](http://img106.imageshack.us/img106/5830/stepper2kg7.th.png) |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: error in stepper code |
Posted: Mon May 12, 2008 12:33 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon May 12, 2008 2:10 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Mon May 12, 2008 3:05 pm |
|
|
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.. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon May 12, 2008 5:45 pm |
|
|
Sorry, I don't know anything about microstepping and can't help you. Maybe someone else can jump in? |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Tue May 13, 2008 7:29 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Tue May 13, 2008 7:47 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Tue May 13, 2008 9:23 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Sat May 17, 2008 12:45 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
ferrousduke
Joined: 31 Mar 2008 Posts: 29 Location: Mumbai, India
|
|
Posted: Sat May 17, 2008 2:00 pm |
|
|
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);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat May 17, 2008 3:45 pm |
|
|
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;
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|