Jump to content
Ultimaker Community of 3D Printing Experts
conny_g

OctoPrint plug-in for laser PCB exposure with Ultimaker

Recommended Posts

I own two Ultimaker 2+ and have created a laser attachment for the print head and a control board plus scripts to expose PCBs with the Ultimaker.

It's a small UM firmware mod (on basis of the tinker firmware) that give a "sync" signal on one of the extension ports of the Ultimaker mainboard and a Arduino based controller (Arduino Pro Micro, the quite small thingy) that receives the pixels via USB/serial connection (for example from a Raspberry Pi that's running OctoPrint in parallel) and "streams" them to the laser driver upon receiving the sync signal from the UM.

Essentially the print head is moving with constant speed left-to-right and the laser is switched by the controller independently matching that speed.

So the core idea is to use the mechanics of the Ultimaker 2, but aside of the sync signal not do any larger mods to it. Which even makes it a universal solution for any precise mechanic like that.

I had done one try to get the pixel streaming into the firmware, but there is a conflict between the timer interrupts for motor control and the pixel streaming coming up. Possibly doable to untangle that, but that felt like a painful road so I decided for that external controller, simplifying the thing enormously.

With that solution I can achieve results down to 3-4mil of resolution which is much better than what I could achieve with the regular film printing & exposure methods or toner transfer. See attached photos (thanks to Henner Zeller the creator of the LDgraphy laser exposure device for the excellent test pattern, https://github.com/hzeller/ldgraphy).

Video of the exposure process:

 

That for the background, now to the question that I have.

Currently the creation of the G-Code for the printer and the "bitstream" file are plain Python scripts I have to call, transfer the files to the OctoPi, run my "bit streamer" and start OctoPi with the G-Code file. Pretty manual process.

Now I would like to integrate all this into a OctoPrint plug-in to use OctoPi as a central UI. That would be much more transparent and comfortable and could also provide the calibration tools to adjust PCB position and focus height in a few clicks.

Would anyone be interested to join in to develop and test this?

IMG_8756.thumb.JPG.8fb1dadda4c041da2038f73e7a9a08a3.JPG

P1010953.thumb.JPG.e4a089298236cee0239ab2ab41bf0e54.JPG

P1010955.thumb.JPG.31b15c0b8a9bfb2032d3afa1d9e60072.JPG

P.S. the holder of the laser head attachment bases on the Mark 2 dual head magnetic plate, so it's easily attachable and removable.

IMG_8756.thumb.JPG.8fb1dadda4c041da2038f73e7a9a08a3.JPG

P1010953.thumb.JPG.e4a089298236cee0239ab2ab41bf0e54.JPG

P1010955.thumb.JPG.31b15c0b8a9bfb2032d3afa1d9e60072.JPG

Edited by Guest
  • Like 1

Share this post


Link to post
Share on other sites

@musyne,

it's not yet "compact" enough to make it easily doable in all details. That would be my long-term plan after I straightened out the software part with Octoprint.

Generally the solution consists of:

  • a 150mW 405nm laser diode in a cooling housing, mounted to the UM head using the Mark 2 magnetic plate
  • a laser driver with analog control, i.e. you can switch its power with a voltage of 0-5V from standby-current to 100% (both set via pots on the driver)
  • a low pass filter circuit before the control input of the laser driver to convert 65 kHz PWM to 0-5V
  • a control circuit on basis of a "Pro Micro" (Arduino Leonardo clone) which is connected via its USB port to a Raspberry Pi. The circuit receives the pixels to expose line by line from the Rasperry Pi, gets a "sync" signal from the Ultimaker Mainboard when the line begins. Then it "streams" the pixels out, using PWM to set the power (laser driver control voltage) and switching the PWM off and on for the individual pixels. That in parallel to the move of the UM head.
  • a python script on the Raspberry Pi that sends line by line from a prepared file with pixel data to the Atmega on the control circuit
  • OctoPrint on the Raspberry Pi that send the G-Code to move the head left / right and from one line to the next
  • a python script that converts an input PNG with the circuit to be exposed to the G-code file for the head movements and a file with the pixel data for the "bitstream" script
  • a firmware mod to the Tinker firmware that would send a "sync" signal via an extension port of the UM Mainboard when a certain G-Code parameter is added to a G-Code move
  • a cable plugged into that extension port of the UM board, connecting the control circuit to the sync signal

That's all the components in overview. Currently working (more long-term due to time constraints, will take a few months) on creating a Raspberry Pi hat to sit the control circuit on top of the Raspberry Pi and to add the python scripts to Octoprint as a plugin. That would make it much easier to use.

Share this post


Link to post
Share on other sites

Hi conny_g,

I've also just upgraded my UM2 with laser cutting/etching capabilities (405nm laser, several Watts of power, mounted with https://www.thingiverse.com/thing:3022126). I followed a quite different approach though for PCB mask etching. I'm using the print-head cooling fan PWM to directly control the laser power output. Then I create a gcode file, tracing the outlines of the PCB layout (through eagle ULM). In my case, I'm not using photosensitive film (as I think you do), but a plain PCB, spray-painted in black and then blasted away where I want to etch (so also effectively using positive resist). I'm also getting a 0.09mm (better-than 4mil) resolution with that. I think I'm mostly limited by the step-size of the UM2 and the 3:1 rectangular beam profile. Working on adding a pinhole in the beam to get a round beam profile (not sure how well that'll work). Using paint rather then resist also allows me to just remove the paint if something went wrong, re-paint it and try again. This is very easy to build and yields great results fast, so I would suggest to you to use this technique for PCBs (with your low laser-power maybe still with photo-resist, rather than paint though).

 

