Go Down

### Topic: Un smooth motion using swiftecx25 (Read 261 times)previous topic - next topic

#### vertigo72

##### Sep 26, 2017, 11:40 amLast Edit: Sep 26, 2017, 12:04 pm by vertigo72
Hi all,

Newbie/wannabee arduino tinkerer here. Im working on an analog vario gauge for a glider. Im using a x27.168 stepper from  adafruit, that (for now), I connected straight to an arduino uno. Im using the SwitecX25 library.

The signal comes from an openvario glider computer, and is basically a number with 2 decimals precision, that represents climb/sink rate in meter per second, and Im only interested in values between -5.00 and +5.00.

I got it working, but I would like to smooth the motion. Have a look:

https://youtu.be/G5f0yHjs8Io

It looks better on video than it does to my eye, but especially with small movements, I think its still too jerky, and Im at a loss on how to improve it.

I tried adjusting the range, so I would more steps per meter/s, but it makes no real difference (by sheer luck, 945 steps of this motor is pretty close to the number of values between -5.00 and +5.00).

Here is my code:

Code: [Select]
`#include "SwitecX25.h"//setup stepper#define STEPS (315*3) // standard X25.168 range 315 degrees at 1/3 degree stepsSwitecX25 motor1(STEPS,2,3,5,13);int target=0;int ind1; int ind2;int ind3;int ind4;int ind5;String received;String msgtype;String variot;float vario;void setup() {  Serial.begin(9600);    vario=-0.1;  // run the motor against the stops  motor1.zero();  motor1.setPosition(STEPS/2);  motor1.updateBlocking();   }void loop(){  static char buffer[80];  if (readline(Serial.read(), buffer, 80) > 0) {      received=buffer;    if (received.substring(0,4) == "\$POV"){ //     Serial.print("got vario:> ");         ind1 = received.indexOf(',');  //finds location of first ,        ind2 = received.indexOf(',', ind1+1 );   //Position of P or E or V        msgtype = received.substring(ind1+1, ind2);   //P or E or V     // Serial.println(msgtype);        if (msgtype == "E") { // vario message          ind3 = received.indexOf(',', ind2+1 ); //value          variot= received.substring(ind2+1, received.length()); //IAS          ind4= variot.indexOf('*'); //position of checksum data at end          variot= variot.substring(0,ind4); //strip checksumdata          vario=variot.toFloat();          //  Serial.println(vario);        }           }      }   target=-70*vario+STEPS/2;  motor1.setPosition(target);  motor1.update();   }int readline(int readch, char *buffer, int len){  static int pos = 0;  int rpos;  if (readch > 0) {    switch (readch) {      case '\n': // Ignore new-lines        break;      case '\r': // Return on CR        rpos = pos;        pos = 0;  // Reset position index ready for next time        return rpos;      default:        if (pos < len-1) {          buffer[pos++] = readch;          buffer[pos] = 0;        }    }  }  // No end of line has been found, so return -1.  return -1;}`

Is there something in can do in code to make this smoother? Would a stepper controller with microstepping help?

Also, Im a little surprised how noisy this stepper is. Its probably acceptable in a glider, but certainly not a car, which is where these are typically used. Is this normal?

I appreciate any and all help I can get with this.

#### MarkT

#1
##### Sep 26, 2017, 12:37 pm
It seems to be following the GPS unit's graph accurately.  You want it to be better than the data going into it?

Perhaps you just want to low-pass filter the data?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### vertigo72

#2
##### Sep 26, 2017, 02:52 pm
Thanks for the suggestion. TBH, Im not entirely sure what the problem is, but I quickly added an extreme low pass filter to see if that is the problem. Its not. Have a look and keep a close eye on the tip of the needle:

https://youtu.be/y7c91p5_wKY

When movements are large and fast, all is well. But when movements are small, you can clearly see it "step" from one position to the next. I guess the speed should be reduced for small movements, somehow?

#### MorganS

#3
##### Sep 27, 2017, 05:45 am
You were somehow imagining that a "stepper motor" doesn't move in steps?

You could try driving it with a proper stepper driver such as an A4988 which has micro-stepping. It should be possible to adjust the current limit down far enough.
"The problem is in the code you didn't post."

#### vertigo72

#4
##### Sep 27, 2017, 07:58 am
This type of stepper is used in a tens of million of automotive gauges. Ive never seen a needle in a car  instrument jerk like that. Of course it has a finite number of steps, but I dont think thats the real issue. I think the problem is that when the values fluctuate between two steps, the stepper bounces between those steps  accelerating and decelerating way too fast, so you get jerks like the seconds hand of an analog clock. If that same movement was done much slower, Im pretty sure it would look smooth.

Microstepping may hide the issue, provided it works, but I really think this can be solved in software.

#### MarkT

#5
##### Sep 27, 2017, 10:23 am
Normally the pointer would be much lighter - the 3D printed one is heavy and vibrating at visible
frequencies as a result.  Some mechanical damping might also help
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### vertigo72

#6
##### Sep 27, 2017, 11:16 amLast Edit: Sep 27, 2017, 11:37 am by vertigo72
The printed needle is actually lighter than the one that was included with the stepper. But admittedly, its mass distribution is different, which is more important here. Still, I attached the "stock" needle, and this is what that looks like:

https://youtu.be/J-0FrQDX24s

As for mechanical damping; not sure how I would go about doing that, but really, that shouldnt be necessary?

#### vinceherman

#7
##### Sep 27, 2017, 11:48 am
Write a quick sketch to see what is happening.  No GPS input.  Just single step with a half second delay between. 20 steps up. 20 steps down.  Can you see the steps here?

#### MarkT

#8
##### Sep 27, 2017, 11:50 am
Yes, that's not oscillating any more (your needle had a much higher MoI I suspect).

You won't get better than that with a stepper dial like this.  No-one would notice in practice!
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### vertigo72

#9
##### Sep 27, 2017, 10:12 pm
Yes, that's not oscillating any more (your needle had a much higher MoI I suspect).

You won't get better than that with a stepper dial like this.  No-one would notice in practice!
Its quite noticeable. Have a look at this:

Would you be happy if that was in your car? I wouldnt. He's using the same setup as me, and is having the same problem. Its easier to see in his setup because the needles are longer.

Ive been reading some more; in automotive gauges they use these exact same stepper motors but with a microstepping controller:

One problem seems to be finding them, in quantities of less than 100 and with a breakout board.

As luck would have it, I found that I did have a polulu A4988 laying around. I tried with that, feeding the motor 9V (its specced for 5-10V).  I used this driver:
https://github.com/laurb9/StepperDriver

Movement is somewhat erratic though, especially when doing microstepping. Maybe I just need to adjust some values, not sure. Another problem is that I dont see how I can do non blocking moves with that library.

#### MarkT

#10
##### Sep 29, 2017, 12:31 pm
That video shows very different behaviour to the previous ones.

Have you tried just generating a linear ramp?  I suspect your signal source is scratchy/noisy and
you are seeing that source noise correctly mimiced by the stepper.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### MarkT

#11
##### Sep 29, 2017, 12:33 pm
This is the sort of response these motors can give if driven appropriately:

[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### vertigo72

#12
##### Sep 29, 2017, 11:14 pm
This is the sort of response these motors can give if driven appropriately: