Driving Bipolar Stepper Motors and Trying to Move the Motor a Bit Faster/PRU or UART?

Hello,

I have been trying to get some answers recently on how exactly to make the Bipolar Stepper Motor move a bit quickly compared to not.

I was using drivers that seem to not be the issue now. I have tried multiple drivers and chips like the ULN2003 that can be used directly from the BBB or BeagleY-AI to the ULN2003 to the stepper motor.

In the diagram, it is plausible to handle stepper usage with ease and with little circuitry.

My issue is not trying to move it but exactly how to enforce speed and accuracy at good velocity.

For instance, I have this BBB or BeagleY-AI. I attach the ULN2003 or other driver to handle the update via GPIO to the stepper motor and I am stuck moving quite slowly during the RPM of the motor.

I have reached out many times on this front.

If you know what I am discussing, please do reply. I noticed another fellow getting UART from PRU working and he made a build process for others to view on github.

I was going to review the build, like earlier today, to try to get some UART and PRU functionality working for specific drivers and motors from Teknic.com.

I know there is a piece to this puzzle I am missing. What do I need to make this motor move a bit quicker than now?

Seth

P.S. I mean…is it possible to use GPIO alone to make this stepper motor move a bit faster or should I try another route with different peripherals?

And excuse me for saying this idea out loud. The L293 is fine and works. The SN754410 works too.

I was actually trying to drive a bipolar stepper motor with the ULN2003 and making errors because it was basically intended for the unipolar stepper motor types.

This is one issue I had. Now, with knowing that L293 drivers are better equipped to handle the bipolar types of stepper motors, I can try these now.

Seth

P.S. I think I figured out what happened.

I should have relied on the tested and true versioning to Bipolar Motors for acquiring testing results. I went to the ULN2003 which is for Unipolar Stepper Motor types.

You just love to tinker with Motors, don’t you? :smile:

Take a look here; really good explaining…

2 Likes

Yea. I chat about old school motor movements at times. Who knows how smart a motor can actually be during its lifespan?

First the 1979 chips and now 1996 chips and so on…

Now, revisions and updates to specific chips are being introduced while other chips are being held highly in regard to make motors do specific tasks and quickly.

I watching the viewership on PRU with it being in the open field of communications now is tantalizing.

Seth

P.S. I will check the Youtube link later… Thank you.

I watched the crash course…

Thank you for providing the small and short explanation on specifics.

The AI speech was quick and to the point. I guess the fellow or lady typed in the required data and had a reading program read it out loud?

Seth

To my mind, on the pru side, you want it to operate a a fixed speed, or at least I had to do that on another development on a different ti chip. This meant it had to be interrupt driven, and then driving the interrupt at a fixed rate. So for you having the interrupt routine advancing the stepper motor one step, then changing the interrupt time, to set the speed. Now given the time for the interrupt routine to run, that gives a maximum speed you can run at when using the pru. Question I have though is can the pru be made interrupt driven, I expect so as driving motor a usual use case for them. But if and how you can do this I haven’t investigated get …

… and just spent 30 minutes looking into this. The PRU cores don’t seem to have a traditional interupt controller. Interrupts come in R31, which needs to be polled (so timing only as accurate as as the poll). Looks like you can generate timing interrupts on the IEP, as there doesn’t seem to be a system timer that can produce interrupts.

Does make me wonder how to design arcuate timing for motor control on the PRU, I’ll think about it - and see what others have done …

P.S. and I assume you are doing simple stepping, and not micro-stepping - the latter takes more resources …

1 Like

I always thought the PRUSS could process interrupts and has so many per core.

Anyway:

There are others out there that produce for the PRUSS on the am335x, am5729, and etc…

I think Acorn CNC and their other boards handle PRUSS as a deliverable for access to motor movement(s). I found some other documentation in github.com that uses the PRUSS on the am335x also.

I think the interrupts come as a file in remoteproc in the kernel: 3.2.4.9. PRUSS — Processor SDK Linux for AM335X Documentation .

