Modbus, Arduino, Mach3 and Brains..oh my

Laser power control via modbus.

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.

My first task was to see if an existing Modbus library existed.  I found a extremely well written and documented one by Juan Pablo Zometa written here.  I read the code and determined that I could start by testing it as is without changing anything.  I would setup Mach3 to match the port settings and try to read and write to the default memory register setting.  I loaded the program into my Arduino Duemilanove.
Setting up Mach3 Modbus

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.

Now try to read from the Arduino using the Test Modbus button.  The arduino starts at register 1  and initially has only 1 register.

Setup the Comm Port setting per above, but don’t bother with anything else.  We will manually test the Modbus now.

I set the Slave Addr to 1 the Start to 1 and the Num Regs to 1.  I clicked read and got 0000 with no errors.  All registers are 16 bit integers and by default they are displayed in hex format.  I changed 0000 to 1100 and clicked Write.  I then cleared the number and clicked Read.  I got 1100 back.  This meant both read and write were working.
Modifying the Arduino code.

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.

Edit the post processor
The next task is to create a post processor to create the custom G-Code.  I used Vectric Cut2D as my CAM program for this exercise.
First I setup the spindle speed to output as Pxxxx.  The + sign comments out the original post processor line.
+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.
Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks

3 Responses to “Modbus, Arduino, Mach3 and Brains..oh my”


  1. Mike

    Have you considered doing this witn Linux cnc.
    There is some work already done on it.

  2. bdring

    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.

  3. Interfacing an Arduino-based pendant - CNCzone.com-The Largest Machinist Community on the net!

    [...] 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 [...]

*