Timers and Stepper Motor Control
Timers and Stepper Motor Control
Hello,
First I just want to say how impressed I am in espressif and the esp32 chip and sdks. I've been in the Arduino space for a while and the power of this chip running on a RTOS is amazing. I have yet to really run into any major hurdles at all. I am a little new to the FreeRTOS way of doing things with tasks vs the bare metal way. My question is for something like a stepper pulse generator(speed control not position) I am curious what the best way might be. I have vetted a few options:
1) A task with a vTaskDelay. Unfortunately from what I can tell there is no way to get 1 sub ms timings this way. I will need rates of around 50khz so around 20 to 30 us task period or so. Other option being using a sort of busy wait delay function. This seems sub optimal and against the spirit of an RTOS.
2) Use the timer API for a software timer callback. Similar issue to above and do not seem to be able to go sub 1 ms timings. Doesn't look like the intended use.
3) Use a hardware timer with an interrupt. Works great. I can ramp up from low speed to high speed by just adjusting the next alarm value to match my desired step rate. I can only get this to work by toggling the gpios inside the interrupt itself. If using a semaphore there back to a task my step rate seems to have a low limit on frequency. Maybe there is a better way to pass control back quickly. If not my thought is enabling a state machine there so I can appropriately adjust my step pins. Worried a bit about putting too much logic in the ISR. Not exactly sure how much is "too" much on the codebhere.
4) Use the LEDC/PWM driver. I have gotten this to work successfully by adjusting the duty cycle/frequency to generate my pulses. However I seem to be having timer bit resolution issues on the frequency side to achieve the slow rates I need as well as the faster rates. Basically I have to bias one way or another. I have not tried changing timer resolution on the fly. Might work but that appears also not optimal.
5) Use the RMT peripheral. Also have gotten this to drive my steppers successfully. I have the least experience with this kind of option. I could not figure out a way to adjust the speed during my task with this very well. Could just be missing something here
6) I2S bus. Looks very interesting. And could drive high step rates easily. Very unfamiliar with how to start down this path. Saw an example using the esp8266 that was working and looked quite promising.
Sorry for the long post and I am not necessarily looking for code help. Just a push in the right direction! Thanks in advance!
First I just want to say how impressed I am in espressif and the esp32 chip and sdks. I've been in the Arduino space for a while and the power of this chip running on a RTOS is amazing. I have yet to really run into any major hurdles at all. I am a little new to the FreeRTOS way of doing things with tasks vs the bare metal way. My question is for something like a stepper pulse generator(speed control not position) I am curious what the best way might be. I have vetted a few options:
1) A task with a vTaskDelay. Unfortunately from what I can tell there is no way to get 1 sub ms timings this way. I will need rates of around 50khz so around 20 to 30 us task period or so. Other option being using a sort of busy wait delay function. This seems sub optimal and against the spirit of an RTOS.
2) Use the timer API for a software timer callback. Similar issue to above and do not seem to be able to go sub 1 ms timings. Doesn't look like the intended use.
3) Use a hardware timer with an interrupt. Works great. I can ramp up from low speed to high speed by just adjusting the next alarm value to match my desired step rate. I can only get this to work by toggling the gpios inside the interrupt itself. If using a semaphore there back to a task my step rate seems to have a low limit on frequency. Maybe there is a better way to pass control back quickly. If not my thought is enabling a state machine there so I can appropriately adjust my step pins. Worried a bit about putting too much logic in the ISR. Not exactly sure how much is "too" much on the codebhere.
4) Use the LEDC/PWM driver. I have gotten this to work successfully by adjusting the duty cycle/frequency to generate my pulses. However I seem to be having timer bit resolution issues on the frequency side to achieve the slow rates I need as well as the faster rates. Basically I have to bias one way or another. I have not tried changing timer resolution on the fly. Might work but that appears also not optimal.
5) Use the RMT peripheral. Also have gotten this to drive my steppers successfully. I have the least experience with this kind of option. I could not figure out a way to adjust the speed during my task with this very well. Could just be missing something here
6) I2S bus. Looks very interesting. And could drive high step rates easily. Very unfamiliar with how to start down this path. Saw an example using the esp8266 that was working and looked quite promising.
Sorry for the long post and I am not necessarily looking for code help. Just a push in the right direction! Thanks in advance!
Re: Timers and Stepper Motor Control
For stepper motor controllers, my goto is the A4988 module. These can be picked up for less than $2 a unit. You have one pin for direction and another pin which steps on a transition. The module takes care of everything else including stepper resolution and more.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: Timers and Stepper Motor Control
Also more hardware drivers still coming https://esp32.com/viewtopic.php?f=10&t= ... otor#p2284
Re: Timers and Stepper Motor Control
Hey Neil,kolban wrote:For stepper motor controllers, my goto is the A4988 module. These can be picked up for less than $2 a unit. You have one pin for direction and another pin which steps on a transition. The module takes care of everything else including stepper resolution and more.
Thanks for the response. Great work with your videos and the book you have out. That has really helped me get up and running quickly. I am not trying to generate the PWM for actually driving the steppers directly. I already have stepper drivers for that like you said. Not the A4988 but similar ones the DRV 8825 I believe, and some AMIS-30543. I have both of these interfaced and working nicely. What I am mainly looking for help with is the code to generate the step pulses to the drivers. I will have a couple of drivers I need to feed and with microstepping will be at decently high rates atleast 30-40 khz possibly up the 50 khz depending if they still have enough torque. So I have them working(the best probably with the hardware timers and ISR callbacks) just part of me has a sneaky feeling that I am not doing it the most efficient way.
p.s. Just watched your video on the MPU-6050 and funny enough the project I am working on is a 2 wheel balancing robot! I have gotten the MPU-9250 interfaced with the DMP functions and it is working nicely if anyone is interested.
Thanks!
Re: Timers and Stepper Motor Control
Hello Jones,
I think the PWM Peripheral is the best way to generate pulses like this (I think you need a lot of pulses with same frequency). I would offload things like this from the CPU because switching into an interupt and toogle a pin is very time consuming for the effect you have. If I see it right in the datasheet, the PWM has a 20BIT counter. So if I have calculated right you can have an output frequency range from 0.1Hz - 50kHz only with updateing the upper limit without changing the divider. But be careful when you update the upper limit to avoid glitches. (I would activate the Overflow interupt for this and change it there.) Maybe you can think about direct register manipulation to speed up the things.
If you want to change the frequency very often (like every second waveform) you can think about the timer interrupt and toogle the pins during the interrupt. I don't know how much time it takes to jump into the interrupt but I think this are some cycles. So I would place the interupt at least in the IRAM to avoid a cache miss 50k times a second. I wouldn't inform an extra task for it. If you want to to this I think you can rerun the scheduler. (I'm not sure about this look at the RTOS doku) I would also look for the implementation of the driver for toogle the pin. Maybe it is worth to write directly to the registers.
I'm not exactly sure but maybe Stepper motors are not the best for a self balancing robot because they have not so much torque and they are not so fast.
Regards
Peter
I think the PWM Peripheral is the best way to generate pulses like this (I think you need a lot of pulses with same frequency). I would offload things like this from the CPU because switching into an interupt and toogle a pin is very time consuming for the effect you have. If I see it right in the datasheet, the PWM has a 20BIT counter. So if I have calculated right you can have an output frequency range from 0.1Hz - 50kHz only with updateing the upper limit without changing the divider. But be careful when you update the upper limit to avoid glitches. (I would activate the Overflow interupt for this and change it there.) Maybe you can think about direct register manipulation to speed up the things.
If you want to change the frequency very often (like every second waveform) you can think about the timer interrupt and toogle the pins during the interrupt. I don't know how much time it takes to jump into the interrupt but I think this are some cycles. So I would place the interupt at least in the IRAM to avoid a cache miss 50k times a second. I wouldn't inform an extra task for it. If you want to to this I think you can rerun the scheduler. (I'm not sure about this look at the RTOS doku) I would also look for the implementation of the driver for toogle the pin. Maybe it is worth to write directly to the registers.
I'm not exactly sure but maybe Stepper motors are not the best for a self balancing robot because they have not so much torque and they are not so fast.
Regards
Peter
-
- Posts: 24
- Joined: Fri Oct 07, 2016 4:43 pm
Re: Timers and Stepper Motor Control
Hi qjones,
I am trying to understand where your 20-30us delay comes into the equation with stepper motors. I have found that at least a couple of milliseconds are needed between each step for the motor to keep up. Even an audio speaker can't keep up with 50kHz.
A stepper is easy to control with 4 digital outputs into a darlington array such as the ULN2003. You can also get away with using two outputs with the help of inverters to drive the other two inputs. With the ULN2003 you can use spare inputs/outputs to create inverters.
I have found that stepper motors get hot - and therefore eat batteries - just sitting there. I make sure to to turn off all control lines when they are not being used so that they don't waste current. This is more difficult if you use an inverter to create the 4 bit pattern from 2 bits. I assume that the dedicated stepper controllers have the ability to turn off all the lines.
Regards,
Murray
I am trying to understand where your 20-30us delay comes into the equation with stepper motors. I have found that at least a couple of milliseconds are needed between each step for the motor to keep up. Even an audio speaker can't keep up with 50kHz.
A stepper is easy to control with 4 digital outputs into a darlington array such as the ULN2003. You can also get away with using two outputs with the help of inverters to drive the other two inputs. With the ULN2003 you can use spare inputs/outputs to create inverters.
I have found that stepper motors get hot - and therefore eat batteries - just sitting there. I make sure to to turn off all control lines when they are not being used so that they don't waste current. This is more difficult if you use an inverter to create the 4 bit pattern from 2 bits. I assume that the dedicated stepper controllers have the ability to turn off all the lines.
Regards,
Murray
Re: Timers and Stepper Motor Control
Duh. Sorry I messed that up. I had gotten away from my notes on my workbench when I posted this question. Lesson learned! Ok so it is really 2.5khz at the absolute max I was looking for and I had tried to add a fudge factor of 2x to be conservative and see how tight of timing was possible. Hence the 50 khz... Anyway so what is needed is really 0.4 ms, or 400us to achive the 2.5khz. Therefore I assume I would still need/like to be able to support sub 1ms timings. The torque might not be there but a fun exercise for helping understand a RTOS and timing things none the less.murray_lang wrote:Hi qjones,
I am trying to understand where your 20-30us delay comes into the equation with stepper motors. I have found that at least a couple of milliseconds are needed between each step for the motor to keep up. Even an audio speaker can't keep up with 50kHz.
Steppers are for sure not the best thing for this. As stated they eat battery and are always consuming a constant high current. Main reason I am experimenting with them here is that I found the AMIS-30543 stepper driver which lets you read back the speed and load angle on the rotor and adjust stepper current on the fly based on current torque demand. No idea how well this works in practice but I am excited to try it! Also the project I am branching from is based on a stepper motor design, and uses the ESP8266 + an Arduino Leonardo.
https://github.com/jjrobots/B-ROBOT
I thought it be a fun task for learning this new chip to get this all working on just a single ESP32 and using the esp-idf. My next goal would be to do a full design using some nice dc motors + encoders I have here on my bench.
Again thanks for the input and sorry for the erroneous original post.
Re: Timers and Stepper Motor Control
Hey peter,peter_ wrote:Hello Jones,
I think the PWM Peripheral is the best way to generate pulses like this (I think you need a lot of pulses with same frequency). I would offload things like this from the CPU because switching into an interupt and toogle a pin is very time consuming for the effect you have. If I see it right in the datasheet, the PWM has a 20BIT counter. So if I have calculated right you can have an output frequency range from 0.1Hz - 50kHz only with updateing the upper limit without changing the divider. But be careful when you update the upper limit to avoid glitches. (I would activate the Overflow interupt for this and change it there.) Maybe you can think about direct register manipulation to speed up the things.
If you will see my previous post I screwed up the required rates. My bad. It is actually closer to 2.5khz realistically. PWM would be a nice way to do it and like I said I got that to work in some certain speed ranges. However from what I see I have a maximum 15-bit counter for the LEDC/PWM driver. Am I missing something here? Also you mention changing the "upper limit" I am not quite sure what you mean. But I will do some research on the datasheet and see what I can find, in particular with the counter bit depth.
Thanks,
-
- Posts: 24
- Joined: Fri Oct 07, 2016 4:43 pm
Re: Timers and Stepper Motor Control
Hi qjones,
If you try to drive a stepper faster than it wants to be driven it will just cough and miss the step. If you are relying on the step count for positioning then you will lose your reference. Inertia is the problem. Smaller, lighter motors will most likely tolerate a faster rate depending on the load. You can also work up to a faster rate when the motor is spinning due to angular momentum, but again it depends on the load. I think 2.5 KHz is still pushing your luck, but I would like to hear back from you on this thread if you manage to achieve it.
I am using stepper motors for robotics because they make it easier to control distances and angles for calibrated movement. I have been using 8 GPIOs, but have decided that's too costly on resources. I am now looking at using a shift register for stepper control - 2 GPIO pins to control 2 steppers. Latency should not be a problem given the timing constraints we have been discussing.
Cheers,
Murray
If you try to drive a stepper faster than it wants to be driven it will just cough and miss the step. If you are relying on the step count for positioning then you will lose your reference. Inertia is the problem. Smaller, lighter motors will most likely tolerate a faster rate depending on the load. You can also work up to a faster rate when the motor is spinning due to angular momentum, but again it depends on the load. I think 2.5 KHz is still pushing your luck, but I would like to hear back from you on this thread if you manage to achieve it.
I am using stepper motors for robotics because they make it easier to control distances and angles for calibrated movement. I have been using 8 GPIOs, but have decided that's too costly on resources. I am now looking at using a shift register for stepper control - 2 GPIO pins to control 2 steppers. Latency should not be a problem given the timing constraints we have been discussing.
Cheers,
Murray
Re: Timers and Stepper Motor Control
Hello Jones,
I mean the technical reference not the datasheet. Page 157.
I have look a little bit closer and just seen, that the upper limit can only be set in bits (2^n). So I think you have to work with the divider (It has 14Bit + 4 Fractial Bits so in total 18 Bits). You can use the normal counter register as Divider and the divider to determine the Frequency. I which you a lot of fun in calculating. But it looks that it is worth because the highspeed timer is glitch free. (At least they have written it in the documentation) So it is fire and forget.
Reading the load angle sounds very interesting. Maybe you can give some feedback how well this work.
@murray
I would recommend you to look at some stepper driver. They normally need only 2 Pins and they can regulate the current very often. This will maybe give you a better torque because you can use a higher voltage and at you can use 4Pin steppers.
Regards
Peter
I mean the technical reference not the datasheet. Page 157.
I have look a little bit closer and just seen, that the upper limit can only be set in bits (2^n). So I think you have to work with the divider (It has 14Bit + 4 Fractial Bits so in total 18 Bits). You can use the normal counter register as Divider and the divider to determine the Frequency. I which you a lot of fun in calculating. But it looks that it is worth because the highspeed timer is glitch free. (At least they have written it in the documentation) So it is fire and forget.
Reading the load angle sounds very interesting. Maybe you can give some feedback how well this work.
@murray
I would recommend you to look at some stepper driver. They normally need only 2 Pins and they can regulate the current very often. This will maybe give you a better torque because you can use a higher voltage and at you can use 4Pin steppers.
Regards
Peter
Who is online
Users browsing this forum: andy_wharton_uk, Bing [Bot] and 88 guests