Seth

P.S. So, something like LinuxPTP may help… I am still looking into it all.

Who is the manufacturer of the motor and model number? How many steps does the motor have per revolution?

How are you sequencing the 4 logic inputs, and at what rate? I am assuming you are using 4 GPIO pins.

omc-stepperonline is the mfg. of the motors. Let me research the stepper models. brb.

Dual Shaft Nema 23 Uni/Bipolar 1.8deg 2.83Nm(400oz.in) 4A 57x84mm 8 Wires

I use a driver for the motors. Sometimes I use a BeagleBone Green with Acorn CNC and then at other times, I am trying different set ups of hardware, chips, and small builds.

So, for the omc-stepperonline.com drivers I purchased a while back, oops and mistakes have been made with that specific purchase, they only handle 3.4A which is not collective to the motors and their status.

Sorry. Model: 23HS33-4008D

I figured I could find a 12v ?A, driver for motors. I could and probably will look into additional drivers since these motors fit the machine/could fit the machine. Anyway, the amperage allowed on these drivers are ā€œsomewhatā€ low compared to what these motors are capable for performance, e.g. 4A.

So, the purchasing end is not done but I really put off building the machine until I got some software and hardware defined a bit better. If you have any words of wisdom, hit me in the face with it.

I also did not expect the, sort of, these motors to be both uni and bi. I figured one or the other. I went with it. I got them to spin with an older model PSU and some GPIO source code. Right now, the gpio source is the least of my worries. I still need to crank out some appliance so I can test everything.

Yea-yea-yea, I know. If they spin, they are listening. But…there is so much in the form of HIGH and LOW, regular GPIO, and then there are edges. Then, the PRUSS is much faster because it does not have to rely on Linux in the fg and bg. I just shovels relentlessly.

off to search now for 24v supplies. Blah.

First - I’m new to the PRU - so could easily be wrong here.

Yes the PRUSS cluster does have an INTC peripheral (on many, maybe all, PRUSS implementations). The INTC is a very capable interrupt handler. Crux is how does it tell the PRU core on an interrupt - and this is by setting a bit in R31 (and a different bit in PRU 0/1); and the PRU needs to poll this bit of R31, to see if an interrupt has occurred. Crux is its the PRU code that decided when it will poll R31, how regular this is, and the timing precession on this.

Compare this to another ISA, the Texas Instruments MSP430. There when the CPU receives an interrupt, it saves the current program counter on the stack, and may also store the register states, then it jumps to an interrupt routine, which does its stuff - and then when it returns at the end, The PC is restored to the original value, and the registers are returned to where it started.

Now the advantage of the second, is it takes a precise number of CPU cycles for the CPU to jump into the interrupt routine, e.g. it is a fixed time. This means that if the interrupt is on a system timer at a regular interval, the interrupt routing gets called after every fixed number of CPU cycles. This is good for motor control - it means with a stepper motor you can arrange every fixed number of CPU cycles to advance a quadrant of the step - and by changing the period, you can change the speed.

Now can set up a PRU in a similar way - where the main loop on the PRU just polls the interrupt register, and loops. That also takes a fixed number of cycles - when an interrupt occurs it passed control to the interrupt routing. That isn’t precise in timing to a CPU cycle, but is precise to the speed of the loop polling the interrupt register.

There are advantages and disadvantages to each approach, neither is perfect - and you need careful design in each to get a good working design.

So crux is understanding what you have to do (in this case for a stepper motor) - and then designing the code appropriately.

Oh thats interesting. So you just have a drive for the two windings, and just need to ensure you drive the right way through the four poles; and don’t have a method of working out the stator position in the four poles (e.g. a Hall sensor on A and B is common).

Anyway what that says is you just have to drive the A and B signals with the right quadrature. Are you doing the negative current by switching in hardware, or do you need a scheme to do that in firmware?

Anyway if you set it up that the PRU just generates the A and B signals, with the right quadrature; then a usual good method is to set this up in a pair of PWM signals, both locked together (most hardware can do this), then arranging the on-off periods on the two PWMs, to have the correct phasing needed. I’m not sure if the PRUSS is capable of doing PWMs like that - I’ll look into it.

Advantage of setting up two PWMs like this - is you just set up the registers for the PWM loops, then they just run by themselves and you don’t need to do anything else.

[P.S. Life is harder, but more reliable, if you have Hall sensors, then you need to only move the A/B switching when the Hall sensor says you can …]

Thank you for your words. In the drivers, they accept PWR, two control GPIO pins from the am335x supported BBB or other board(s), and then to the ole motors.

About the motors. I use all four wires for the bipolar type of motor. A/B.

On those motors, one would need to be careful on which wires to pick.

Is there a consistent routine you choose when making your loop, e.g. stack or heap?

I keep reading about the PRUSS in my spare time but I am not a 100% computer programmer for PRUSS and selected chips. I have taken time out to learn only.

For instance, I read over the datasheets of clpru and asm type programming for the PRUSS at times. I have never really put anything together well enough to receive positive feedback. Well, LED. Yes but no motor control with the PRUSS with larger programs controlling the motors so far is my level so far.

Meant does the PRU drive two signals A and B (which hardware then changes into A+ A- B+ and B-); or does the PRU generate A+ A- B+ and B-. If the latter you need 4 PWM - and be careful of phasing.

I need to think some more on the motor winding, e.g. does one have to drive A- at the same time as A+ …

P.S. Hmm that data sheet doesn’t have enough info for me! I’m not sure if the A- winding is wound on top of the A+ winding, just in opposite sense …. need to think some more …

1 Like

@DavidSummers ,

Hey…and yeppers. I will only need two GPIO pins to control the driver. I am missing something…

I always thought since I could light a LED with the PRUSS, I could also run a motor. Usually LEDs have drivers but I have not made it as far as controlling LED drivers. I like motors.

I think what I am missing is the type of control the PRUSS is actually. I always thought RISC while ARM calls it something different. I know by TI’s personnel and beagleboard.org personnel and users, PRU is a PRU but ARM knows of it as a different naming scheme.

Update

So, from what I am reading, it seems that if I make some files for this PRUSS GPIO driver:

  • The driver for the PRU needs to communicate somehow to another entity, i.e. am335x
  • Now, how should it communicate? No clue for now…
  • I always thought it was as easy as allocate driver in build, use it, and control

The issue I see so far with this method is that with there is a degradation of the stack, i.e. something slips.

LIFO or whatever happens, I guess the PRUSS accounts for the slipping overflow of the development. I actually remember now.

I read a long time ago that the cycle throughout the process is backwards. Like an inversion in dialect. I think. So, like with the kernel driver used to handle the LIFO, the PRUSS actually is FIFO. Right? ←- I would have to double check the specification from TI on the PRUSS on the am335x to be certain.

Ok lets start with stepper motors, you aim with the waveforms to create a rotating magnetic field. This is given in the stepping shown in the DataSheet for your motor:

Step A+ B+ A- B-
1 + + - -
2 - + + -
3 - - + +
4 + - - +

First thing it shows A- = - A+ and B- = -B+ always and no gap between so both + and - coils are bother energised at the same time, with current in opposite directions in + and -.

A and B are at 90 degrees to each other, and which goes first depends on the direction the motor is being run in, clockwise or counter clockwise.

It does say how fast you run these waveforms, and the speed you run them, is the speed the motor runs at. So to run faster you need to run these.

First problem is switching from the + state to the - state, this is Voltage one way, vs the reverse voltage. Now reversing the voltage means switching the which terminal is connected to the positive rail, and the terminal connected to 0V. Now consider that you have to switch both ends - and thats where the problem occurs what if you don’t switch perfectly - then you end up with Vdd connected to 0V; at that stage you get a short - and the circuit rapidly dies.

So your drive chip will be set up to ensure that that never happens. Often in space we had to do this with discreet power transistors, its the only thing that can handle the power flowing through it - the chips don’t want to be driving anything too strongly. When doing this switching it is often better to set up the switching with gaps, e.g. consider:

Step A+ B+ A- B-
1 + 0 0 0
2 + + 0 0
3 0 + 0 0
4 0 + + 0
5 0 0 + 0
6 0 0 + +
7 0 0 0 +
8 + 0 0 +
This has 8 steps to go round once, but notice only one state is switching at a time, and always switches to no voltage, and also I’ve always kept things +ve. Now you would need to check with the motor manufacturer that you get a full magnetic field doing that, you may not - in which case always have to drive the + and - circuits with opposite voltages, but dropping to zero voltage on both in between.

Then how to generate these signals, as stated above, you want reasonably timed signals; and want to be able to control the frequency, to get the motor speed. This is usually done using PWM circuits, and PWM is so common that many chips, including at least the AM6254 found in pocket beagle 2, and I would say is probably true in all these texas instruments chips. So first I say read up on PWM, the pocketbeagle2 has it in the main part of the CPU, so is probably accessed from the linux machine on the armv8. So just needs to be programmed. Read the TRM, so I say section 12.5.3 of spruiv7c.pdf.

What you need to do is program 2 or 4 PWM circuits, all tied together - so all tied off the same clock, but attaching the on and off periods to give one set of the waveforms above. Then use the pins those are outputted to (you may need to pinmux for this, and so load the right device tree) and feed these into your motor control chip. Do check you don’t need power circuits outside of that (e.g. the chip is design for the voltages and current that you need for the motor).

Then in linux, slowly increase the frequency - and the motor will slowly spin up. As it spins faster it will create more back EMF, and so the voltages across the motor will slowly go more and more into driving the back EMF; eventually there will be none left to drive the motor - and you won’t be able to go any faster - unless you increase the voltage available on the power rail.

The other nasty that can happen, the stator can’t keep up with the rotating magnetic field - then it tends to jump backwards round the above cycle. That also usually gets fairly nasty and the motor stalls, and you pray that nothing burns.

So thats about the limit of my knowledge of motors …

1 Like

One of the considerations for driving a stepper motor at a predefined rpm is the L/R ratio of the motor. The load intertia vs torque. The L/R effects the time to produce the holding torque while the load intertia determines how long it takes to move one step of 1.8 degrees. As mentioned once you get the load accelerated you will run into the back emf issue.

The PRU’s would be perfect for this job using their __delay_cycles(xx) function where a cycle for the BBB is 200Mhz. Communication between the PRU and Linux could use the RPMSG protocol.

For the RPMSG you can take a look at the example found in the pru-software-support-package/examples/am335x/PRU_RPMsg_Echo_Interrupt0. Also the PRU_gpioToggle is an example of the delay.

https://git.ti.com/git/pru-software-support-package/pru-software-support-package

Don’t know if this helps? I could upload some code that combines toggleing gpio with the RPMsg. This would be for the BBB using debian 13 Trixie with linux 5.10.168-ti-r83.

1 Like

Got me interested in doing this myself as a winter project. I have a Drok 7a/160W Dual motor drive module that uses LM298 chips. Got this from Amazon. Will need to scrounge around for bipolar stepper motor. This driver has PWM/Enable input which could be used to regiulate the motor voltage.

1 Like

I ruined my PSU once doing something along these lines. Also, this .pdf will be helpful to me: spruhv7c.

That is the C Compiler User Guide.

All in all, thank you for taking time out to make me understand some basics on an approach I can take for the PRU and GPIO handlings along with drivers and motors.

Oops yes its spruiv7c.pdf one letter different. that is the TRM for the AM6254 on the beagle 2. So if programming the BB processor, find the processor number - then find the appropriate TRM on the texas instruments site. It will be a big document, but if the CPU has some dedicated PWM circuits it will be described.

You can run a PWM far faster than bit bashing in the pru - PWM is done in hardware and it dedicated to doing that one thing very well. bit bashing and it needs to be software on the pru - and that will limit the speed …