Rotary Module Loses Origin

I noticed that the rotary module immediately loses origin after pretty much anything it does. I can do the origin assist, then immediately do a carve, but if I have to cancel it and try to restart it, home, or simply “go to work origin” the rotary simply forgets where it is. Attempted to do a rough pass with an 1/8" bit, then used the built in bit assist to change to the straight groove v-bit to do a finish pass. Did a run boundary aaaand… the rotary module just spun. Checking the control the rotary says it’s at some thousands/millions of degrees. If I try to set B manually, it then forgets X/Y and I have to break down and just do the origin assist again with the new bit. However; this poses issue as now there’s absolutely no way to be exactly where I was in relative to my previous carve.

Another question that comes up is this; if the rotary module doesn’t actually have a ‘home’ position (via limit switch or other) then how would say, power panic work? This is a very serious limitation for those who don’t want to spend days letting the v groove carve EVERYTHING, it’s senseless, slow, and excessive wear on a bit they only give you one of.

Anyone else experience this? Is it a fluke of mine or is it by design?

Edit: with further testing, it seems the rotary module is just that far out in degrees for whatever reason. I did a test where I loaded a bit, set the origin, and made a top mark to compare. Then changed the bit, using bit assistant. Afterwards I homed the machine, and the rotary module said it was over -10300 degrees. So I decided to just let it go, tapped go to work origin, B said 0 degrees and began spinning… And spinning… Somewhere between 5-10 minutes before it stopped at the correct place.

Tapped home again, it rotated back about 120 degrees, back up to -10k… Go to work origin, same thing. It had to rotate back those 10k degrees despite only rotating partially during homing. Though it seemed to return to the proper place, just takes awhile. I’ll do more testing.

1 Like

Doing more testing and just letting it go after a roughing pass… Final B in the gcode was B144450.00. So since it has to backtrack all those degrees to reach the origin… Divide by 360, is 401.25 rotations, the speed is listed as 45 degrees/s, so 8 seconds for a full rotation. 3,210 seconds, or 53.5 minutes of the rotary module spinning away to reach the origin again. Currently at 40 minutes of watching the rotary spin endlessly and hoping it gets the origin right after using bit assist to change bits. I would think the controller could do the math to find the original origin without having to backtrack that far. I’ll update this topic if it manages to start and if it manages to start correctly.

Edit: It took an hour and 2 minutes to reach the origin again and start cutting. The Y seems off a little bit though, but that could be simply from going from a 3.175mm flat to the straight groove v-bit. Sadly with how long it took to just simply get started, I’ll have to let it run unsupervised… I somewhat expect it to break itself, but one can hope it doesn’t. I still feel like this can be mitigated with some simple math in the controller instead of having to wind ALL the way back.

Note: This was for about a 50mm tall, 30mm wide carving. Using a 3.175 flat with 1.25mm stepover, 1mm stepdown for the roughing pass with 0.5mm alloance set in Luban. Final pass is 0.12 stepover with the default depth of 17.5 since it should just be fuzzing off the last 0.5mm. If all goes well, 7-8 hours overall is much better than 30+ using the v-bit alone, but still that harsh lag in the middle.


That is freaking hilarious. Please create a bug report on GitHub, or email support, that needs to be fixed.

LOL, I agree that’s insane. I haven’t taken mine out of the box yet, but it’s beginning to look like I’m in for another steep learning curve…

I’ll have to do a test later today, but in theory going back to the original B shouldn’t be too difficult. At the final B, divided by 360 to get total rotations, which in my above was 401.25 rotations. Drop the full rotations, leaving 0.25, multiply by 360, nets 90 degrees. So manually spin back 90 degrees, set B origin, and boop should be ready to go again. If it shows the same final B in the control menu, subtract the 90 degrees and crank it back to the result and set B origin. I don’t know which direction it counts out, so I’m not sure which direction to spin for correction. Again, I’ll see about a test this evening.

