How to improve my stepper performance with Accelstepper

Hi all!

I have the attached code running, and at the moment it pulls in input from 4 potentiometers and controls 4x BKA30lF1 stepper motors via a VID6606 driver from a Teensy 3.2. While doing this, it also sends out any change in data via serial to another Arduino with an OLED display. This all works pretty well (see video here), but when I move the controls very fast, the pointers are struggling to keep up. Is there anything I can do to improve the performance of the code? For example, can the motor be running to position while something else happens?

Thanks!

Nick

StepperDuino.ino (7.17 KB)

Why do you think the problem is in the code and not in the stepper motors not being able to move that fast?

Paul

Because if I wire just a single stepper up and run nothing but the pot to the stepper position, it is lightning fast and moves as fast as I can turn the pot. The stepper is capable of 600 degrees per second according to the datasheet. With the code I have it's probably running around half that speed so there's definitely some room for improvement.

Every time through loop() you are doing everything.

Perhaps you only need to read the pots every 10ms or so, then most of the calls to loop() can just be the run() method calls for the motors which will make AccelStepper much more responsive.

You need to learn how to avoid code-duplication. You have 4 copies of most of your code, which is bad news in many ways, 4 times more places for bugs, 4 times harder to maintain, 4 times more code to read.

Parameterize or index your code so only one copy is needed.

MarkT: Every time through loop() you are doing everything.

Perhaps you only need to read the pots every 10ms or so, then most of the calls to loop() can just be the run() method calls for the motors which will make AccelStepper much more responsive.

You need to learn how to avoid code-duplication. You have 4 copies of most of your code, which is bad news in many ways, 4 times more places for bugs, 4 times harder to maintain, 4 times more code to read.

Parameterize or index your code so only one copy is needed.

Thanks Mark, I'll try that now. Do you have any good examples of how to do this? I figured I would need to duplicate because each of the 4 sets of code is storing data averaging. I guess in VB code you'd use an array to store the data but I haven't learned how to do this with Arduino yet...

[EDIT] I noticed that I can increase the .setMaxSpeed to 15000 and it does improve the speed, but when I move the pot quickly the pointer stops mid sweep and then loses position - I guess this is too fast...

The serial code is already running only every 10ms, but I added another if statement to run the pot calculations and .moveto command every 10ms though it seems not to have any effect... Clearly doing something wrong here...

Nick

Was going to run your code on my test bench kept getting an error for Serial1 was not declared in this scope.

DAS

Thanks Das! It could be because I'm running a Teensy 3.2 and it has multiple serial connections. If you replace serial1 with serial that may solve the error?

Nick

I'll try that, Tried it on 2 computers one was set up for a Teensy I may not have had it selected in the boards

Thanks

Doug

Nick

That worked. Going to wire it up later just to see how it works. why did you go with step direction and not drive the stepper motors directly from the teensy The the switec style instrument stepper motor can be driven directly from an atmega328P with NO stepper motor drivers of kickback diodes. I have dissected dozens of factory built stepper motor instruments With pic.Cypress and atmega Microcontrollers, none use a stepper driver.

Thanks DAS

Thanks very much Doug, really appreciate the help. The main reason was that originally I was planning on using the VID-23 motor and the material I read recommended using the VID 6606 chip to drive it. It saves on pin usage so I figured it was the best way to go. If you think otherwise then I'd be interested but I've no clue how to do it :)

Secondly, to drive the 4 steppers I need to do some calculations to process the input data. This can come from:

  • Speed: either square wave read or CAN Bus
  • RPM: square wave or CAN Bus
  • Water Temp: analogue read or CAN Bus
  • Fuel Level:analogue read

Presently I'm simulating everything using 4 pots on analogue read on the servo teensy, driving the servos then serial communicating the figures across to another teensy to run an OLED. I noted that the OLED kills the performance of the servos so I felt it best to keep the servo related stuff away from the OLED display teensy. My question is, do you agree this is the best way to do it? Thanks again!

Nick

If your needles are good and steady not jittering and you have good needle resolution in microsteps and not loosing accuracy, keep it the way it is. these are all things I went through driving directly from the atmega. took a lot of back and forth with the person that was writing the code for me to get it 100% If you can do your own code for the steppers makes it a little easier. I cant. a square wave input on the speeds needs to be a 50%duty cycle with a 2.5volt offset any thing other than close to that the Arduino wont see it. a sine wave would need to be run through a vr signal conditioner.inputs oil pressure could use a .5 to 4.5 volt pressure transducer. temps are usually a thermistor could use a voltage divider but most automotive temp sensors are not linear. there is a 0 to 5 volt temp sensor used on GM trucks with the LS motor fuel you might be able to use. a voltage divider there and adjust the code on the input to match your gauge reading. I found on the stepper driven directly from the atmega did not like to operate at lower input voltages. the full range 0 to 5 seemed to work the best. I am going to try your set up to see how it differs from the stepper driven direct.

DAS