As you already figured out however, gcode doesn't really support drawing shaded bitmaps (and it is hard to hatch larger areas with a 0.09mm beam). So I might still be interested in developing the solution you proposed. It could also be better suited to cope with the non-square beam profiles that we often see in diode lasers. One solution would be to use rectangular instead of square pixels, another to move adjust the write time for each pixel such, that it effectively becomes square (which would lower the resolution a bit, limited by the longer side of the beam).

 

Ideally, we could merge the two approaches and build one controller that can run in either mode without having to switch stuff around. This might be possible if we used the fan PWM to give the sync signal, which can then be send from the gcode. As a bonus, the firmware-modification would be unecessary.

 

Let me know what you think, maybe contact me via PM.

P7260057.JPG

P7270063.JPG

Share this post


Link to post
Share on other sites

Hi Razanur,
good work, congrats 🙂

 

I had two different versions of a head initially as well, one version used the thumb screws to attach it to the side.

The second version was an alternative head that allowed change a part of the head

https://www.thingiverse.com/thing:945899

The 3rd version is the magnetic mount of 

https://magnetic-tool-changer.com/

(participated as beta tester there)

That allows to attach/detach the laser head at any time, without screwing or anyting.

 

Regarding color vs. photo resist. I am quite happy with the photo resist, it's very refined product and it's easy to expose it with the 150mW diodes which are cheap and available. The multi-Watt ones are much more expensive and harder to get in decent quality.
Thought about trying the color method, but on one hand it's a bit of a mess to remove that much black color afterwards and on the other hand I am absolutely happy with the photo resist stuff. I belief it's more accurate than spray color and supports efforts of high resolution better than spray paint.

Regarding the vector edging vs. pixel rastering I believe I can achieve higher resolutions with rastering as I can control the energy going into one pixel very precisely. And I can expose the exact image of what I want to do without having to convert it to vector edging, leaving the areas (unless I hatch it which is the same than rastering...).
For that reason I don't experience much of an issue with the oval/rectangular shape of the dot. I have set it to 45 degrees vs. the raster direction and that way in essence it has the same size for X and Y, simply making the focus larger. Which I can compensate with reducing the energy (gaussian beam, effective dot converting the photo resist is then smaller). If you move in all directions you see the effects of the "bar" in one direction vs. the other.
Then with the vector there is acceleration/deceleration ramps that change the energy going to the color/photo resist strongly so the lines are thinner/thicker, depending on the speed. Unless you go "full power'" anyway which will always create a large "effective" footprint (see the gaussian thing above). With the rastering every pixel is identical.
And with the vector method I had strong oscillations in the corners as the laser is on while it't going around the corners. Depending on the speed, of course.