Edit: The math should work out in reverse as well. Divide the end B by 360 to get rotations, drop the partial rotations, multiply full rotations by 360. Which nets B144360, that should be the number you turn to in control if it shows that. I’m not at home to check, but feel free to test this and let me know.

Hate double-posting, but I’ve done some tests. Did a roughing pass, should have used a ball-nose but I don’t have one long enough for the stock I have so I used a flat end @ 1mm allowance in luban. ETA was 4 something hours, took around 2 so ETAs on Luban are useless. Anyway, when it finished, I used the bit assistant tool to swap in the straight groove v-bit and then went to Control. While there, it said B was -236890.00 degrees. So I did the math, divided this by 360, ended up with 658.0277>infinity, so I went with the whole rotation method. Multiplied 658 x 360, got 236,880. Ten degrees off, neat. Rotated it to B-236880.00 and it seemed to line up with my origin! (I have a tendency when setting my origin to have one of the clamps directly up and use one of the chuck wrenches to line it up exactly, actually cloned it in fusion and printed in PETG as not to scratch the module) Went to set origin and set the B, and selected my finish pass file. A quick run boundary looked good so I started it. It’s currently running, but so far it’s looking good. Being another 100k out, I’m sure it would have taken 1.5-2 hours to reset if I didn’t do the math myself. I’ll update this again on how the carve turns out if it was the actual origin and all went well.

1 Like

You should consider adding G92 to your list of tools for that. Might be easier to set B to 10 (I think) in your example.

The proper fix for this would be for luban to G92 B0 after every full rotation so that it never has to travel more than a full rotation.

That functionality is done by slicers automatically on the E axis, usually at layer changes

And even better solution might be for the firmware to limit the rotation of the Axis to plus or minus 180 degrees, though there’s some issues with that.

I tend to try not editing the gcode directly and find ways around it for public findings (and I edit enough gcode at work, I don’t want to stare at it when at home :wink: ). Instead it’s a bit easier to do some simple math quickly on the touchscreen. Divide by 360, remove decimal, multiply by 360, match on touchscreen is quick enough. :slight_smile: Also, can never be too sure if the Gcode is actually how it’s going to end. An example? The snapmaker apparently moved B after it was done. Checking the Gcode file, the final B was B236970.00 vs the B-236890.00 the snapmaker said it was in control. Why? I don’t know. Maybe from the homing procedure when doing the bit adjust. It’d require more testing for a good gcode method. Maybe manually adding in the movement and a G92 at the end so even if the snapmaker makes any moves, it won’t be very far.
I would think for a proper solution instead of doing a G92 after every rotation, which would make the file that much bigger/extra commands (though admittingly not much) it might be better for Luban to just do the math so the final move comes back to a full rotation so it sits at the origin, THEN G92s at the very end. This way, during a power loss event, it already knows how many degrees it’s spun, and can continue from there. Similar to the gcode method I explained above. Although I don’t know exactly how they implement power panic, I would assume it either writes the location after every line (like a Creality), or if it writes the location upon detecting failure (similar to a Prusa).

Sorry if it seems rambling, I might be completely off the wall by now with how my brain is mush from being up all day at work. If you have a rotary, please do some testing and update your findings here, maybe together we can come up with an easy solution for everyone. :slight_smile: So far what I’ve found seems promising, if I can simplify it further, I’ll definitely update here. Sadly, I can only do one test every other day or so. :frowning:

I also enjoy these types of discussions. Likewise.

My thought process was, as I usually have a terminal hooked up, do exactly the same thing you described but instead of jogging by 10 degrees issue G92 B-10 on the terminal. Then when the next program starts it sorts itself out when it moves to B0. Same amount of work, different method. As you noted, you could also put that G92 B-10 into the gcode footer in advance.

That sounds fairly alarming. Gcode is, as you know, deterministic, so there really should not be any unexplained happenings going on.

Yea, which is why I think the most important thing is you create a ticket on the Luban issues channel so the developers can think about this and fix it instead of going round and round forever on the forum, which staff doesn’t monitor :rofl:. Issues · Snapmaker/Luban · GitHub

In a nutshell, the power supply has a capacitor that stores energy during a power failure, as well as a binary status it sends to the controller indicating the presence of AC. When AC drops out there’s a few moments of stored energy left where the controller pauses everything, writes the state of important things to flash memory, attempts to make the machine safe, and then halts the cpu.

The things it writes to memory are the following:

typedef struct __attribute__((aligned (4))) {
	// checksum of this section
	uint32_t CheckSum;
	// temperature of extrucders
	int16_t HeaterTemp[PP_HEATER];
	// speed of work
	float PrintFeedRate;
	// speed of travel
	float TravelFeedRate;
	// CNC power
	uint8_t cnc_power;
	// laser Power
	float laser_percent;
	uint16_t laser_pwm;
	// target temperature of heat bed
	int16_t BedTamp;
	// position of stepper on last move
	float PositionData[NUM_AXIS];
	// position shift between home offset and workspace offset
	float position_shift[XN];
	// line number of last gcode
	int FilePosition;
	uint32_t accumulator;
	// fans' speed
	uint8_t FanSpeed[PP_FAN_COUNT];
	// if this section is valid
	uint8_t Valid;
	// working toolead when power-loss
	uint8_t toolhead;
	// Gcode source
	uint8_t GCodeSource;
  // active extruder
  uint8_t active_extruder;
	// file name
	char FileName[PP_FILE_NAME_LEN];
  int8_t active_coordinate_system;

	bool axis_relative_modes[X_TO_E];
	bool axes_relative_mode;

	int16_t feedrate_percentage;
	float   live_z_offset;
} PowerLossRecoveryData_t;

It’s a regression! I setup the laser and decided to look at the gcode and at the end?

Laser L3:
G0 B0.00 Y24.70
M107 P0
G92 B0.00
; G-code END <<<

This was gen’d with Luban 3 (I hate Luban 4 thusfar, but I’ve been generating my CNC stuff with L4 as it has real stepover/stepdown options vs ‘density’) So I did more tests.

Laser L4:
G0 Y27.23 B0.00
G92 B0.00
M107 P0
; G-code END <<<
G0 Z0 F150

CNC sees a regression.

G0 B89460.33 Y0.10 F2400
G0 Z27.50 F1500
G92 B180.33 (doesn’t zero it out, but it origin’s minus all the full rotations like the method I mentioned first)

G1 X-3.28 Z14.71 B-90901.46 F790
M5 (Just stays there)

I also notice, Luban 3 goes positive, whereas 4 goes negative, this might be where my annoyance it does conventional vs climb is as well. I’m finding even more reasons to hate version 4. I’ll do some more tests before dropping an issue on the github, I want to make sure I have examples and repeatability first.

So it’s a Prusa style power panic. The MK3S has the same setup, when the power cuts, it sends a signal to the motherboard which immediately shuts off the heaters and uses the power in the capacitor to move the hotend up and away from the print to prevent melting/blobbing and writes to memory.

Edit: More testing with Luban 3, it’s a bit annoying to do the math, but density is literally just divide 1 by what I want my stepover to be (i.e. 1.25mm stepover is 0.8 density). One annoyance, however, is apparently the “allowance” option, despite being in Luban 3, does absolutely nothing. I generated a file with 0 allowance, 1mm allowance, and 12mm allowance and did a compare; they’re exactly the same. So for roughing, I may have to do some tomfoolery and simply lift the bit a little after setting origin to make it ‘longer’ so it doesn’t go as deep and leaves material for the finish pass (and hopefully allow cusps to be removed on angles)

Edit 2: Ugh, machines reversing axes are a pet peeve of mine. More tests, disregard what I said about Luban 4 going reverse, it just spins backwards more than 3, they both move in a “positive” direction… That being said, positive in the gcode == negative on the rotary. That’s why it conventional cuts instead of climb cuts… Reminds me of the Multicam CNC I run, where Z+ is down, and Z- is up, so frustrating. So to get it to climb cut, I have to mass replace B with B- and vice-versa. Another annoyance is the fact it works from the tailstock end towards the rotary, which means if I use the tailstock, it cuts that end off first, negating it… It’s like Luban just generates the program completely reverse of what it should.

