WIP: Marlin on Jackpot

In researching ESP32 options I just learned that Marlin can run on ESP32, and there is a component that can serve a web page and drive (the rest of) Marlin, also running on the ESP32.

I decided to give it a try and here is what I’ve got so far:

  • Got Marlin official release to compile for ESP32 target.
  • Got 7 endstops working, showing in M119. (5 endstops + 1 probe, assuming 7th works)
  • Got 3 (of 6) TMC drivers to show in TMC debug command and setting/showing motor current is working
  • Got Web UI installed (version 2.1)

I haven’t gotten the motors to move yet. Fortunately it looks like the MKS Tinybee uses the same chained I2S driver scheme as the Jackpot board, and the pins file looks promising, but I am missing something somewhere and the motors are not moving. I am pretty sure I can find it eventually.

I confirmed that the TMC current settings were working by setting current and feeling the holding torque by hand. For low current, it’s easy to skip steps, and with high current, it’s harder to skip steps.

The serial multiplexing (to get TMC UARTS working for slots 4, 5, and 6) is possibly more of a challenge. I did find some serial multiplexing option (TMC_SERIAL_MULTIPLEXER) for TMC2208 used by FYSETC AIO II but it appears the product doesn’t match (no TMC2208). But maybe it has some hints for implementing serial multiplexing that the Jackpot uses.

Also the versions are a little strange because not all of the tweaks to get ESP3DLib working are integrated into Marlin. Luc (who develops ESP3DLib) has a fork with the updates that are necessary for ESP3DLib 3.0. The official Marlin release links against ESP3DLib 1.0 by default, and only ESP3D-WebUI 2.1 works with it.

Maybe some issues could be resolved in ESP3DLib 3.0, and ESP3D-WebUI 3.0 requires ESP3DLib 3.0 and I also want to try that.

So for next steps:
It probably doesn’t make sense to chase I2S streaming on ESP3DLib 1.0 if I am going to change to 3.0, so I’ll try that set of software first. Maybe stepping then works on drivers 1-3.

If it doesn’t “fix itself” on 3.0 then I have to dig into that.

Then look at multiplexing and see if I can learn what TMC_SERIAL_MULTIPLEXER was trying to do, and if I can apply it to the Jackpot board.


Do you think this would this make it easier or more difficult to put a pendant on it?

What’s the benefit of Marlin on the Jackpot? Or is this just an exercise to see if you can?

I never ran a previous version of the CNC with Marlin, but I thought one of the main benefits of the decision to make and produce the Jackpot with FluidNC was that it was running a firmware built for CNC, rather than one built for 3D Printing.

I don’t know if it’s easier or more difficult to add a pendant. I am thinking it is about the same but if I need changes in the firmware then that part is easier.

Part of it is to see if I can, and if it works then it’s a backup option. Also the Dual-X LR3 (“IDEX”) will work out of the box with the right configuration whereas FluidNC would need to start an implementation from scratch. I was reminded a couple days ago that G4 P500 on Marlin waits a half second and G4 P500 on Grbl waits 500 seconds, and more broadly there is some friction in switching between the two.

I have never seen Marlin stutter or inexplicably pause. I will have to watch closely for that to see if the Wifi ever causes hiccups in Marlin/ESP3DLib like it used to for FluidNC, or if it ever has memory issues.

One of the features of ESP3DLib is Lua scripting, which is very intriguing. I don’t know yet where exactly the Lua scripts are allowed, but if it is allowed in gcode then that could open up things that are not currently possible. For example, probe four corners and G92 in the center of the workpiece is maybe possible with an Octoprint plugin or a new special function in Marlin, both of which are impractical for all but very high value functions. A Lua script would make this available to casual use at the user level.


I was curious about this, as it seemed to me that the Jackpot would be kind of cool to run an MP3DP on. I think it has all of the necessary outputs, including PWM for a BLTouch.

Might be light on 12/24V MOSFET driven outputs. The 2 on-board probably needed for fans, use other outputs with external MOSFETs for hotend and heated bed?

I don’t know that Marlin would take advantage of the wifi or bluetooth link, so a serial UART would be necessary. Could possibly use the TFT35 in touch mode?

I am not sure that Marlin offers an advantage over FluidNC for CNC work though, besides maybe familiarity.

Yeah, I notice that the mks Tinybee has marlin release.

It looks like everything, including their webpage, is here:

The ESP3DLib adds wifi connectivity and acts as a web host so you wouldn’t need a Raspberry Pi or other sender. You can launch a job and disconnect if you wanted. The JavaScript part of the Web UI is split off into its own repository but it’s essentially part of the same project.

Here is what I’ve got now on the Jackpot board, no USB or other UART needed.

It is a fair point that it may not have an advantage over CNC specific software. That will depend on a variety of things. I just wanted to clarify that the web UI is integrated into the ESP32, so in that regard it is similar to FluidNC.

Maybe the TFT35 can plug into the Jackpot expansion port in case someone is jamming your wifi, which accidentally happens at RMRRF.

Ok, progress.

I dug into Luc’s fork of Marlin, and with no UART stuff it runs fine and I can get ESP3DLib 3.0 and ESP3D-WEBUI 3.0 running. But unfortunately there is some conflict with ESP3DLib 3.0 (actually the platform it requires) and the TMC UARTS. So that’s a no-go. That is way above my expertise.

Then I tried building the old Tinybee code, which is a snapshot frozen in time. It is so old that it does not accommodate EXTRUDERS = 0, and when I try to set up an extruder it complains about pins for thermistors, heaters, blah blah.

While looking for pins to fake heaters etc., I realized my I2S streaming pins were wrong! I fixed that on the current official release, and guess what – now X1, Y1, and Z move on command.

Next is X2 and Y2 (and rotary axis) if I can figure out serial multiplexing. (X2 and Y2 move, but microstepping is wrong and current is wrong, maybe other things too.)

The select lines that direct UART traffic are not regular GPIOs but are outputs of the I2S stream. I don’t know if this adds difficulty or if it’s all handled by the HAL. Assigning I2S output pins for the stepper drivers required no special magic, so maybe I can treat them like regular GPIO pins and it won’t be too bad.


This is just awesome. Love seeing you take your knowledge and try something no one has tried yet. I wish i knew 1/4 as much as you do about this stuff! Keep us updated. Love following along!

Uh crap, I stand no chance then.

At least you don’t have to worry about the sensorless homing stuff. I am really not sure how Bart made that happen, I hope they are treated like regular GPIO. The multiplexing stuff is not something I fully understand yet and when he was working in it just remember hearing “I have an idea” then "well I have another idea… We had a whole other board designed and made and were testing before he figured out how to make it work in fluid. I hope it isn’t that complicated in Marlin.

After some hacks in the TMCStepper library (couldn’t do it in Marlin alone), I think I got addr + mux serial working, and it appears to work:

All axes are moving (except haven’t checked rotary axis).

Now I’m seeing a problem where X2 moves approx twice the distance as X1, and Y2 moves about twice the distance as Y1.

I tried swapping the pins in the pins file and the far side (board sockets “A” and “B”) still move twice the distance as X and Y, so it’s not the firmware sending twice as many steps per mm. Either the I2S is not being encoded correctly, or I suppose in theory the microstepping could be off, although it looks like they match in the M122 report. But it’s also possible that the serial is not working as well as I think it is, and I’m fooling myself somewhere in there.

I sure hope it’s not the I2S streaming because that is going to be spooky, though I might give it a look over and see if I can get any idea of what it is doing.

No freaking way!

You know, I don’t actually understand any of this, so random things I would check…does the current set differently for each A B stepper? That is on the same command line as steps? It is always double, or is it just not being set and defaulting to something?

Oh, I spoke too soon. Even though the currents are showing what I expected, the UARTs are not working properly. Still a ways to go. It occurred to me that the multiplexing signals might be late due to the I2S DMA buffering, or it’s something else entirely (even X1 and Y1 don’t look right). And a brief dive into the I2S, everything looks about like I would expect I guess.

I’m not stuck yet.


I feel like you might have just turned your hat around and are about to get serious.

So this doesn’t help? The tinybee marlin config mentions tmc in it.

I have a tinybee that i am running Fluidnc on. It has esp32 so the fact that they already have marlin figured out, I thought it would help. (But I did move my 8825’s to it, I did not run the tmc’s.)

TL;DR: A bunch of technical details, blah blah boring stuff.


The stepping is working. The UART scheme is where the Jackpot is different from the Tinybee and also from the FYSETC E4.

For completeness, UART is how it sets the microstepping and the current (and stealthChop and other junk but primarily microstepping and current) in contrast to the jumpers/potentiometer on the older stepper drivers.

The Tinybee doesn’t support the UART on the 2209. There is no connection so it won’t ever work unless you do some serious soldering.

The FYSETC E4 does have UART connection and assigns each stepper driver a different address 0 through 3 so they can all connect to the same wires. When the controller makes a request, it includes an address so only one of the controllers pays attention and responds. If two controllers had the same address and shared the wires then they would both take action (setting microsteps for example) and they would try to talk over each other in their responses.

There are only four possible addresses (limited by TMC2209) so it is ok for FYSETC E4 with four drivers, but to get five or more drivers you need another strategy. This is mentioned here. The solution wasn’t explained in detail (or my forum search couldn’t find it), but the idea is to have an analog switch to temporarily connect/disconnect multiple drivers that have the same address.

In the Jackpot implementation, the X driver has address 0, the Y driver has address 1, the Z driver has address 2, and A, B, and C all have address 3 but they essentially go through a 1-to-3 multiplexer that connects only one at a time of A, B, or C. (X, Y, and Z are always connected.) This is unique to the Jackpot board; no other board supported by Marlin has this.

My off-by-two error above I am pretty sure was just bad microstepping values as as a consequence of messed up UART communication (and my bug also made it incorrectly report OK when in fact it wasn’t). I think I have the I2S step generation solved, and I have X, Y, and Z UART solved, both of which are simply using the existing features that the FYSETC E4 and a couple other boards use.

The 1-to-3 multiplexer is (still) the difficulty.

The TMCStepper library is used by Marlin, and the TMCStepper library has a little bit of a UART multiplexing feature, but it doesn’t cover our use. One of the bigger problems is that it can only use “real” GPIOs, and it has no concept of the virtual pins that are the I2S outputs that Marlin defines.

Yet the TMCStepper code feels like the “right” place to add the multiplexing because it has a setup phase before it starts talking, perfect for configuring the multiplexer when it’s talking to the A, B, or C drivers. But it can’t use the I2S outputs. Adding the mux control at the point-of-use in Marlin would mean a much more complex modification spanning a ton of files, which is theoretically possible but extremely nasty.

My current thought is to add an optional callback function into the TMCSteppers so they can invoke a function during the setup phase before talking. Then the function is defined at the Marlin level and does the mux control and is able to use the virtual GPIOs.

That’s my next plan. Maybe it sounds complicated but it shouldn’t be that bad.

1 Like

Jamie how did you get the M122 marlin style output in fluidterm for the jackpot?

Well, duh… X2 is twice as large as X1 :slight_smile: HTH

Same way some of my classmates did it in their CS labs: hardcoded the output…