After considering all this I stuck with the rastering approach. Tried the vectoring some time later and I didn't like it better, so still going with rastering now. The rastering takes long (3 hours for 1 side of Euro PCB), but I like the perfect result over the time factor.

 

With the software + controller the vector approach is still possible. I have two modes built in, one is the "bitstream" mode, the sync signal given by printer starts the pixels being generated while the head moves along the defined path. And the "direct" mode where the sync signal actually controls the laser beam, sync on = laser on, sync off = laser off. That way I can vector any path directly with G-Code (just an amendment of the G-Code is needed: G01 X100 Y200 B1  -> the B1 is "beam on").


For simplicity I had started with the fan output originally as well, but I disliked that I needed to switch plugs or connection between fan or laser so I started to use the EXP3 port and can just leave the laser stuff connected.

I don't have an issue with the firmware mod, it's making the solution more flexible and it's not a big /complicated mod. Even if you have to update the firmware from the repo again and resync the mod.

 

For the "bitstream" thing you need an external controller and for that you need a sync signal. So there is not really a way around the firmware mod. I had tried to integrate the pixel generation in the firmware, but I got conflicts between the movement control (using interrupts) and the pixel generation (using ints as well). Possibly you can get that resolved, but I am quite sure that this will bring the poor Atmega to it's limits and I didn't feel like having to resolve all sorts of strange side effects changing the usage of the Atmega that much.
So an external pixel controller was so much more safe and transparent.

So for me all that is pretty much working and finished, currently. The most important next step is to unify the software parts in OctoPrint with a nice UI behind it. Currently it's just python command line scripts.
And I am working on the drilling solution in a similar way. Magnetic attachment of the Dremel, python scripts to control the drilling.
Also that would benefit strongly from controlling that with Octoprint. 
Already spent a few hours in the last months to delve into plugin development for Octoprint and I think am now ready to do the next step soon.

 

Share this post


Link to post
Share on other sites

First: I think you did something amazing and I probably want to go in a similar direction. I just wanted to add my personal views/perceptions on some points, maybe also for the benefit of people reading this in the future.

 

2 hours ago, conny_g said:

The 3rd version is the magnetic mount of 

https://magnetic-tool-changer.com/

(participated as beta tester there)

That allows to attach/detach the laser head at any time, without screwing or anyting.

That is pretty neat! I think it might not be suitable for the big, heavy laser I'm using though.

 

Quote

[...] the 150mW diodes [...] are cheap and available. The multi-Watt ones are much more expensive and harder to get in decent quality.

That is a very valid argument. However, with more power you can also cut, engrave etc. I'm not sure, how much power is exactly required to remove the paint.

 

Quote

Thought about trying the color method, but on one hand it's a bit of a mess to remove that much black color afterwards and on the other hand I am absolutely happy with the photo resist stuff. I belief it's more accurate than spray color and supports efforts of high resolution better than spray paint.

As far as I can tell, there is no proximity effect whatsoever for the spray paint method, where I would expect a small a proximity effect in the photo-resist solution (the resist is transparent, so reflections from the copper also develop nearby resist). So from theory, but also from the results I've achieved so far, I don't think there is much of a difference.

 

Quote

Regarding the vector edging vs. pixel rastering I believe I can achieve higher resolutions with rastering as I can control the energy going into one pixel very precisely. And I can expose the exact image of what I want to do without having to convert it to vector edging, leaving the areas (unless I hatch it which is the same than rastering...).

I think both techniques have their strong and weak sides. Since most (all) PCB design softwares use-defacto vector descriptions to begin with, I don't really see your point here to why it would yield higher resolutions. Also, there is a well-working plugin for eagle to produce nice gcode files already. For pictures with shading etc, I think you totally have a point.

 

Quote

For that reason I don't experience much of an issue with the oval/rectangular shape of the dot. I have set it to 45 degrees vs. the raster direction and that way in essence it has the same size for X and Y, simply making the focus larger. Which I can compensate with reducing the energy (gaussian beam, effective dot converting the photo resist is then smaller). If you move in all directions you see the effects of the "bar" in one direction vs. the other.

