Multi laser control (PWMs - for raster photo engraving)

Hello everyone,
Im a bit desperate after a year of searching for solution how to control multiple lasers (spindles, pwms) with one control firmware. Im using 5W blue laser diode controlled by PWM (spindle pin). Is there a way how multiple PWMs (lasers) could be controlled for raster engraving(photos)? The idea is to put multiple lasers into one working head with small offsets and engrave multiple rows in one pass(faster production). The laserhead moves pixel by pixel and changes PWM values during moves. We already have our own CAM which can generate needed Gcode but we are stuck with firmware solution. Please can you share any possible tips how it could be done? Could smothieware and SWITCH MODULE be up to the task? Or is there another sollution? Grbl, Marlin?
thanks a lot for any tip or suggestions.

if all the lasers are doing the same image then you might be able to connect the one PWM to all 3 laser heads as long as each laser has either its own power supply or you’ve added a much larger one to provide power to all 3 lasers.

If you want each laser to do multiple images then you would need to dig into the gcode parsing of the firmware and post process your gcode to combine the different images. But it’d be fairly easy if you know LinuxCNC.

If you know anyone familiar with LinuxCNC it could be done by mapping another IO pin to the motion.analog-output-xx pin usng the M67 gcode. It supports 3 devices and you’d change your gcode from G1XxxYxxSxxx to M67XxxYxxE0Qxxx for one laser, M67XxxYxxE1Qyyy for the 2nd laser and M67XxxYxxE2Qzzz for the 3rd laser.

if your images were the same size, ie rastering the entire area of a tile then a pixel at x124.1 y200.2 would look like this for the 3 images:

What controller board do you currently have? If it is LPC1768 or LPC1769 based then Remora firmware could be used.

I understood this as rastering different lines of the same image with different heads with some fixed offset. So if they were offset by 2" in Y and were aligned in X, and you were doing 1000DPI, and your image was 6 inches tall, a single carriage holding all three heads would make 2000 raster passes, and each head would be responsible for ⅓ of the image.

1 Like

Thanks Michael, I started thinking he wanted to do different images but I reread it and see it’s to cut the engraving time of a single image as you pointed out. LinuxCNC could still be configured to handle this since the M67 command allows you to specify one of 3 analog outputs. I currently don’t know how many hardware PWMs can be defined in Remora but if they wanted to look at LinuxCNC, it shouldn’t be difficult to find that out.

I just got LinuxCNC/Remora working with my K40 and it was mostly learning about how to setup Hal configurations. ie mapping pins and signals and learning that by using the spindle commands which are common in the ‘little firmwares’ the trajectory planner in LinuxCNC doesn’t like lots of spindle speed changes. That’s why I went with mapping the M67 command to the Laser PWM pin and how I know how the M67 works in LinxuCNC. :slight_smile: I’ve hardly looked at any of the gcode parsing of Smoothieware, Marlin, GRBL, Sailfish etc. They are pretty dedicated to a particular gcode subset.

Hi, dougl, many thanks for the tips about Remora and LinuxCNC. Will look into it. Unfortunately I don’t know anyone who knows linuxCNC but will try to find someone or dig by myself. Exactly as Michael pointed out. We placed 2 laser diodes into 1 working head with slight offset in X axis and precisely 0.1mm offset in Y axis.
(This is how it looks like in 3D cut: Dropbox - laser_head.png - Simplify your life)
So every diode is responsible for it’s own half of rows of one photo. (We plan to add even more lasers if we will be able to control it). Right now I’m really looking for the best option(working option with easy implementation) how to implement it. I have Smothieboard v 1.0b with LPC1769 and Re-Arm board with LPC 1768. I also have arduino MEGAs (for GRBL) and Arduino DUE (for TinyG). Really just looking for some hint what to use, where to dig and how could it be done. We do use RPi for gcode streaming so Remora option sound very interesting. I will try to look in other firmware for M67 command. Do you think that it would be big difference for this task between M67 and M68 ? (synchronized vs. immediate). Could M68 works as well?

ah, so you’re really kinda doing interlacing but with 2 diodes it’s just one sweep in half the time.

pretty much no different than if they were 1cm apart and each one was engraving their section of the 1cm and when laser 1 and 2 finished their last row, the Y axis would move 1cm and start the next section. but if you’ve got the lasers aimed for 2 lines then it’s just a Y axis move over one line and etch the next.

You might be able to hack one of the firmwares to parse a line with 2 laser power commands. Your CAM utility will have to handle the Y axis jumps.

I doubt any of the ‘little firmware’ handle M67 command. As for LinuxCNC/Remora with lasers go I tried the typical combo of M67/M68 and found it was slower than just using all M67 comands. I tested a grayscale image at 200mm/s 254DPI and it appeared to operate as fast as Smoothieware and that was good enough to call it a success. ie controlling a K40 with LinuxCNC/Remora.

In your current configuration, it would have to be determined if there could be 2 M67 commands on a line or what the results would be of idential move coordinates for 2 lasers:

Cool idea. Like a inkjet printer head.

So you basically need to change multiple PWM pins in sync with the movements of one x/y axes pair.
If I would try this in grbl, I probably would add a S0, S1, S2 param to the G1-3 moves, each of which would control a different PWM pin. This way the gcode could look like this:

Long time ago, there was discussions about special gcode for raster engraving, where we wanted to send a whole line of pixels in one command (to overcome the serial speed limitation because of overhead). This could also help in this idea.


I like it but it would make it a bit more difficult to post process with the S designation being numeric.
Maybe S[a-c] or more like M67 where the unique analog output is designated with E[0-2] and the spindle speed parsing remains.

As I’d mentioned, in the other firmware designed for small uCPUs(Marlin,GRBL,Smoothieware,etc) there needs to be a fork of the source code and maintaining of that fork. With LinuxCNC it would be a hal configuration file change. Since I’m on my workstation, here’s my hal section for LinuxCNC/Remora for my K40 with scaling so S0-1000 maps to S0-100 and I used a mux like an AND gate so when there was no movement, the laser PWM output was disabled:

        loadrt abs count=1
        loadrt scale count=1
        loadrt mux2 count=1
        addf abs.0 servo-thread
        addf scale.0 servo-thread
        addf mux2.0 servo-thread
        setp scale.0.gain 0.1 #this will make m3 s1000 give 100% output and m3 s100 10%
        #       signal          source          destination
        net spindle-speed-scale motion.analog-out-00 =>
        net spindle-speed-abs scale.0.out =>
        net laser-prog-is-running => mux2.0.sel
        net laser-mux-abs-in1 abs.0.out => mux2.0.in1
        net laser-mux-zero-in0 mux2.0.in0
        sets laser-mux-zero-in0 0.0
        net laser-pwm-out mux2.0.out  => remora.SP.0

In the M67 gcode parsing E[0-2] are parsed and values mapped to pins motion.analog-out-0[0-2] so you’d define a total of 3 abs,scale and mux2 nodes and you’d have 3 definitions for setting output pins.
The config.txt for Remora would define 2 other ununsed pins as hardware PWM pins instead of the one remora.SP.0 so maybe remora.SP.2 and remorea.SP.4 just incase you want to use Remora’s dynamic PWM freq/period setting which uses the next pin# defined.

        #       signal          source          destination
        net spindle-speed-scale-0 motion.analog-out-00 =>
        #       signal          source          destination
        net spindle-speed-scale-1 motion.analog-out-01 =>
        #       signal          source          destination
        net spindle-speed-scale-2 motion.analog-out-02 =>

Forking of one of the basic firmwares might be easier if your devs don’t know LinuxCNC and your devs can isolate the change to an easy place to patch or better yet, implement a currently unsupported gcode( M67) and maybe submit as a pull request for inclusion the main branch.

1 Like