Modbus, Arduino, Mach3 and Brains..oh my
Mach3 is a great program. People have used it to control a vast diversity of machine, but it has some issues when controlling lasers. This is especially true when it comes to the beam control.
The beam can be compared to the spindle of a mill. It does the cutting and has an on/off state and power level (like RPM). On a mill, the spindle can safely stay on during rapid moves above the work and dwell at points without issue. A laser cannot do that because it does not retract from the material. It must only be on during G1 feed moves and must not dwell at any point or excessive burning will occur. The normal spindle logic does not work well with lasers.
I thought it would be a fun experiment to try to enhance the control using a Modbus slave device. Modbus devices are basically remote device that allow a host to read and write data registers. The remote device can then use the data registers to give information to the host or do a task when a register is written to by the host. The devices typically communicate using a serial port or Ethernet. You can view the Modbus protocol here.
There are a lot of commercial Modbus devices like ModIO and the Automation Direct PLCs, but I wanted a cheaper home grown version. I thought an Arduino would be a good choice because it has a built in USB to serial port, it is less cheap (less than $20) and it is open source.
I created a new Mach3 profile by cloning an existing working profile. Modbus is turned on via the Ports and Pins dialog. Check the Modbus dialog. Skip the second check box for now. I used the simpler old Modbus plug in
I needed to restart Mach3 to make the changes available. Next, go to the plugin dialog. Setup the serial ports to match the Arduino settings.
Setup the Comm Port setting per above, but don’t bother with anything else. We will manually test the Modbus now.
I changed some Arduino code to allow more registers by adding “ = 6” after MB_REGS.
enum {
MB_REG0,
MB_REG1,
MB_REGS = 6 /* total number of registers on slave */
};
Now I was able to read and write multiple registers. To have a little more fun a wrote a function that runs every time a write command was received. One register toggled an LED and the other set the value of a PWM. That worked perfectly.
Automating the Modbus
That is all cool and fun, but manual control is not gaining us much. Now it is time to put Mach3 in automatic control of it. To do this we will write a macro that is triggered from G-Code. I wrote a macro the would run whenever Mach3 encountered a special bit of G-Code. I chose to use an M666 code. I would use that with a “P” parameter for the PWM value. So “M166 P50” would set the PWM value to 50.
The code is very simple. It reads the parameter. Param1() always gets “P” parameters. It then sends the value out via the second register in the slave Modbus device.
+VAR SPINDLE_SPEED = [S|A|S|1.0]
VAR SPINDLE_SPEED = [S|A|P|1.0]
The next change is to add the new M666 line before each first feed move to set the power level.
begin FIRST_FEED_MOVE
“[N]M666 [S]”
Next steps
The next step is to use a Mach3 feature called “Brains”. This is a ladder logic type programming method that works much faster than macros and can run in parallel with Mach3. This can allow some really interesting ideas.
Possible Future Ideas.
- Tie power level to feed rate. When a move starts out it accelerates to the desired feed rate. Therefore the power per speed is not constant. A Brain could adjust for this.
- Control beam enable on with “is move G1” logic. Rather than using the E1P1 method common with many laser users, you could have a Brain toggle the beam on whenever the code is in a G1 move.
- Return water temp to Mach3. The Arduino could read water temp and Mach3 could display it on in a DRO. Mach3 could act on a high temperature value and do a feed hold and turn off the beam.
- LCD display. The Arduino could control a simple LCD display of feed rates, power levels, axes positions.
- Jog buttons. A simple jog button panel could be implemented.
- Feed rate offset. A pot could be used to adjust the feed rate plus or minus while the job is running.
- Feed hold with beam off: A feed hold button could be implemented where the motion stop and the beam goes off at the same time.














Have you considered doing this witn Linux cnc.
There is some work already done on it.
Yes, the Arduino side of things would not change at all. I primarily use Mach3, but I have used Linux EMC2 as well.
All my good CAD and CAM software runs on Windows, so it is nice to be able to stay in that OS.
[…] Modbus, Arduino, Mach3 and Brains..oh my at Buildlog.Net Blog Interesting notes on Arduino and Mach3 hookup using Modubus. function hidestatus(){ window.status='' return true } if (document.layers) document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT) document.onmouseover=hidestatus document.onmouseout=hidestatus […]