Hmmm, it appears you have a very different beam geometry than I do. My beam is currently rectangular with one side about 3x longer than the other. As I said, I think it is much easier to compensate for weird dot geometries in the raster/pixel scheme. The only way to compensate is to use a pinhole (which especially for low power (150mW) should be no problem whatsoever (albeit extra work)). I don't really understand how rotation and defocus can make a gaussian profile out of a non-gaussian profile. Could you maybe explain this a bit further?

 

Quote

Then with the vector there is acceleration/deceleration ramps that change the energy going to the color/photo resist strongly so the lines are thinner/thicker, depending on the speed. Unless you go "full power'" anyway which will always create a large "effective" footprint (see the gaussian thing above). With the rastering every pixel is identical.

If you really have a gaussian profile you have a very valid point. However, in my case my beam is a pretty well defined rectangle, so this is not an issue. Also for PCBs you basically only want discrete paint removed/not removed. As my beam is currently smaller than the apparent step size of the UM2, this does not seem an issue to me. Again, if you want shadings etc, go pixel 🙂

 

Quote

And with the vector method I had strong oscillations in the corners as the laser is on while it't going around the corners. Depending on the speed, of course.

I did a few test patterns and with speeds of 300mm/s, I see no residual ringing whatsoever. Also check the picture I appended: I think it is high-res enough, that you should be able to specifically point out any artifacts - and I don't see any oscillations.

 

Quote

After considering all this I stuck with the rastering approach. Tried the vectoring some time later and I didn't like it better, so still going with rastering now. The rastering takes long (3 hours for 1 side of Euro PCB), but I like the perfect result over the time factor.

I think this is advantage no 2 of the vector approach; its much faster and potentially uses less etchant. Advantage no 1 being, that you can implement is much easier for beginners/as a first test and cheapter (unplug fan, plug-in laser, extract gcode from eagle, replace a few commands, run).

 

Quote

With the software + controller the vector approach is still possible. I have two modes built in, one is the "bitstream" mode, the sync signal given by printer starts the pixels being generated while the head moves along the defined path. And the "direct" mode where the sync signal actually controls the laser beam, sync on = laser on, sync off = laser off. That way I can vector any path directly with G-Code (just an amendment of the G-Code is needed: G01 X100 Y200 B1  -> the B1 is "beam on").

For simplicity I had started with the fan output originally as well, but I disliked that I needed to switch plugs or connection between fan or laser so I started to use the EXP3 port and can just leave the laser stuff connected.

That's super nice. I think I should also go with the exp-port and introducing the 'B1' command. Does this port also support PWM directly? I would like to set the laser power from the gcode directly for the vector mode (as you then only have to update the gcode on the SD card, nothing else).

 

Quote

For the "bitstream" thing you need an external controller and for that you need a sync signal. So there is not really a way around the firmware mod. I had tried to integrate the pixel generation in the firmware, but I got conflicts between the movement control (using interrupts) and the pixel generation (using ints as well). Possibly you can get that resolved, but I am quite sure that this will bring the poor Atmega to it's limits and I didn't feel like having to resolve all sorts of strange side effects changing the usage of the Atmega that much.

So an external pixel controller was so much more safe and transparent.

Well, you could use the FAN output as sync. Otherwise, I totally agree. I would also go with an external controller. In the case of vector mode, I would just forward the PWM signal (either from the ext or the FAN) from the main board.

 

Quote

So for me all that is pretty much working and finished, currently. The most important next step is to unify the software parts in OctoPrint with a nice UI behind it. Currently it's just python command line scripts.
And I am working on the drilling solution in a similar way. Magnetic attachment of the Dremel, python scripts to control the drilling.
Also that would benefit strongly from controlling that with Octoprint. 
Already spent a few hours in the last months to delve into plugin development for Octoprint and I think am now ready to do the next step soon.

That's good to hear! I would definitely love to see a write-up and some pictures of your rig! I'll try and see if I can drill the holes by cutting them out with the laser, but I'm still a bit sceptical about that.

Edited by Razanur
saved the post too early.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

Welcome to the Ultimaker Community of 3D printing experts. Visit the following links to read more about our Terms of Use or our Privacy Policy. Thank you!