Question: What is HAL2Arduino?

Answer: HAL2Arduino is by itself (no mods) is just a communication framework that allows an Arduino to communicate to LinuxCNC, this allows users that are familiar with an Arduino micro-controller to make a DIY CNC machine without having to write a custom gCode interpreter. After all, some really bright people over at linuxcnc.org have already done that. It’s a great piece of open-source software for running CNC machines big and small. It has a unique breadboard-like way of connecting to the real world and that’s where HAL2Arduino comes in. HAL2Arduino just exposes this breadboard-like interface to the Arduino platform so users may harness it without have to do any extra background coding.

Question: How does the HAL2Arduino tool-chain work actually?

Answer: On the PC side it contains a Python script that LinuxCNC runs upon start up, this script finds any arduino that is attached via serial USB cable, handshakes with the arduino firmware, queries it for info and the generates the requested HAL pins that LinuxCNC might be configured to use prior to actually starting up the LinuxCNC GUI itself. If the associated HAL interface pin is already defined in the custom.hal file LinuxCNC will put it to use.

Question: Can I make “Das Uber” CNC machining center work using HAL2Arduino to handle the whole thing over USB?

Answer: Yes, but please don’t. Instead, use the parallel port for moving the machine’s axes and reading the encoders. Why? Be cause its easier to configure that part traditionally AND it will perform faster too. If you have that class of machine chances are the general motion controls are intact and very well documented. HAL2Arduino should be sufficient to handle everything else like switches, DRO’s, jog wheels, joysticks, pumps, lights, tool-changers, indexers, control panels, touch probes, part shuttles, or even that 3-phase line conveyer.

Question: Can I use LinuxCNC/HAL2Arduino to make an automated production line?

Answer: In theory yes. LinuxCNC I think can be made signal other CNC machine controllers, if not HAL2Arduino easily can.

Question: Can HAL2Arduino be used over Ethernet? Does it support SD cards?

Answer: I don’t see why not, though no mod has been made for it yet.

Question: My computer does not have a parallel port, should I go out and get an Arduino to make my CNC machine work?

Answer: You are better off to go out and get a 9 dollar parallel port card. It will perform better than a 30+ dollar Arduino. Plus, the parallel card is likely to be directly supported by LinuxCNC without any need for this HAL2Arduino monkey business.

Question: I have a CNC machine that I would like to add something to. Can HAL2Arduino do that?

Answer: Absolutely!

Question: I read that HAL2Arduino supports more than one Arduino simultaneously. How is that possible?

Answer: It does this on the computer-side via Python by running separate threads, one per connection.

Question: I downloaded this stuff now what?

Answer: Read the README.txt follow the directions to get it installed. Afterwards, there should only be two files you should have a need to play with.

  1. The custom.hal where LinuxCNC will look for the pins you will need to define. Don’t worry there is an example file included to give you some clues. (In the future this might get automated too.)
  2. The Arduino sketch where you will need to do some actual coding. But don’t worry, I’m building up a list of modules to make this an easy (nearly) cut and paste experience.

Question: Will there ever be a non-LinuxCNC version of HAL2Arduino?

Answer: I’m only (somewhat) familiar with LinuxCNC’s HAL interface. Its also the only CNC host software I have. If someone else has Mach3 or some other CNC software that they added HAL2Arduino to, and would like to share how they did it I would be happy to link to their site or even setup a page with their instructions, walkthrough or howto on it.

Question: I made a module (or ‘mod’) that I think might help others. Or a better version of one. Would you like a copy?

Answer: Yes I would, just bare in mind. This is a survival of the fittest type of thing. If I list a module and you send me a better one, or link to a better one. I’ll relegate the old one to the archives and give yours the spotlight, with credit of course. That goes for new mods too. If you think someone could put it to use, even if its your very first bit of code and your worried that its not very good or its just plain ugly. Send it to me. Someone might actually need it. If your shy just credit to it ‘Anonymous’, that person is legendary. πŸ˜‰

Question: Ccan I use LinuxCNC in a Virtual Machine (VM) such as VirtualBox?

Answer: Yes. Normally you would not be able to, this has to do with LinuxCNC thinking that it absolutely requires at least one parallel port. Not true.

