Modbus Interface Board
From Field of Cows
This page provides information on my Modbus interface board that I created to allow me to handle the buttons on the front panel of the Boxford 125 TCL CNC Lathe that I have been retrofitting.
What is Modbus?
I had never heard of it until I started investigating methods to allow me to provide more digital inputs to the Mach 3 CNC controller application. My 125 TCL has 12 front panel buttons and a potentiometer that sets feed rate, all of which I wanted to perform functions in Mach 3 so I could drive the lathe without having to use the keyboard or mouse.
Mach 3 supports a couple of ways of doing this; you can add a second parallel port to provide a few more inputs, use the keyboard (or buy or create an interface board that pretends it is a keyboard) or you can use the Modbus protocol. The laptop I was intending to use would not support a second parallel port and I didn't fancy using a keyboard interface as this requires Mach 3 to always have the focus - although it should, Windows is quite often in the habit of popping windows on top of your application. So, I started looking at Modbus.
There are two flavours of Modbus based on different interfaces; TCP/IP and Serial. I decided to ignore TCP/IP and go for serial as I have some experience of making serial hardware. The serial Modbus protocol has two variants named RTU and ASCII. I won't go into too much detail here as you can easily find information on the differences elsewhere on the Internet (I particulalry liked this site) but, in brief, the ASCII variant as its name suggests uses ASCII characters to transfer the data whereas RTU encodes the same inforamation in a binary format. Each variant uses different start and end of frame markers and checksum calculations. I was not entirely sure what Mach supports so I decided to write a Modbus library in C that supports both serial variants.
What can you do with Modbus?
To tell you the truth, I only really investigated the real basics of the protocol so it can probably achieve much more than I describe here but at it's basic level you can:
- Read and write the state of digital outputs (Modbus calls them "coils")
- Read the state of digital inputs (Modbus calls them "discreets")
- Read and write the state of numerical settings/analogue outputs (Modbus calls them "Holding registers")
- Read the state of numerical states (Modbus calls them "Data registers")
The computer running Mach 3 is a host, any devices connected to this host are slaves. Each slave has a unique numerical address. The host sends requests to each slave which responds with either an acknowledgement for a command or the requested data.
So, in terms of my requirements, Modbus allows me to create an interface board that can read as many buttons as I want from the front panel of the lathe. Also, as I decided to control my lathe spindle speed and direction using Modbus, I can provide a "Holding register" to allow the spindle speed to be set and a couple of "coils" to allow the direction to be set. More on this configuration later.
USB Prototype Board
My electronics experience is fairly limited - I am a software engineer. But, I do have some experience using Microchip PICs. Therefore, I decided to base my board on one of these. Of course, I need to provide a serial port but ideally I would like to use the USB port to connect to the computer. Luckily, there are a range of PICs that provide direct connection to a USB host. Furthermore, kind Microchip have produced a firmware framework for handling the USB link, including emulation of the Serial port. I decided upon the PIC 18F4550 as this provides the USB interface plus a load more wizardry and I/O that may come in useful. It has more then enough inputs for my requirements.
The next stage was to mock-up a development board for trying this out.
Prototype PIC board with ICD2 header
This is the first time I've worked with a USB PIC and I have been very pleasantly surprised. I thought it may be fiddly and difficult to get working but, instead, all you need to do is connect the USB cables to +5V (if providing power to the board) and 0V and connect the D+ and D- lines directly to the USB pins of the PIC. The only other components you need to make a fully functioning board are some sort of resonator - I used a crystal plus required capacitors, and a few decoupling capacitors. You can see the full circuit I used below, created using the free version of Eagle. Note that JP3 and JP4 in the circuit should actually be pushbuttons. I could not find a standard pushbutton symbol in Eagle.
Prototype PIC USB board circuit diagram
The software was almost as simple. Microchip provide quite a comprehensive set of firmware and drivers for handling the USB capabilities of PICs. They also provide a number of samples and application notes that provide a good starting point for your own firmware. One really useful feature they provide is a USB bootloader. This means that you use your PIC programmer once to program the bootloader but from then on, you can upload your firmware directly via the USB connection. Very good if you do not have an in-circuit programmer. My circuit includes two buttons, one for reset and the other on a general purpose I/O pin. These are required by the USB bootloader to initialise the bootloader mode (press and hold the button on RB4 then press the reset button to enter boot mode).
I envisiged my firmware getting fairly complicated seeing as I wanted to handle the Modbus protocol and various other bits of functionality to so I bought the Microchip ICD2 in-circuit debugger. This is a fantastic piece of kit that allows you to not only program the PIC but execute your code line-by-line, examine the contents of variables and set breakpoints all directly on your hardware. It certainly makes debugging your firmware much easier. The photo of the board above shows the ICD2 standoff in the PIC socket on my USB board - this was required as I did not include a programming socket on my board.
My Modbus firmware was based on the serial port sample firmware provided by Microchip. The sample gives examples of how to handle serial connections and how to send and receive data. Perfect for what I need.
I decided to develop the actual Modbus library on the PC as I feel more comfortable working in Visual Studio than the Microchip IDE. I setup a simple MFC application that, using a dummy serial port, sends a Modbus message to itself then receives and decodes it. I didn't know whether Mach 3 uses the ASCII or RTU variants (although I could have found out without too much effort) so I implemented both. The actual protocol is very simple so it is not difficult to implement although I had to bear in mind the fact that this was going to be targetted on the PIC which has limited RAM resources - you can't just create big memory buffers for receiving data for example, not if you want RAM left for anything else. Once the Modbus library was working in Windows it was time to port it to the PIC.
Porting the Modbus library to the PIC was not that difficult. I am using the student edition of the Microchip C18 compiler. This seemed to cope with all the C code that I threw at it. I only had to make a handful of tweaks to make it compile plus implement the serial send/receive functions to actually transfer the data.
http://www.modbustools.com/modbus.asp - Good description of the Modbus protocol.