1 Like

That’s good stuff, thanks for sharing. I hope this ends up resulting in improvements to L4. It could be good stuff. Someday. In the meantime there’s Solidworks CAM for me lmfao

Oh, forgot to post a workpiece of testing my theory. I think Luban called for like 40-50 hours at this size using the V bit alone. Instead I did a roughing pass, which took about 2 hours, and a finish pass of 2.5-3 hours with me manually resetting the B origin between.

Edit: for reference the blank was 90mm, by 44.5 diameter.


Alright… more testing was done and I found out some interesting bits… First information:
Model was “Small Desk Ornament Vase/Pen Holder” By Rejutka: Small desk ornament vase/pen holder by Rejutka - Thingiverse
Setup using Luban 4.0.4:
1st pass: Rotation mode, 1mm allowance, 1/8" Double-flute down spiral @ 800mm/min, 1mm stepdown, 1.25mm stepover.
2nd pass: Rotation mode, 0mm allowance, Straight groove v-bit @ 300mm/min, 17.5mm stepdown, 0.12mm stepover (defaults for epoxy basically)
G-Code Post-processing: Swapped the max_b and min_b values, and made them reverse -/+ (I think this is just for the run boundary but did it anyway), replaced all B with B- and vice versa. Noticed they DO include a G92 at the end, specifically for my rough pass, G92 B90.01 (Which was modified to G92 B-90.01).

So, that out of the way… It’s the snapmaker that brings issue. I ran my roughing pass and verified the machine takes the G92 just fine.

Now is where it gets a bit spicy… I ran through the Bit Assist to swap out the bits and then checked the control again;

Snapmaker… Why? The hours of rotation are falsely manufactured. However; the math still works.

Final B in the program was B-111330.01, doing the math means whole rotation origin is: 111,240.
Control after bit assist was B110837.00, after math is: 110,520
A difference of two rotations, 720 degrees. So it does keep the correct point, it just adds 307 unneeded rotations. So I took the bit assist number and rotated to B110520.00, and swapped tabs and set B origin. Loaded up the finish pass and everything works great. I will say taking the time to swap B/B- to make it run in climb mode is worth it, much quieter and the surface finish is much better too. Here’s the final piece, kinda sad I used it on a junk piece of wood with imperfections now… :slight_smile:

If anyone wants, I can see about writing up a full tutorial on multi-passes from my findings. Still to investigate though; test before this my X origin somehow changed and it tried carving about 10mm to the left, which of course failed. I don’t know if the snapmaker ignores the X origin (I suspect it does in rotation mode) and I moved it during bit assist and forgot to put it back so it just went there, or what happened. So good idea is to in luban or the controller move X/Y/B back to origin before starting. Careful of Z as not to have a bit crash.

Edit: Looking at the gcode, yeah… There’s absolutely no X movements, so it just goes wherever X was left last. It really should have a G0 X0 at the beginning. Being able to add a header/footer to each file like a slicer does would be handy here. Instead of having to do it by hand for every file. Add some safety movements to ensure something like this doesn’t happen.

1 Like

Thanks so much for sharing. It’s stuff like this that would make me reconsider buying the rotary module.
(maybe if they give a 40% discount in the flash sale :grin:)

Thank you so much @Skreelink for sharing your knowledge and research findings. I’m definitely interested in your tutorial.
As a newby in cnc, 3d printing and laser, I feel a bit intimidated when it comes to g-code and such mysteries. But easy explanations using simple maths helps a lot to understand a little more, not only how the machine works, but also other topics in this forum.

Thanks, here’s the tutorial I did on multiple passes on the rotary module:

I’ve also done a tutorial on how to make a repeatable setup for the laser:

@Skreelink , you rock!!
I read the tutorial, and you filled so many gaps in my knowledge. And I already feel the thrill to go and edit g-code.

I will certainly read the laser tutorial in the future, thank you so much!