SimpleFOC using LC86H2160 stepper with DM860H on STM32F103C8T6, for open-source injection machine

Hi Peeps!

First time posting, been lurking a while trying to find answers to my intentions:
I have built a motorized injection machine that I wish to add to the Precious Plastic initiative, that originally wished to control via Arduino (I am pretty familiar with ArduinoIDE, making functions, state machine, etc), and had so far got an isolated setup with FastAccelStepper to move the motor very nicely, both continuous via button press until release, and commanded moves, endstops to stop movement, and was adding encoder support (this stepper has a 1000PPR optical AB encoder), but here started running into issues, as the interrupts on the Arduino are used by both FastAccel and Encoder, slow speeds work, but medium speeds start to interfiere, steps lost on motor, encoder also loses pulses, etc…

so after a look at alternatives, decided for BluePill, as was basically only STM32 available locally, and having hardware encoder support and motor timer PWM support offloaded from MCU, thought would be great to get the hard calcs/counters onto dedicated interfaces… THEN I found SimpleFOC and obviously the attraction of uniting all the data from motor, encoder and current sensing seemed sent from heaven… had seen that in 2022 step/dir was not directly supported, but my workflow I don’t (strictly) need full FOC:
When Stepper motor is firstly compressing recently introduced cold plastic, with the nozzle blocked to avoid already hot plastic coming out* I WANT the stepper motor to reach full load and lose steps, as therefore I am sure that max power and compression has been applied… the same for actual injection, to make sure mould is full (depends on mould, others requiere less force)… I had created a comparison function that took the motor steps ordered and the encoder feedback, and when there start to appear a discrepancy, then this is because motor is losing steps, so back off speed, but keep going until new threshold of loss is past, etc, until speed is below min…
I was also contemplating incorporating current sensing to add to the mix, and detect similar situations (later testing would indicate which system is more reliable), so finding SimpleFOC seemed ideal…

  • (production works on reload after each injection, but full stroke may do 3-8 injections depending on mould size, plastic takes 10-15 mins to heat up, so adding after each injection and making sure a full strokes worth of plastic takes at east 15mins helps maintain continuous (paused between each injection!) production)

So I am somewhat confused about the current state of controlling stepper motors via step/dir commands, the speed/dir driver is for listening, not sending commands…? have not been able to find an image of how to actually wire a step/dir setup, all seem for at least 2PWM set up, using 2 half bridges for complete phase control (necessary for full FOC support), but I am relying on encoder positioning to maintain realtime plastic use, plunger position (later wish to add a ESP32 Display to show the reported plastic Refills, with a graphic that can show coloured rectangles with times since intro, so the user can see how much hot-enough plastic is available for next mould size (which will also be stored in ESP32 Display as “mould-profiles”, including injection speed, amount, possible current max) which can be loaded from a pre-saved list of calibrated “NextInjection” parameteres that would be sent to the STM32 before each injection, keeping the STM32 only for actual motor movement and control…)

Sorry for the ramblings, first time trying to describe everything, may be a bit chaotic, hope someone can help me sort out best path to go forward… am learning STM32CubeIDE, a lot more confusing that ArduinoIDE, but have so far managed to assign in STM32CubeIDE and configure most of the pins for Motor Speed/Dir, EncoderA&B, USART3 for communication to ESP32 Display (although will be starting with a simpler ESP32 loaded with serial passthru to talk directly to the PC, to get encoder data every second, and beable to send new arrays of mould-profile data sets for NextInjection) SPI to thermocouple daughter board, and current sensores to phA/B (although inline current sensing image seems to indicate to use phB+/-…?) - still have to add 3 user buttons, a couple of strips of WS2812B, to change button colors as per State of machine…

I must admit I am more of a hardware guy, the machine I made some decisions what hardware could be useful, with respect to the power needed (the stepper goes thru a 20:1 reductor, drives plunger thru rack & gear), whilst having a reasonable Arduino knowledge, but did not realise the limits of Arduino would requiere something like a STM32 with dedicated hardware pins for the most intensive tasks…
To use the SimpleFOC I am doing a complete rewrite of my code, which so far was only half complete, as had run into this issue of getting driver library and encoder readings to work together… had tried various other libraries for both, but none gave good combined results… I would like to use the SimpleFOCdriver implementations if possible, as would seem to take advantage of the STM32 hardware encoder and PWM motor timing available, but as mentioned, am at a bit of a cross roads as to where to go from here, as options are various and in some cases limited…

Thanks for reading, maybe someone can do a TL;DR post after mine, I’m not good ad resuming… (although have been starting to use ChatGPT to help with Arduino programming, it helped me find an optimised version of driver/encoder code that worked at low speed where nothing else would even do that… :thinking:)

1 Like

So as I see it you have some decisions to make:

Type of driver and control

A PWM based driver will allow you to control the stepper using FOC, usually reducing current consumption and noise, and allowing you to use SimpleFOC library for the motor control.

The step-dir based driver you have is known to be working, and we don’t know what it’s doing internally. It might be quite efficient already, or it might be worse than using FOC. You can use it with a step dir based control library like FastAccelStepper.

If you want to switch to PWM based control, you probably need something with 4 PWM channels (most steppers are 4-PWM steppers). For 7.2A current you could use something like the Dual MKS boards based on ESP32, or find two DRV8302 based boards (available on AliExpress) and use 4 of the 6 channels.

MCU type

Using SimpleFOC will mean you have to change hardware.
Using FastAccelStepper isn’t possible on STM32.
Using Sensor and Stepper based on interrupts isn’t working on ATMega hardware.

But you can consider other MCU types:

ESP32 - we have a hardware encoder driver for it
RP2350 (Pico 2) - you can use PIO to read encoders by hardware, drivers available on GitHub

Also other MCU types have hardware encoder interfaces: SAMD51, Gecko ERF32 and Renesas, but I’m not aware of Arduino support for their encoder hardware.

Controlling Steppers

If you want to write your own driver to control by step-dir on STM32, managing the velocity is not so hard, using 2 timers for example:

  • 1 timer produces the pulse in “one shot mode”
  • another timer triggers the first timer at regular intervals (giving constant velocity)

Controlling the acceleration curve is a bit more tricky :slight_smile: probably that’s where the interrupts come it, I haven’t checked the code of FastAccelStepper…

But there may also be alternative libraries for stepper control that already work with STM32?

ChatGPT says…:

TL;DR:

The user built a motorized plastic injection machine intended for the Precious Plastic initiative and initially controlled it using Arduino with FastAccelStepper. However, they faced issues with step loss and encoder inaccuracies due to interrupt conflicts at higher speeds. They switched to an STM32 (BluePill) for better hardware support and discovered SimpleFOC, which seemed ideal for integrating motor, encoder, and current sensing. The user is now considering using SimpleFOC with step/dir control but is confused about the setup and wiring, especially how it integrates with their existing workflow that relies on encoder feedback for step tracking and potential current sensing. They seek advice on the best path forward, using STM32CubeIDE for pin setup and hardware integration, and aim to integrate a display system to monitor plastic refills and mold profiles via ESP32.

lol :joy:, that is indeed a long post. Welcome to SimpleFOC.

Short answer to your post: I think what you need will be possible with SimpleFOC and its drivers, but of course it will be a bit of work and tinkering.

I think you have many questions and maybe it’s better if you post them specifically and and one or two at a time… I think people will be able to help you better then, because TBH right now I don’t know where to start :slight_smile:

Correct! It is a lot all at once… with Arduino I try to do by parts normally anyway, so as I create a large sketch, try and test smaller ones just on one “item” at a time…
in this case, I guess I would start with Encoder (moving motor by hand exactly 1 revolution, 10 revolutions etc), then go to motor separately, then both (which is where discovered interrupts issue with Nano), and with current should be pretty simple to add to motor tests…

however as SimpleFOC “backend” (not too sure how else to call it) reunites all of these data inputs to make a control algo, and also separates motor and driver constructors, do all of these parts have to be done together anyway…?

also, if anyone can point me to examples, tutorials for getting steppers working with SimpleFOC commands using step/dir only, that would be a great help for trying out a motor sketch…

Right now am in the middle of pretty large injection job (manually :person_shrugging:), so can only dedicate late evening time to going thru this with the setup that I brought home (made the machines electronics set up on a separate backboard for the electrical box, except REX-C100 which are installed on one side of box), but I will try and set up and connect as mentioned above…

Attached photos of electrical back board, capture of spreadsheet of power distribution ATM (will be dividing the LV distribution board into 2 sides, 3.3v and 5v), capture of pinout of STM32 with pins assigned thru STM32CubeIDE, pins with “?” are yet to be assigned (have to check there should be no issues, although WS2812B may require a pin with timer access?), LLC with assigned pins and signal directions, and capture of STM32CubeIDE pinouts FWIW…

have a small(ish) issue with pin choices… as this was originally going to be a Nano, I decided on a Nano breakout to terminal board, which is 15 pins long, whilst the STM32 is 20 pins long, so to hack/use same board, will leave some pinouts without pins, and have tipp-ex’d the original Nano pin designations and will write in the STM32 pins that I need to use, so have to use pins within 15 long span to make this work (marked with green rectangle on pinout)… I have been unable locally to obtain a similar STM32 breakout terminal board :person_shrugging:… LV dist board is same Nano breakout terminal board, but with terminals arranged for easier connection, and wired and soldered all along the back of the terminals :stuck_out_tongue_winking_eye::person_facepalming:… will be making a break about half way to divide later between 3.3v (require 6 connections) and 5v (require 8 connections)…

doubts about how to exactly connect stepper leave me unsure if will need another LLC…? if have to use 2PWM somehow (not sure if possible), would that mean additional 3.3v signals from STM32 would need converting to 5v for motor…? Have another LLC if needed, but not too much space left!

doubts about the inline current sensing, as text indicates phA and phB, but images show sensing on B side only…?

As this is the most complicated project I have as yet adventured, any advice is gratefully received, for sure have some things I have not contemplated yet/correctly

PD new user can only embed 1 image, of the 5 I wish to share… links to images:

opps, only 2 at a time!

Eventually yes, but testing each part separately first is the best approach.

I’m still pretty lost what you’re trying to do…

The DM860H is a stepper driver that already has step-dir control. It’s not the kind of driver you can use with simpleFOC. If you want to use SimpleFOC to do field oriented control of the stepper motor you will need a different kind of driver that allows you to control the phase voltages via PWM.

Of course you can use our sensor classes and other code but you will have to write the step-dir output logic yourself, we don’t have that. We only support step-dir input, not output.

as have to rewrite most of the (half complete) code for the Arduino to adapt to the STM32, am trying to decide whether using SimpleFOC as an (almost) complete solution would work for my use case (luck has it that found SimpleFOC after deciding on the STM32, after finding the issues with FastAccel and Encoder stepping on each others interrupts use) … AYK, many Arduino libraries are not compatible with STM32, and FastAccelStepper is unfortunately one of them (AFAIK), however it is my preferred as ideally I need to get to at least 6000 steps/s or more to be able to fill the moulds fast enough (the stepper motor should be good up to about 10000steps/s, 1500rpm)… my particular use case of forcing the stepper until it skips on purpose requires that have a primary source of real steps moved (encoder), to know when pressure has increased enough to make the motor skip steps (with a comparison function comparing motor steps sent and encoder steps really done), this is to know when the mould is full, and when the plastic has been fully compressed in the barrel… I was also trying to get current data from the DCin to the driver, but it was giving incredibly unstable readings, and as the driver is constant current, not too useful, although there was actually variation with load, but jumping all over the place, with about 1A uncertainty… inline to the motor itself is totally new to me, but also not sure what to expect if the driver is constant current :thinking: (would I see useful data using inline sensing…? is SimpleFOC the only way of reading this way the current of a stepper), so the encoder data is still primary source ATM…

the injector sketch is based on state machine, & user button presses, to control exactly what motor movement will occur in each state, from Refill (lift plunger to top), to CompressNewMaterial, thru the InjectProcess, which consists of Purge (continuous move whilst button press) with zero of motor, AntiDrip whilst user positions mould and Confirm, then ActualInjectParams (previously set/sent via serial from computer/ESP32 Display), that include, for the ActualMould in use, first speed and distance programmed move (exact for each mould to fill just right), second holding speed and distance (to help get a good fill & finish), then a CommonParam Release speed and distance to back off and release pressure and be able to remove the mould, then back to Refill again, and loop that (with various other considerations, etc)

The driver/motor combo is using a 80V PSU, and will pull about 6-7.2A / 500-600W at max load… what type of (2PWM?) driver could/should use with SimpleFOC that can support this much power…? Stepper drivers | Arduino-FOC shows only drivers much less capable, and to be honest, I have no idea what to look for for larger drivers… I have never used a PWM driver with a stepper before, I have many years of 3D printer making, and all used step/dir…

Important for me (ATM, I think) is access to hardware level data use (which is why I chose STM32 with hardware quadrature encoder pulse input), and preferably for motor control as well (at least, AFAIK, FastAccel uses interrupts on Arduino, but the STM32 has a 16-bit motor control PWM timer), so that, at the time, seemed another attractive way of off loading MCU load, but it is my first time with STM32, so am probably a bit out of my depth… have been trying to follow some tutorials about STM32CubeIDE, it a magnitud more complex than ArduinoIDE, and I don’t really “know” C/C++, and some ST provided classes about motor control, but none of them use steppers with step/dir either… so now not sure how useful this PWM motor control is for me :face_with_monocle:

Anyway, impossible for me to make a short answer of anything, so sorry again for the rambling, feel sometimes like have bitten off more than I can chew, but guess can go back to the Arduino code and retouch for STM, shouldn’t need too much to work as is (although without hardware optimization, and without FastAccel :grimacing:)… thinking a moment about that, actually, other (slower) stepper libraries that on Arduino Nano cannot make enough steps for my use case, may very well be able to make about 4.5 steps more than previously found on Arduino, just from the increase in MCU speed​:crossed_fingers:… although another great point of FastAccel is the motor smoothness of the library, that I think was also down to using interrupts, so, YMMV …

Anyway, thanks for taking the time to read and answer, I will continue to investigate SimpleFOC and try and get other stuff working, and either see how can maybe use Commander to send motor moves from a motor library to SimpleFOC…? Would it be necessary to inform SimpleFOC of the intended motor moves…? Otherwise just send from another library and let SimpleFOC give me info (would have to see how to get that info back to the motor library, if I have to continue commanding move moves to assure compression…)… sorry, thinking a lot out loud :person_shrugging::person_facepalming:

Look, no offense but this is pretty hard to follow.

You are much less likley to get a response if we cannot quickly glean the information we need to help you.

If I understand correctly;

  • You plan to use a stm32 board for control.

  • You have a 1000ppr optical encoder.

  • You need to drive your stepper motor to a maximum torque and hold it.

  • You need to drive a stepper motor at 80v, 7.2 amp and need a driver board for it.

As of now, code and wiring are unimportant until you can find a suitable driver board.

Now I am unaware of any boards that will support 80v. There are plenty that will reach 600w but they cannot tolerate 80v.
Here is a non-exhaustive list of supported boards.

You’d either need to find or make a driver board that is compatible with your requirements, switch to a different motor, or use something other than simplefoc.

@runger THANKYOU for such a detailed summary and thoughtful description of issues and solutions, I really appreciate it!

in no particular order…:

I have used ESP32, and have one spare here, the Pico 2 have not even heard of, but will revise… I will investigate the driver options, but as Gloppy16 also mentioned, finding one that supports what I need may be difficult; the ones you indicate don’t reach both operating parameters of 80V and 7.5A (the MKS Dual FOC is 12-24v, the DRV8302 is 60v but max 2.3A, if I read correctly…), and I have no experience with these yet, so no idea about what to look for yet (investigation…)

The datasheet I have for the motor (2 Phase Nema34 Closed Loop Stepper Motor Datasheet.pdf, please google as the forum won’t let me upload pdf) would seem to indicate 2 Phases, but no idea how many PWM channels, and the simple images of this doc don’t look like the detailed examples of the stepper 2PWM, but maybe somewhat the 4PWM pages here (U1A, U1B = A+, A-:thinking:?)…? Again, never had this issue before as using step/dir was all I have done :pray:

For me at the moment, I would prefer using ArduinoIDE to code, and compatible hardware with Arduino libraries,… a reasonable STM32 stepper library search produces a couple of old options under the STM32duino alternatives, and a quick search of Stm32 - Arduino Libraries there are NO stepper libraries there at all… this is also why was hoping to use SimpleFOC, which does seem to be updated and control steppers on STM32 (although not thru step/dir)

Anything to come will have a learning curve (which is part of the fun, to navigate the labyrinth to the exit! Or find a blind end and have to take another route :person_shrugging:), I think I will go for:

  1. redo my Arduino code for ESP32, will probably be quickest - as have dual cores and endless interrupts, can probably assign encoder and motor use much easier… and can keep step/dir use, libraries, etc, I already have a planned Comparison function that can test once both Encoder and Stepper can work without stepping (pun intended) on each other…
  2. keep trying with the SimpleFOC libraries, on STM32, will need to investigate if can (probably) access the TIM1 to trigger that second timer to produce pulses… not too worried about acceleration curves (famous last words!) just yet, as the nema goes thru a 20:1 reductor, and will be pushing melted plastic thru an open nozzle into a closed mould until full, so hopefully the mechanical inertia of the system will compensate slightly for 0-100% power transfer in the large mould filling (which is the only state which will require that fast a move to worry about acceleration, all other moves are much slower, and also other smaller moulds will require less speed)
  3. look into high enough powered PWM drivers that will work with my setup to transfer fully to FOC, once I can understand what to look for in this type of component (what signals need from MCU to this board, etc, there must be already some comercial/industrial versions of the power necessary, but will surely be larger (as seen I have a very tight electronics space ATM, although going to a larger box is an option) and more expensive)
  4. programming directly thru STM32CubeIDE will be a bedtime youtube tutorial task, will also involve learning C/C++ properly, so could take a while, but seems that if wish to continue ahead with projects that have out-grown my use of Arduino (at least the versions that I have used so far), then most likely will be worth the while

Thanks again for the informative responses, and thanks for going thru my torturously long and overly complicated explanations, to guide my next steps, I now have a clearer idea of what is possible ATM, and what is possible in near future…
Hopefully in a few weeks can update with a working indication of the machine!

Cheers!