MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.1k stars 19.19k forks source link

[FR] Software correction for laser SLA distortion #6001

Closed sfj13 closed 3 years ago

sfj13 commented 7 years ago

First off, amazing work on Marlin. I have had a great experience with the firmware and I appreciate all the development that has gone into it.

I am developing a low cost SLA printer using stepper motors and mirrors mounted in a galvanometer scanhead type arrangement to manipulate a laser.

There is a non linear non symmetric distortion that occurs with a galvonometer setup. This is present due to the distance from the mirrors to different points on the build plane changing as the laser moves. The effect is that a square would end up looking parabolic on its sides as if you were to stretch the corners out.

I created a relationship between the mirror angles of a galvanometer type setup and where the laser will hit on the build plane. I am looking for help or advice implementing this correction into Marlin.

If anyone is interested in helping me set this up, my printer is working and ready to test this type of correction.

This could have applications for laser cutters that use a galvanometer for positioning as well.

I am very limited in my coding experience so I am reaching out to see if anyone is interested in this.

I think an implementation would do something like this...

Take the current X and Y coordinates and calculate mirror angles from them. Calculate the mirror angles from the coordinates of the destination that is desired. Use the difference in mirror angles to calculate the number of steps required to make the move.

For large moves, the move will have to be broken up into smaller moves to preserve a linear interpolation between the two points. If I understand correctly, delta type printers do something similar.

The calculation has four intermediate values that need to be calculated before the mirror angles can be found. These involve inverse tangent and inverse sine calculations and taking the square root as well. Would this be too computation intensive to be calculated as the G code is processed?

I'm trying to do this myself currently but my coding skills are lacking and I don't have detailed knowledge of Marlin.

Thank you for taking the time to read my post and any information is greatly appreciated.

Nerradia commented 7 years ago

Hello svj13,

I just created my account to tell you that I am looking for the same thing, but my coding skills are not that great... If you managed to make it, please tell me ! (I'll try on my own for the moment) I think that could be awesome to use steppers as galvo, but what about the laser focusing ? The length of the path of light will not be constant. I imagined that I could mount the laser source on a slider, to cancel this length difference.

Thank you.

marcelogaio commented 7 years ago

Hi @sfj13 Is there any advance on this? I am trying to control a couple of galvos with Merlin but so far I cannot seem to understand how to do so.. I should be able to get out of Marlin a digital signal with the position (for example 12 bits) that goes into a DAC, that connects to the galvos. The questions are:

I have a lot more questions I am trying to solve, but these two are essential...

thinkyhead commented 7 years ago

To support SLA galvanometers we'd basically need to do a slightly complex rewrite of Stepper::isr, adding proper support for galvanometers to replace the XY steppers in that method.

Elsewhere we would need to account for the lack of XY endstops, and make many other similar changes throughout the code. I believe that it is totally doable, but it will require great care and attention, and a lot of #if ENABLED(GALVO_XY) blocks strewn around.

What is the maximum bit-rate of the DAC?

thinkyhead commented 7 years ago

Thinking further… I've never used galvanometers, but I'm guessing that they don't change position instantaneously. So we'll also need to know how fast they can move (to know how long an "instantaneous" move requires).

The other thing that occurs to me is that apart from the Z stepper, there's no other stepper logic needed at all. Everything extruder-related would go away. There would be no need to do coordinated stepping for 4 axes, but only 2. So a large amount of code will be completely disabled from the get-go. It will be simpler to make a separate Stepper::isr just for galvanometer-based XY, plus stepper-based Z.

I've done large-scale strip-downs and refactoring of Marlin before, and it's always an adventure. The first step to support an SLA setup will be to get Marlin to compile with EXTRUDERS set to 0, with no XY endstops specified, and so on… Only then can we start to think about the galvo interrupt code.

thinkyhead commented 7 years ago

Would this be too computation intensive to be calculated as the G code is processed?

Not at all. For one thing, not needing to generate 80 step pulses (or many more) per millimeter for the X, Y, Z, and E steppers in coordination will save a huge amount of computation. More than enough to compensate for the extra maths.

I have had a great experience with the firmware and I appreciate all the development that has gone into it.

I'm gratified to know it's working well! I did a comparison with 1.0.2-2 recently, and you can really feel the difference in the UI, for example. Even the character-based LCD is noticeably more responsive. It's been 2 years of incremental improvements, most small, but some of them achieved dramatic reductions in CPU use. We can all be grateful to Github, Patreon, the Caffeine Gods, and some really talented and tenacious contributors.

If anyone is interested in helping me set this up, my printer is working and ready to test this type of correction.

I'd be very interested to help out, though I am spread a little thin. I can also set up simulations (in Unity3D), if needed, to help get all the maths right.

marcelogaio commented 7 years ago

I had no idea about Patreon!! I will definitely contribute on Patreon right away!

marcelogaio commented 7 years ago

As for the help, since I am very interested in getting the galvos working, I am willing to help as much as I can. I have a 2 axis galvo I got on banggood (the name gives me a laugh every time ;) and I am setting up a DAC and an op amp (to generate the +- 15 v needed)

For the last week I've been looking at Marlin trying to figure it out. Based on your comments I'll give a look to the Stepper routines...

Would it be good to start a branch for galvo version or is there a branch (of v1.1) already open?

Sorry for all the questions!!! I am excited to see there is interest in integrating galvo support into Marlin!

marcelogaio commented 7 years ago

@thinkyhead

What is the maximum bit-rate of the DAC?

Usually i've seen tests with 12 bits as well as 16 bit ADCs. It all goes down to the resolution we can achieve. For a 12 bit ADC you would get 4,096 steps, and for a 16bit ADC you would get 65,536. Should there be a parameter to specify the ADC resolution (12/14/16/etc)?

Thinking further… I've never used galvanometers, but I'm guessing that they don't change position instantaneously. So we'll also need to know how fast they can move (to know how long an "instantaneous" move requires).

My galvos (standard, cheap ones) are supposed to be 30kpps. They are meant to be used along with an ILDA laser show card. They are supposed to be able to draw an ILDA standard test image without showing any flicker. There is not a lot of documentation on what 30kpps exactly means, but apparently it goes down to the ability of handling around 1000 moves per second at a max angle of 8 deg. The response apparently is in the micro seconds, so it's pretty much instantaneous!

There are a couple more things to think about:

thinkyhead commented 7 years ago

All of this is doable. My suggestion would be to start from a snapshot of the current code, either the 1.1.1 tagged release or the bugfix-1.1.x branch, create a new branch from that in your fork, and start there. The lower-level stuff won't be changing for a while, so this is a good time to add support for SLA and the galvanometer.

At the low level, we only need to be able to convert blocks from the planner into commands to the galvos. We already have the higher-level ability to divide up moves into smaller segments, which we use for Delta and SCARA, and we have a kinematic layer to deal with whatever kinematics we need. Ignoring bed-leveling, the procedure Marlin uses for a kinematic linear move is:

So, to your points…

the galvos "drawing" speed should be relatively low

Once implemented, the galvos will follow the feedrate specified in the G-code.

the laser should be able to "draw" each layer 1 or more times

That must be specified in the G-code. Marlin will not remember previous paths.

the turning on/off or regulating the power of the laser

This will be specified in the G-code by M3 and M5 and will use whichever PWM pin is specified. I have implemented support for a laser with separate 12V power and 5V PWM control at 25KHz. Both slower and faster PWM rates are possible, and for SLA all you really need is on/off.

After each layer (when the Z axis is retracted) some printers do a "swipe" of the resin vat floor with a "wiper"

Marlin can directly address a connected servo, and this will (again) be controlled by a G-code command at the layer change. Marlin doesn't have the concept of "layers" but merely follows the commands to move the Z axis. So, we would need to define an additional G-code to initiate the "peeling" step, and a way to configure the G-code for that step.

Generally speaking, everything needed to support SLA printing is in place except for the galvos control. So let's tackle that first!

marcelogaio commented 7 years ago

I found this old version from 4 years ago that implements something in the lines of what we are talking about: https://github.com/beardface/Marlin-OpenSL Apparently it's based on an old and modified version of Marlin. I am trying to figure it out...

marcelogaio commented 7 years ago

Generally speaking, everything needed to support SLA printing is in place except for the galvos control. So let's tackle that first!

GREAT! I'm all for it!!! I forked the bugfix-1.1.x branch. Do you think we can work it in there?

PS: Marlin is... wait for it.... Awesome!

Nerradia commented 7 years ago

I am happy to read that I'm not alone :D I was planning to make my SLA with steppers driving mirrors, is there a way to implement this at the same time ?

marcelogaio commented 7 years ago

@Nerradia I did a lot of research regarding SLA with steppers. The main issue is that the steppers cannot (apparently) provide the amount of steps needed for the high resolution needed... Remember the mirrors move between 7-8 degrees (max), and most details just need a couple of fractions of a degree. If you use steppers, (again, apparently) the best solution would be to build an X/Y arrangement to move the laser (like the http://muve3d.net/press/product/muve-1-laser/ ). On the downside, i believe you won't get the resolution you would with galvos (again, just my guess) but on the upside you can control it without much change to Marlin...

Nerradia commented 7 years ago

@marcelogaio Thank you for this answer. I did'nt precise that I was planning to add some gears/Toothed belts to increase precision, but I don't know if it will be enough... You are right, I will order a galvo soon !

If I can help on the hardware side (PCBs ?), please tell me.

After googling 30 seconds, about the DAC needed to drive galvo, why not use 24 bits audio DAC like this one : http://www.ti.com/lit/ds/symlink/pcm1789-q1.pdf Acording to the datasheet, the minimum sampling frenquency is 8 kHz, is it possible to continuously send 192 kbps I2S with Arduino mega ? The teensy 3.x have an hardware I2S port, but I don't know about the others.

thinkyhead commented 7 years ago

SLA with steppers driving mirrors

That is already in place, essentially. You only need to write the kinematics to convert XY into mirror angles, and Marlin will faithfully move your mirrors just like it moves the joints on a SCARA. The only thing you'll need to add is layer-change G-code for any special moves on layer change, and you can do that in the slicer.

thinkyhead commented 7 years ago

Is it possible to continuously send 192 kbps I2S with Arduino mega ?

i2c? I believe the "fast i2c" on the Mega is only 40kbps. But I will look into it.

Nerradia commented 7 years ago

No, I am talking about I2S, it's a standard for digital audio which is compatible with a huge part of audio ADCs and DACs. https://en.wikipedia.org/wiki/I²S I don't know if we need that much speed and precision to drive mirrors...

I did'nt know it was that easy to change marlin for SLA with steppers driving mirrors, thank you for your advice :)

thinkyhead commented 7 years ago

image 😝

thinkyhead commented 7 years ago

I2S may not be suitable unless the galvos are tightly integrated. Sources indicate that it's meant for use between circuits, not over longer wires. But there is an I2S library for Arduino, so feel free to test such an interface.

The more common and easier-to-integrate circuit is the DAC_MCP4X, which uses SPI. I suggest we start with that common circuit and then look to expand it later.

Nerradia commented 7 years ago

At the speed we will use it, I2S can travel some distance without problem. I am ok to start with the SPI DAC and his library, as it will be easy to change to a better one later by changing the library. Orders from Bangood/Aliexpress are very slow and I may get my galvo in a month :(

marcelogaio commented 7 years ago

Orders from Bangood/Aliexpress are very slow and I may get my galvo in a month :(

@Nerradia This is the galvo I ordered: https://www.aliexpress.com/item/30K-laser-Galvo-Galvanometer-Based-Optical-Scanner-including-Show-Card-US-ship/1901995485.html?spm=2114.13010608.0.0.uDzfNV It comes with the galvos, the driver board for each galvo, a 15v (+15/-15) regulated power supply and an ILDA laser show card. The show card will not be used, and each driver board has a 3 pin connector for the signal. Yeah, it took a couple of weeks to arrive :(

Nerradia commented 7 years ago

I bough the same one from the same vendor :D

marcelogaio commented 7 years ago

I already have this 12bit DAC: MCP4725-I2C but it's I2C. Here is a library for using it: Adafruit_MCP4725

The more common and easier-to-integrate circuit is the DAC_MCP4X, which uses SPI. I suggest we start with that common circuit and then look to expand it later.

I just found this one ak-mcp4922-dual-12-bit-dac-breakout , and it looks promising, because it has a DUAL output, which could be useful! (I'll still give the I2C a try...)

Both are just 12 bits, and as mentioned before, should give 4096 steps of resolution. If my calculations are right (most likely not!) an average stepper w/belt arrangement with 1.8deg resolution should give around +/-4000 steps in 20cm... So with a low end 12bit DAC we should have about the same resolution (even a bit more, because without a f-theta lens, I asume the print area would not exceed 15cm x 15cm)

Nerradia commented 7 years ago

I would like to talk about that f-theta lens, or how do without it. To have the laser perfectly focused everywhere on the plate, I though about using a slider to move the laser source, to null the beam length variation. It will just need a stepper and a belt. Should we use an axis and control it with gcode, or should it be linked to XY positions by Marlin ? I don't see how to implement the first way if we use Cura as slicer. The second looks better for me.

marcelogaio commented 7 years ago

I would like to talk about that f-theta lens, or how do without it.

As far as I know, a great printer like FormLabs2 does not use a lens or any other type of correction, other than software. So i am guessing that the focus is not such a big deal. Here is an interesting blog about a Formlabs2 tear down.

Maybe (just maybe) there could be some type of "compensation" for the unfocused laser, if the laser power was reduced in the center and increased at the edges? But I guess not even that is needed...

marcelogaio commented 7 years ago

I though about using a slider to move the laser source, to null the beam length variation. It will just need a stepper and a belt.

I thought about that too, but it would be VERY hard to sync the galvos motion with the beam focusing belt motion, since the galvos can move much more faster than the belt could... Also, going back to the FL2 teardown, if they don't need it.... ;)

Nerradia commented 7 years ago

I thought about that too, but it would be VERY hard to sync the galvos motion with the beam focusing belt motion, since the galvos can move much more faster than the belt could...

Acceleration will be controlled by firmware, we will never move the laser as fast as galvos can ?

Also, going back to the FL2 teardown, if they don't need it.... ;)

They are using a mirror to have a longer beam to avoid too munch length variations... Let's do the same ! But it could be an upgrade if someone wanted to print larger parts without having a 2 meters tall printer :smile:

marcelogaio commented 7 years ago

Sorry!! I just fixed the FL2 teardown blog link: https://www.bunniestudios.com/blog/?p=4641

marcelogaio commented 7 years ago

They are using a mirror to have a longer beam to avoid too munch length variations... Let's do the same !

YES! I totally missed the mirror. It would help a lot!

marcelogaio commented 7 years ago

@thinkyhead @Nerradia I made a Pull request: https://github.com/MarlinFirmware/Marlin/pull/6909 https://github.com/MarlinFirmware/Marlin/pull/6911 https://github.com/MarlinFirmware/Marlin/pull/6913 ...finally. I'm quite an amateur at collaborating! :p

It basically adds the support for a non-extruder non-hotend printer, with a new config profile for a Galvo SLA printer. So far it allows Marlin to compile with these basic settings.

Regarding the endstops, I already undefined them in the config, and with some minor changes, the code compiles.

Next steps:

superdave42 commented 6 years ago

Lets not let the momentum die! Lots of us have the Galvo Kit now and would like to use reprap software to drive them. :-)

thinkyhead commented 6 years ago

I do want to get the Galvos support merged pretty soon. At the moment I'm just aiming to get the bugs shaken out for a 1.1.7 release, but immediately afterward I will tackle lingering PRs including the Galvos XY patch. The main delay on this is that code continues to evolve, so the changes allowing for zero extruders needs to be applied in a few more areas.

guojunTTTT commented 6 years ago

what kind of support do you want?

Roxy-3D commented 6 years ago

Lets not let the momentum die! Lots of us have the Galvo Kit now and would like to use reprap software to drive them. :-)

I do want to get the Galvos support merged pretty soon. At the moment I'm just aiming to get the bugs shaken out for a 1.1.7 release

@superdave42 @marcelogaio @Nerradia This is a complicated subject and will require 'critical mass' to make good progress. My guess is there are some galvanometer companies that would love to donate 6 or 8 units to serious firmware developers. What they get out of the deal is their equipment becomes the 'reference platform'. It will be the most tested and best supported. 'Fast follower' user types will be buying that exact equipment because of those reasons.

That is exactly what we did with the Marlin on 32-bit initiative. Please check out https://github.com/MarlinFirmware/Marlin/issues/3851 and #7076 . Panucatt Devices seeded the Marlin development community with 8 Re-ARM boards. And we are making very fast progress because we have 'critical mass' now. And the 'fast followers' are buying Re-ARM boards because that is the path of least resistance.

thinkyhead commented 6 years ago

what kind of support do you want?

I'm specifically referring to the pending submission #6977.

RavenWarrior commented 5 years ago

Hi all, so I’ve started my journey buying an xyz da Vinci, then found the world of open source after that mistake. I built the 16year old kids printer, the cherry 🍒. Realised the joy of it all, and how it could be so easy to build bigger. I turned the Da Vinci into a frankenvinci thanks to the guys at soliforums after trying to hack the rfid chip issue. Then I set about building a 300x300 dual extrusion printer which worked and was looking awesome, but soon realised levelling was a problem and the nozzles I had were cheap and nasty. I’m now rebuilding this but along side it I’ve bought myself some galvos, a laser and some c-track aluminium extrusion in all the sla 3dp excitement. I gotta say you guys have gotten the furthest I’ve seen in regards to understanding and keeping it open. There are youtubers who’ve got things going but they don’t wana show their workings. I wish I could help with all this but sadly I’m all no electrical engineer. I’m a mechanical fitter (machine tool fitter) by trade so building is easy. Software and electronics are hard for me to fathom so I’m grateful for finding this thread. I was wondering what happened. Where’d you guys and your excitement go? I’m Andy btw

thinkyhead commented 5 years ago

@RavenWarrior — Congratulations on your acquisitions! We're still here, still excited. In fact I just got back from WMFNY2018, and it was great to meet people and talk about the future of Marlin Firmware.

In case you haven't been following our work, for the last several months Marlin's core developers have been focused on fixing bugs, finalizing 1.1.x, and filling out 32-bit support in the 2.0.x branch. So we haven't had time to assess and implement every feature request.

Developers who are excited about galvanometer support seem to lack the skills or motivation to write the code for it, and those who could code it are generally bogged-down in the day-to-day handling of the ever-busy issue queue.

If you'd like to take on some of the load dealing with support requests to help free up our time for things like galvos and zero extruders which are far down on our long to-do lists, it would be a big help! Or, you may be able to entice some of the developers to put more time into galvanometers by offering them decent monetary compensation for the required time and their valuable talent!

RavenWarrior commented 5 years ago

I really wana help you guys, I’ve read a few threads relating to marlin and the updating of it, but I really am a noob when it comes to all of the coding. I’ve only ever altered the little things like steps per mm, bed sizes and things like that. It took me forever just to get the cooling fan and extruder fan allocated to the correct pins. You know when you change something to see if it works then realise you forgot what you changed when it starts throwing errors at you. Point me in the direction of beginners reading material and I can begin there. I don’t want to fill these threads with coding questions.

thinkyhead commented 5 years ago

The Arduino website is a good place to start, with lots of example sketches.

RavenWarrior commented 5 years ago

Got some serious studying to do to get to these standards🙄

boelle commented 5 years ago

is this one still up in the air?

boelle commented 5 years ago

@thinkyhead this one also has the wrong label i think

Bx3mE commented 5 years ago

I have been digging into this for the past 3 weeks now and would say this one is actually two parts, One for Galvo integration and one for distortion correction. ATM i am not aware of any active efforts, please announce if any work is beeing done. I am experimenting on my own on 2.0. Making it work does not seem to be the hard part.....

RavenWarrior commented 5 years ago

I’ve made some electronics up on a bread board but I’ve not the slightest idea how I’d write a code in marlin or Arduino that would convert a printer host Gcode into a 2d vector movement.

Bx3mE commented 5 years ago

If you dont know what the code will output - how can you wire up some electronics? What output do you expect from the code? There are many ways to implement this... Digital, DAC to analog, MCU to DAC to analog...

I look at a solution for both XY2-100 (Digital) and DAC to anaolog shield. Currently i am trying to handle a 8Bit dac i had laying around and it works quite well basic moves are in place but it is a long way before i can share anything. I am not alone in this, i work with several people from work and also other people from around the globe.

RavenWarrior commented 5 years ago

From everything I have read online, watched online; searching galvo control, diy sla printer (which ends up being dlp)... so many variants of search terminology and trying to understand it as best I can, I’ve somewhat gathered enough information as to how a laser galvo printer would be build mechanically/electronically, however I was apprenticed in mechanical engineering, so my understanding of the electrical and the code side is very limited. I could send an image

RavenWarrior commented 5 years ago

How can I send an image?

Bx3mE commented 5 years ago

Please do! I made a proof of concept which actually worked quite well using, #dont_try_this_at_home, direct power from the GPIO to power 2,5" HDD galvos. Now it was a "Hot Glue" kind of construction and barely kept it together and stabillity was bad. I i had some Op-Amps id have much better results... Now i am progressing my development using some professional galvos and some mid range lasershow galvos. I could make some shield to control this but prefer to wait for some of the people I colaborate with to do it for me :P

Bx3mE commented 5 years ago

Image? do a post on Reddit -> /r/OpenGalvo/ I just started a Reddit for it...

RavenWarrior commented 5 years ago

Are you rougeneurons?