## stepper motor pulses wrong calculated

6 posts / 0 new
Author
Message

Hello everybody. I am kind of new to avr-gcc and I have a problem. I would appreciate any help.
I have a project in which I use USART to talk to uC and accordingly the uC sends pulses to a stepper motor that controls a syringe. I have counted that the maximum number of pulses that can be send are 136620.

So to be more user-friendly I decided to send the percentage of movement required. For example if someone wants to move the syringe by 30% of the total allowable distance he sends to uC "move30". The uC filters out "move" and 30 stays. Theoretically 30% means (136620/100)*30 = 40986 pulses.
I use the code below and what happens is that until 20% everything is ok. When I send move21 the pulses send are only 1366 (like move1) and then move22 gives 0 pulses. If I send again move22 the pulses send become 1466946000000.

```void move(char s[], char c)
{
unsigned char sComm;
unsigned char sComm2;
unsigned char i = 5, j = 0, k = 0;
unsigned long int pulses_dis = 0, counter = 0;
double pulses_1 = 0;

while( (s[i] != '\0') && (j <= 3) )
{

if( (s[i] >= '0') && (s[i] <= '9') )
{
sComm[j++] = s[i++];
}
else
{
sendString("Error - Comm");
sendChar(c);
sendString(" received a non integer: ");
sendChar(s[i]);
sendChar('\r');
}
}

sComm[j] = '\0';

if(j>3)
{
sendString("Error - Comm");
sendChar(c);
sendString(" number too large\r");
sendChar('\r');
}
else
{
sendString("\rThank you for sending the number: ");
sendString(sComm);
sendChar('\r');
pulses_1 = (1366.2 * atoi(sComm));
dtostrf(pulses_1,6,1,sComm2);
sendString(sComm2);
sendChar('\r');
pulses_dis = round(pulses_1);

for (counter = 1; counter <= pulses_dis; counter++)
{
PORTB |= (1 << PB0);
_delay_us(30);
PORTB &= ~(1 << PB0);
_delay_us(30);
}
}
}
```

I almost forgot! When I reset the uC and then I send move21 it works.

Thanks in advance for any help!

Maybe,

`pulses_1 = (1366.2 * atoi(sComm));`

needs to be:

`pulses_1 = (1366.2 * atol(sComm));`

One thing for sure, you are rolling over somewhere...

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

Quote:

```   while( (s[i] != '\0') && (j <= 3) )
{

if( (s[i] >= '0') && (s[i] <= '9') )
{
sComm[j++] = s[i++];
}
else
{
sendString("Error - Comm");
sendChar(c);
sendString(" received a non integer: ");
sendChar(s[i]);
sendChar('\r');
}
}```

i and j are only updated if s[i] is a digit. Your code enters an endless loop if a received character is invalid.

Quote:

`double pulses_1`

float and double is the same for WinAVR applications. Instead of using floting point math you can do all by using integer math:

`pulses_1 = ((136620 * (unsigned long) atoi(sComm) + 50) / 100);`

Much faster and smaller code. The "+ 50" is the integer way for rounding (add 1/2 divisor before divide). I never have used floating point math in a µC project. Maybe it causes the trouble.

Regards
Sebastian

micocarl I have already tried that but it didn't work. Thanks anyway!

S-Sohn the last code snippet did it. Thank you very much. I knew it had to do something with the type casting. Also by using your math code the code size decreased amazingly. Thanks a lot.

hi everybody,
i am facing little problem.i am trying to make a small cnc lathe with avr, and i am using bascom to control stepper motion.
but i can't program it to higher rpms.
max speed it could run is 60 rpms,
so 60 rpms* 200 steps per revolution=12000 steps per minute generated by the atmega16.
i am using no delay berween the pulses
i tried 25us delay also.
where is the problem ?i am using a 5A h bridge made up of mosfets.
can anybody gain my rpms?