Lemon Pepper (Stepper) simpleFOC board (STM32G431)

Hi everyone! I have been working on bringing up a new motor driver design and am at the point where it’s probably useful to make a post!

The Lemon Pepper board is a G431 based stepper and BLDC motor driver, with input voltage up to 48V at 1.5A, three inline current sense amplifiers, and 60V overvoltage protection. It uses the high resolution MT6835 in both SPI and ABZ modes, intended to be (configured and then) used with the low overhead STM32HWEncoder sensor class. The input connector can support step-dir (as a drop-in replacement for “dumb” open loop steppers), I2C, CANbus, as well as USB. The form factor is designed to mount to the back of NEMA 14 motors, but boards with larger outlines have also been produced to work with NEMA17 motors. The board is also single sided so friendly for both JLC and home assembly on hotplate. If assembled at JLC, the boards come out total to about $18 each. The BOM and board design have both been optimized to minimize cost and component count.

I have found some things during bringup that I will change for the next revision but this board is working really great for me so far! I am able to easily hit 300 rad/s at under 100mA (no load) on one of my steppers I had lying around. Still working on getting current sense up and running.

Here is the Github, I am still actively working on adding changes as bringup moves along:


Very nice project @VIPQualityPost :slight_smile: Just for curiosity some questions:

  • Which gate driver IC are you using in your design? What IDE should be used to import the firmware project?
  • Did you implement some kind of higher level protocol to be used over CANbus and I2C ?
  • When you say USB as input ar do you mean serial communications using the serial port?

Regards and thanks for sharing such nice project:)

1 Like

Looks really good.
Are there any extra GPIO pins exposed for e.g. an endstop switch?

@JorgeMaker it’s the ST L6226Q driver.
I don’t have a higher level protocol now, it just has the hardware to support those interfaces. You can upload using PlatformIO over DFU or SWD (using tag-connect header). I guess you could also use Arduino IDE but I don’t really know how to set things like build flags using that.
I wrote some simpleFOC canbus protocol for my last boards but it’s not very fleshed out at all.
Yes, it can be used as any type of USB device, it’s defined by the firmware. I am just using USB CDC (i.e. as virtual com port for serial right now).

@o_lampe No, unfortunately there is barely enough room as is, but maybe I can squeeze one or two small pads on. I don’t think any connector can fit. It’s really tight on the board.


Looks really good.
How did you mount the magnet onto the stepper spindle?

I have some diametric ring magnets, so I mounted it on the shaft, then put a strong glue in the center (so no glue between magnet and shaft, just the glue holds onto both surfaces separately). I centered it by hand, it’s off by a bit, maybe 0.1mm but it’s hard to notice and doesn’t seem to effect the sensor too much. I am hoping that the MT6835 calibration will improve the linearity even further.

Now that bringup has moved along smoothly I have prepped the next rev of the board!

  • Fixes for all the bringup issues
  • I was able to fit on a few solder pads for a timer pair (for use with an external AB encoder!)
  • Also adding 3 GPIO (including some other timer channels that could be used for general PWM use) @o_lampe :smiley:
  • I was also able to add hardware UART as a supported protocol on the input connector!
  • An ADC channel was setup so that Vmotor can be measured in firmware.


Banging my head on the wall here…
The PWM frequency I measure is half of what it should be (16kHz instead of 32kHz).
I can’t find the root of this- I am using a custom clock config, but it looks fine in CubeMX (and the generated code matches what should be generated) and initializing doesn’t throw any errors from the HAL RCC configuration.

The really weird thing is that if I increase PLL R clock div, it doesn’t appear to effect the PWM frequency. Moving from /2 to /4 should half the system clock frequency (and therefore PWM as TIM2 is derived from APB1) but no difference on my scope. Another funny thing is that SystemCoreClock global variable setup by the RCC code shows 336MHz with this configuration, even though it should be half of that. Changing the clock div from /2 to /4 does impact this and it reads 168MHz, although again that is twice of what the real frequency should be. I checked this also on my older AIOLI-FOC boards and indeed those are also running the PWM at half specified frequency, even though I also have a custom clock config on those. I did confirm my crystal HSE is actually 12MHz as well.
@dekutree64 @Valentine any ideas? I know you two did a lot of tinkering with clock code…

On a more positive note, someone recommended a neat idea of making a heat sink for the board as it’s getting quite warm at >1.2A. I tossed together a little design and got a quote from JLC. For 35x35x7mm part, the CNC machining service they offer quoted $10/pc for a qty of 10 parts, which isn’t too bad, although I was hoping it would come in a little cheaper.

1 Like

Just figured this out- the print is wrong if you don’t define HSE_VALUE 12000000U, which makes sense as the default value is 24MHz, double what I was using… but the actual frequency still seems off, even though the PLL should operate the same regardless of input frequency.

Very nice disipator :slight_smile:

How many amps can your design handle? Do it offer Step/dir interface ? Do you think it wold be possible to adopt it to work with NEMA 23 motors?

Not sure about the clock, but for the heatsink you might try a quote for 3D printed aluminum too. It’s surprisingly cheap for small things.

Or for CNC, what are the tightest corner radii, like around the 4 pin connector? Standard length end mills are 4x as long as they are wide, so for 7mm thickness you should plan for a 2mm diameter mill (1mm radius).

1.4A DC 2.8A peak


Yes, actually someone in the discord also ordered this board with NEMA 17 outline/mounting holes. It could be done for NEMA23 but to be honest, I think you can make a design which is cheaper and with higher current capacity if you have the space. I was really constrained with the 14 design.

Thanks for the tip! I’ll check the design.

Maybe next year I’ll try using your design to upgrade my CNC router to replace the driver box with boards based on your Lemon Pepper design … running SimpleFOC :slight_smile:

1 Like

Hopefully!! I’m really trying to get my 3D printers running using simpleFOC :smiley:

There has also been some effort by @Copper280z (who has some lemon-pepper NEMA 17) for getting a Klipper node working and @Juan-Antonio_Soren_E for a motion planner, so it really feels like we are getting close !!

1 Like

Fixed the issue with the clock speeds!
Actually, it seems like the HardwareTimer code uses the SystemCoreClock as the basis for calculating the prescaler to the timer for PWM. So if that is wrong, then the derived PWM frequency is wrong. Yesterday I posted about #define HSE_VALUE 12000000U but actually, this doens’t go in main, it needs to go as a compiler flag !! So in platformio.ini, the “real” HSE clock speed should be passed in:

build_flags =
        -D HSE_VALUE=12000000U

@Valentine , @dekutree64 you may want to try and add this for your boards, as while the main clock speed will still be running at your frequency derived from the PLLs (so loop freq should be unaffected) , the actual peripheral frequency for PWM and others used may be off by what the code “thinks” your HSE actually is.