Stepper Motor Slow Compared to Arduino

Hi, I have a very simple bit of code connected to a stepper motor driver but I am experiencing some strange behavior.

I am Pulsing at 2khz and expecting 60rpm (in accordance with micropulse setting and 5:1 gearing)

When I run the code on an Arduino, the motor runs as expected but when I run it on a photon my stepper motor seems to max out at a very slow speed which is much lower than the expected RPM if calculated by pulses per second.

Strictly speaking, my stepper motor driver wants a 5V logic level, I thought I could circumvent this by supplying it with constant 5V and the pulsing ground is my logic here flawed? and if so is this explaining my inability to run the motor particularly fast and why does it turn at all in this case?

Alternatively, perhaps the photons pin (D2) cannot switch at 2khz but I find this very unlikely as the Arduino UNO can.

Or it could be something I have not thought of that slows down the loop on a photon or something?

Any thoughts would be appreciated. The code is very basic but I will include it:

#define pulse_pin D2

int pause = 200;

void setup() {
  pinMode(pulse_pin, OUTPUT);
  digitalWrite(pulse_pin, LOW);

}
   
void loop() {
    
    digitalWrite(pulse_pin, HIGH);
    delayMicroseconds(pause);
    digitalWrite(pulse_pin, LOW);
    delayMicroseconds(100);

}

Be aware that after each loop, the OS gets a slice of time before running loop again. So you might not get a perfect 2kHz using bit-bang method as you are. If you wrap your HIGH-LOW sequence in a while loop for a period of time (say a second) on each loop, you might get closer to a full 2kHz.

Have you tried the tone() function? I think it uses hardware timers for PWM which would get the 2kHz exactly.

https://docs.particle.io/reference/firmware/photon/#tone-

I will have a look at tone() presuming it likely makes a nice square wave.

But just to clarify, my issue isn’t quite that I am not achieving exactly 2khz. It is that with the photon my stepper motor seems to max out at much much lower speed than expected where as on the Arduino it runs as expected with the same code. As such I was presuming I was “loosing” pulses when the code was run through the photon.

Or else its my 3v issue.

OK

Just a follow up,

In a while loop, the photon behaves. So my question is, why is the photon using so much time per loop extra compared to an Arduino and how would this be remedied without a while loop round everything?

While similar, the photon is a different beast than a comparatively ‘simple’ Uno. The photon has an RTOS to run, and a cloud connection to maintain. That all takes time. In turn, they offer a lot of added functionality that is not commonly available on your average arduino, since those only run the task you give them, and nothing else.
Running it in manual mode, or in a thread might be an option, but I haven’t got any experience with that so I’ll leave that to someone else to answer.

3 Likes

Ahh thanks for that, its seems I have opened myself a delightful can of worms!

I hope someone can follow up with a bit more guidance on threads (as manual also poses issues).

Using the tone function is the simplest method. Next to that will be the SparkIntervalTimer Library. Getting into threads seems so messy and unnecessary to get a 2 kilohertz signal.

The Photon loop is scheduled at 1000 times per second, so even without a delay you’ll only get 1 kHz. You’ll have to use PWM instead of manually doing it the way. PMW is a better idea anyway; the hardware generates a precise jitter-free signal and you only have to tell PWM to start/stop/change the delay instead of every high-low transition.

2 Likes

Ahh, so I do need to alter the speed of the stepper and also track position which is why tone and PWM arn’t ideal.

I think maybe my best option for now is to break out of a while loop only once a second but this is giving me a bit of jitter in the motor drive.

OR sort of “threading” but cheating is to use the Arduino to generate the pulse and then use the photon for all the other functionality I need.

Essentially I might use the photon to tell the Arduino to perform X Pulses at Y speed

You could track the exact number of pulses using callbacks from the SparkIntervalTimer. In each call back, toggle the pin and increment a counter. When the number off pulses is satisfied, disable the timer.

Thinking out loud now, you still may be limited at 1 kilohertz based on @rickkas7’s comments.

SparkIntervalTimer can go as fast as 10 microseconds per cycle. It’s just the Timer class and the loop thread that are limited to the FreeRTOS task schedule which is 1 millisecond.

1 Like

Yes I do keep spotting the 1khz limit listed too.

I think looking at the problem now Im moving in the direction of generating the signal outside of the photon and simply modulating desired number of pulses + pulse width via the photon.

I want a simple set of BLYNK controls too and I know how much delay that is going to add to the whole thing. really I’m not sure generating what should be smooth pulses at this speed should really be done the way I was attempting. Especially when I want to do a few other things at the same time.