You can omit using parallel ports all together by commenting out all the lines in my-mill.hal that contain the word parport in them. When LinuxCNC starts up it literally has to be instructed to look for a parallel port, if the config file never tells it to look for one, it won’t. Then we can supplant the whole mechanism with HAL2Arduino or even good old EMC2Arduino.

Question: How can I use LinuxCNC in a VM with a parallel port and HAL2Arduino?

Answer: Not currently possible, at least not without a VM that supports emulating an old-school parallel port. I know as of the time I wrote this FAQ that VirtualBox does not support parallel port emulation.


30 Responses to HAL2Arduino

  1. Gustavo says:

    Hi bro! i have a arduino with homemade servo motor with encoder, i would like to know if i can receive axis values in arduino to control the servo and transmit the position to linuxcnc to confirm that axis is in right spot. Ex: LinuxCnc send(1step X+ Axis, and keep waiting for feedback to continue), arduino receive move(1 Step X+ axis , if (encoder really move 1step, send to LinuxCnc OK ready for next step) else (keep going) ), LinuxCnc receive( OK sending ). understand? its a loop. the LinuxCnc will only send next step when Arduino request, this way we will never lost any step. if this works i can build extremely low cost high power Servo motor using RC motor.

    Sorry for my english

  2. dewy721 says:

    Well, yes and no.
    Yes it is possible, but it is very, very, slow. The better option would be to have the arduino validate the position internally. That way the limited bandwidth of the serial link is not consumed by simple feedback control AND the arduino has less work to do.

  3. Henning says:

    Hello, can HAL2arduino be used to control a closed Loop servo Driver via Linuxcnc ?
    I wish you would give me an answer πŸ™‚
    Thanks Henning from Germany

    • dewy721 says:

      Not yet, however I do have intentions of adding it in.

      The much older (and very basic) EMC2Arduino version 0.2 had closed-loop servo control.

      When time permits, I will add servo support to HAL2Arduino. (Hopefully VFD support as well.)

  4. Jeff says:

    Ive just begun trying to use Linux and LinuxCNC and have tried to get your project to work for me but I cant seem to succeed in getting it to work. I have a file that was generated when I attempted to run LinuxCNC, would you have the time to take a look at it? I’m a Linux beginner …..Mach3 just doesnt cut it for me anymore. BTW….this looks really cool

    • dewy721 says:

      Well, how did mach3 move your machine? If mach3 used the parallel port then you can do the same with LinuxCNC. No need for any middle ware at all.

      What file?

      • Jeff says:

        I wanted to see how your project worked because I built a pendant for MACH3 and since Im moving on to LinuxCNC I want to adapt what I already have so that it can be used…. your project is a great example of communications between the Arduino and LinuxCNC.

        Anyways here is a portion of the debug from my attempt to start the program, as far as I can see the communication happened between the Arduino but I have no clue as to what these errors are caused by

        Can you help ?

        Stopping realtime threadsDebug file information:
        Can not find -sec MOT -var MOT -num 1
        Can not find -sec IO -var IO -num 1
        Can not find -sec LINUXCNC -var NML_FILE -num 1
        Can not find -sec EMC -var NML_FILE -num 1
        Waiting for component ‘Hal2Arduino’ to become ready……………………………………………………………………………….
        Traceback (most recent call last):
        File “/usr/bin/axis”, line 3078, in
        vcpparse.create_vcp(f, comp)
        File “/usr/lib/pymodules/python2.6/vcpparse.py”, line 177, in create_vcp
        File “/usr/lib/pymodules/python2.6/vcpparse.py”, line 47, in read_file
        doc = xml.dom.minidom.parse(filename)
        File “/usr/lib/python2.6/xml/dom/minidom.py”, line 1918, in parse
        return expatbuilder.parse(file)
        File “/usr/lib/python2.6/xml/dom/expatbuilder.py”, line 922, in parse
        fp = open(file, ‘rb’)
        IOError: [Errno 2] No such file or directory: ‘custompanel.xml’

        Unloading hal components
        Traceback (most recent call last):
        File “/home/jeff/linuxcnc/configs/my-mill/HAL2Arduino-0.4.py”, line 2005, in
        commandHandler(str(listOfCommands), str(listOfAxis))
        File “/home/jeff/linuxcnc/configs/my-mill/HAL2Arduino-0.4.py”, line 1176, in commandHandler
        Unhandled exception in thread started by
        Error in sys.excepthook:

        Original exception was:
        Unhandled exception in thread started by
        Error in sys.excepthook:

      • dewy721 says:

        Actually that’s the HAL2Arduino module waiting to the arduino to respond.

        What comport is your Arduino on?

  5. Jeff says:

    Thanks for the reply ….. I found out by trial and error that I needed to run the StepComp Wizard and all is well and that was the only thing that stopped me from getting it to run. I also needed to add a tool table file from another machine to get rid of all of the errors.

    After I had success I began looking at the documentation for Linuxcnc and was unable to find out where youre getting the command numbers from …. for instance the command 900,was that a number you assigned or made up or where did it come from ?

    On another note, did you ever experiment with an encoder to attempt an interface an “jog wheel”
    or do you have any insight on how to interface it ? The most difficult thing I had to accomplish with Mach3 was the jog wheel and I want to accomplish that before I proceed with the total retrofit to LinuxCNC because I had problems with the jog wheel “running on” after you stopped rotating the encoder.

    I did interface an existing push button on my pendant to simulate a limit swith and it worked great so all of the other functionality should not be an issue.

    Hats off and a toast to you …. great job

    • dewy721 says:

      Thanks! And hats off to you for the prompt and intuitive diagnostics, resolution + modification. πŸ™‚

      As for the command numbers: Those are my simple little creation. I needed a simple numbers only communication that the Arduino could easily digest. So, hence numbered commands it was. I tried to leave room for developer expansion as well as user customization.

      On the computer side: Open the HAL2Arduino.py file with a text editor and you see the commands as listed within the code. (Python format)

      On the Arduino side: Open the HAL2Arduino.ino then click on the “program” tab. Within processCommand function you see how those commands are put to use.

      So in a nutshell, I had to build the code up on both sides to make it work, at least to the extent that it yet does.

      Encoders: Funny that you mention it. EMC2Arduino 0.2 is built around the encoded servo motors of my old / hacked HP plotter. The only “CNC Machine” I own. Since then, everything I’ve been coding is based solely on a mental image, handful of loose switches, a quadstepper board and four nema23 steppers I have laying around.

      I have yet to garner the *”spare”* funds to build an actual machine of my own so I can REALLY start developing HAL2Arduino into a really useful form. But I digress… Adding a quadrature encoder to an Arduino is trivial. There are tons of howtos on the web to do it. Adding one to LinuxCNC (via parallel port) not hard either. Adding one to HAL2Arduino = adding new code to both HAL2Arduino.py and program.ino Myself getting a chance to really “sit down and just CODE for a while” = {college * jobHunt + old car / (family*2)} ==> fzzt! *small curl of smoke*

      Needless to say, I have the intent in abundance, but everytime I try to pin down an ever fleeting opportunity it seems that I miss and nail my foot instead. Doh!

      I want to knock the dust off of my plotter to make some PCBs; I’ll need to re-introduce encoder support for it. At that point adding jog-wheel support would be a no-brainer on my end.

      • Jeff says:

        Im in the process of trying to enable LinuxCNC deal with command 220 as far as I can gather you need to add it to the Arduino list of commands like this, which is really clear

        // When asked, request access to these commands.
        #define commandsRequested “215 224 226 231 233 220”

        I believe the next step is to “unlink” the LinuxCNC pin by:
        unlinkp axis.0.jog-counts

        Which I can understand, but then Im confused by whats going on here (example from the limit switch):

        net min-X Hal2Arduino.axis_0_neg-lim-sw-in axis.0.neg-lim-sw-in

        I know this is the “remapping” command but what exactly is does this particular portion of the command do?

        min-X Hal2Arduino.axis_0_neg-lim-sw-in

        I cant find any other place in the Arduino code or any other files where this would mean
        anything that would help me realize what this is doing

        Also, at the top of the “Hal2Arduino” file theres a reference to a file that I might need
        but cant seem to locate. (9axis_Hal2Arduino)

        #First load the Python user module named /user/bin/9axis_Hal2Arduino
        I just need some help piecing the procedure to set-up a new command

        What other files would need to be modified , I feel so close but yet so far

        Thanks for your time

      • dewy721 says:

        Doh! It just a typo in the comment line. 9axis_Hal2Arduino(.py) was renamed to Hal2Arduino(.py) So really, it should read as: #First load the Python user module named /user/bin/Hal2Arduino with the name ‘Hal2Arduino’ So the line: loadusr -Wn Hal2Arduino /home/dewy/Desktop/my-mill/HAL2Arduino-0.4.py Is valid.

        The ‘net’ lines are just to make symlinks with a name, source variable, and finally a destination variable. In the example you provided, min-X is the symlink’s name,Hal2Arduino.axis_0_neg-lim-sw-in is the source/output variable, and axis.0.neg-lim-sw-in sis the input/destination variable.

        More or less as I’ve come to understand it, the command is laid out as “net name source destination1 destination2 destination3 dest…”. The net command has rules though:

        Symlinks must have a name. Symlinks are allowed one output, but multiple destinations. Symlinks may read/write to other symlinks (calling them by name).

        So in a nutshell, this where LinuxCNC and HAL2Arduino’s python script is actually married together. Some lines give out data while others take it in.

        Also, if you were to add your own commands to the python script (to put that jog wheel to use) then you would need to marry your data to LinuxCNC by using a ‘net’ command.

        If you would like to know more about LinuxCNC HAL commands may I recommend the official http://linuxcnc.org/docs/EMC2_Integrator_Manual.pdf for all the details and examples. As I’m a bit rusty and only studied it “just enough”. πŸ˜‰

  6. Jeff says:

    I have achieved success setting up the MPG jog wheel except it only works at a jog-scale of 1.If I attempt to change the scale to .001 by printing

    Serial.println(“222 0 .001 222.001;”); // sets the jog scale

    The wheel doesnt function, I think its because of the way this print command is structured, should it be something more like

    Serial.println(“222 0 .001 222;”);
    Serial.println(“222 0 .001 223;”);

    • dewy721 says:

      Ah, I see the problem. AVRs choke on floating point math so as a workaround the communications protocol doesn’t do floats. Instead it multiplies them by 10000 which just shifts the decimal to the right by 4 places. So what you think is a jog scale of 1 is actually 0.0001 (which happens to be LinuxCNC’s default resolution).

      • Jeff says:

        How would you apply a jog scale of .001 then…. and I dont quite understand if the AVR takes a value of .001 and multiplies it by 10000 then the result would be 10 not 1.

        Could you achieve the same results by leaving the print command as this:

        Serial.println(β€œ222 0 1 223;”);

        and adding the following to the custom.hal file

        setp axis.0.jog-scale .001
        net mpg-scale Hal2Arduino.axis.0.jog-scale

      • dewy721 says:

        wheel count *10 = 0.001

        The reasoning is since the LinuxCNC backend handles its floats with 4 decimal places (although the GUI only displays 3 of them) the HAL2Arduino python script shifts it out by 4 places and sends the outbound data as whole numbers. Also the inverse is true for inbound data being that whole numbers received are converted back into floats before passing it over to LinuxCNC.

        This conversion all happens on the PC-side of the link; thus sparing the Arduino(s) the taxing overhead of floating point operations. (It makes a big difference to the little buggers.)

        On Fri, Sep 13, 2013 at 10:04 PM, Emc2Arduino

      • dewy721 says:

        Hmm, not dead-certain on how best to get the jogwheel going. You’re the pioneer here. πŸ˜‰

        Yes, you would need a net line in the hal file. The setp command I’m not experienced with. (Yet?)

        Man…. Now you’re making me want to go look at some code.

  7. Jeff says:

    The wheel is working but 1 click of a 100 count per revolution quadrature encoder results in a .030″ axis move.I believe that scaling is the first parameter that Id like to change in an attempt to control the movement a little more realistically. By using the HAL Meter the scale is currently set to 1 and I either have to find a way to set the scale through the Arduino or by using the HAL file.

    Im currently sending integer values to LinuxCNC, maybe I should try scaling them down in the Arduino and send smaller floating point values just as a test.

    Ill keep you posted on what I discover and Ill be glad to send you the code when I figure it out.

  8. Max says:

    Sadly, referring people back to ye olde parallel port is less and less of an option as time passes – I came here trying to escape the fundamental flaw of linuxcnc, its inability to reliable perform real-time stuff (PCs have no business whatsoever generating stepper pulses, neither in software _nor in hardware_; the absolute minimum that _needs_ to live _outside_ the PC is a black box capable to fully decelerate and stop a machine on its own if its buffer gets starved).

    Which is not to say there are no working linuxcnc machines – of course there are, I’ve been using one myself for years now with an older PC, based on the 8.04 Ubuntu. It worked just fine. However, time came to replace failing hardware, and apparently nowadays the only reliable way to using linuxcnc is to buy some down-to-the-last-digit specific hardware kit, or else. As it is, I’m now having latency problems the size of a mountain, and after rummaging multiple times through all available wiki pages and various forums, the only conclusion is “we have no idea why it doesn’t work for you – get some other hardware then come back to play Russian roulette; maybe it’ll work better this time.”

    Apparently, they moved to multiprocessor support with 10.04, which reportedly can cause horrendous (multi-MILLIsecond) jitter even on single core machines. Sadly, it really does, so it seems. Trying another multi-core PC is not an option – it happens to be an Intel chipset known for SMI interrupts which causes… horrendous jitter. Yes, it does indeed. Disabling that (if you manage to do it) comes with a warning about the out-of-spec regime and potential thermal burnout.

    Five random machines I tried the live CD in ALL exhibited staggering latency problems. Not minor, fixable deviations, but hangups there’s no point even talking about. I need the newer distro because no other software (CADs etc.) can be had these days on anything older than the current LTS. I’m just tired trying to find the one particular way to tickle linuxcnc that will finally satisfy it.

    There’s no other way around this – the parallel port and in-PC step signal generation just needs to finally die (a preferably horribly painful death). Yes, I’ve heard about grbl. That’s what I use at home, for that exact reason. It’s a wonderful fit for masochists, given the state of GUIs in general that are available to support it. I could write volumes on that (or indeed even a usable GUI if it weren’t for my long-standing pathological inability to finally learn to code for the PC).

    Perhaps the recent BeagleBone-EMC efforts will pan out in the end, but right now they’re very much alpha too. The bottom line is I have a no-longer-functional CNC on my hands, and reached the end of the road with no solution is sight. I guess it’s understandable that “Yes, but please don’t. Instead, use the parallel port…” was the last thing I wanted to hear. Anyway, sorry for the rant, all this really isn’t your fault…

    • dewy721 says:

      Hey, no problem! Your gripe is EXACTLY why I started down the embedded route. For me though, it was primarily a learning experience, AND the fact that they said it could never be done. πŸ˜‰ But that never stopped me before.

      Unfortunately I don’t own a proper CNC machine. Instead all my work on the subject has been developed against an old servo-driven scrapped-out HP plotter from the 80’s for EMC2Arduino versions <= 0.3. Afterwards, I switched over to stepper-based IO; hit the wall for performance limits and diverged towards a multi-core arduino approach with HAL2Arduino.

      But alas, my means do not justify my ends and life removed too much of my free time to faithfully continue the project. At for now.

      Don't be fooled by the BeagleBone/EMC project making use of a DB25 connector. Unlike a PC's CPU that has a the Northbridge and Southbridge chips (+others) to keep satisfied before ANY software can be looked at. All the junk in the PC's schedule is not involved with the embedded setups. For example, many of the IO pins on the BeagleBone are direct lines from the CPU. Not only can it generate insane steprates (think Mhz), it can do the math to slope those axies, then apply the data directly to the pins. Something that PC's lost ages ago.

      Its not that I'm saying "No you can't", if you want to grab a copy of EMC2Arduino/HAL2Arduino go for it! Even if you don't use it as the heart of your CNC machine it can help to give you easy add-on options later. But what I was originally saying with my previous post was, "They got the better idea; to get more fruit, shake their tree".

  9. Armin says:


    i’ve got the issue that HAL2Arduino won’t pair up with LinuxCNC. When i connect to HAL2Arduino and send the ‘990 0 0 990;’ manually it returns the firmware name. So communication seems to work fine. I tested this with a native LinuxCNC 2.5.4, 2.7.0pre and a 2.5.0 running in a Virtualbox. None seems to connect to the Arduino. Can you give me a hint what to do?

  10. Armin says:

    its /dev/USB0, but i already changed the port config in the py script to use it (see my other post here https://github.com/dewy721/EMC-2-Arduino/issues/3)

    • Duane Bishop says:

      I don’t yet know why on some machines ser.close (line#2020) holds up the show.

      Like for your machine for example: Just comment it out, but as a result it may take two attempts to successfully open a connection. First one to close a stale link. Second to open a new one.

  11. Penelope says:

    Thanks, sir, for your great work! Just a quick question to ask. I noticed you said “Not RC-Hobby servos” in modEncoderServo. But basically I am now building a 3D printer with hobby servos. Any suggestions to incorporate the controlling of hobby servos in it? You can just tell me where to start, I am glad to get my hands dirty. πŸ™‚

  12. Evgeny says:

    Can I use your comp for connect to Arduino by UART(NOT USB) or MESA FPGA?
    I use plasma cutter with HF arc ignition and USB ports resetes after any ignition…

  13. dewy721 says:

    Yes. By default the code uses the standard old-fashioned two-wire serial connection between the serial interpreter chip (which btw, is a separately programmable chip) and the arduino’s main processor. I know that this is true for the Uno, Mega2560 & Due. (Two-chip boards.) You can feed data to the Arduino’s main processor over these two pins. Afterall, that is way the IDE flashes programs the chip as well.

    Conversely, one-chip boards like the Leonardo, Micro, Nano, Esplora, etc. emulate a USB interface natively, so there is no external link to tap into. But it could be made to sorta work using the serial connections on those boards.

    Plasma + 3.3v arduino like the Due, Leonardo would be hard to keep noise out of. Better to use a 5v arduino and use strong shielding everywhere, ferrite chokes, and heavy pull-up resistors on limit switches.

  14. Coni says:

    Hi, I have been reading for a couple of days a lot of forums and I am confused because some people wrote that LinuxCNC doesn’t work with Arduino by a serial port and other said that this way works just fine, so can you tell me exactly how is it? I am trying to make a CNC from a Proxxon MF70 and with LinuxCNC, but I can’t comunicate the software with the motors and their drivers. Greetings and from now thanks. πŸ™‚

  15. dewy721 says:

    Hello Coni,

    If you do their way, no it won’t work. 😦
    If you re-distribute the system, yes you can. πŸ™‚

    Let me explain:
    20 years ago when micro-controllers weren’t as common, it was convention to think that any given CNC machine had to be wholly & explicitly controlled by a local computer bolted to the side of it. Usually you’d see nothing between the two except a massive amount of wiring. That was because ALL of the machine’s thinking was done inside the attached computer. The logic of the day was such that each and every servo/encoder/stepper/switch & panel indicator required a dedicated set of wires. That’s A LOT of copper!

    If we apply that very same old-school logic to today’s hardware it becomes easy to draw an assumption that all those discrete signals can’t possibly fit within the tiny bandwidth of just one little serial connection, and they would be right in that regard. Fortunately that’s in NOT how we do things.

    Instead, we offload some of the computing power to microcontrollers. Specifically, the motion controller; the very part that needs all the wires. The GUI and trajectory planner is left on the computer and just sends co-ordinates and switches over the serial link. Furthermore, we can leverage multiple serial links over multiple MCUs to build even ridiculously complicated machines. It’s even theoretically possible to build an automated assembly line of complex tasks.

    But before I get your hopes up….
    You could for comparable price buy some xylotec cards and follow the tried and true old’way of doings things. You’d have tons of support from the LinuxCNC community and more documentation to point you in a successful direction with that hardware setup. You’ll end up with a simple machine that will perform better at uselessly fast speeds but have far less room to modify things to suit your individual needs.

    On the other hand….
    If you happen to already have an old Arduino or two, some $10 stepper drivers, an old ATX PSU, some steppers to bolt on to your machine plus a few limit switches as well as an adventuresome spirit. You could roll your own CNC machine. It’s not as easy, seeing as their WILL be soldering, some light programming, and hours of head scratching. But when you’re done you be a master of the hardware you own instead of a slave to its limitations.

    I hope that explains things a bit better.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: