My place...

There's only 10 kinds of people who understand binary:
Those who do and those who doesn't...

2012-03-18 17:17







Your Link

Your Link

Your Link

Your Link

PIC Links




PBP Forum




Text Box

Use this box to type any specials, new updates or even gallery pics here.


Mini MODBUS board

Update 2012-03-18: Kits and bare PCBs available.

Please see the bottom of page for further details or email me at:

henrik [at] henriksplace [dot] se


On this page I'll give you all the details needed to build your own PIC based MODBUS RTU slave board to be used with the Mach3 CNC control application or any other application/device acting as a MODBUS master. The hardware itself can obviosuly be used for any application you see fit but the firmware supplied on this page makes into a MODBUS RTU slave device.



Here's a list of the hardware features of the board:

  • 4 digital inputs, opto-isolated, with LED indicator.

  • 4 digital outputs, open collector, 500mA, LED indicator, protection diode.

  • 2 analog inputs, 0-5V, 10bit resolution.

  • 1 analog output, 0-10V, 10mV resolution, 50mA drive capabillity.

  • Wide operating voltage range, 15-30V


The schematic:

Click on the picture for a high resolution version or download as .pdf


When it comes to the hardware there's really nothing special going on. Your typical linear voltage regulator, standard PIC circuit operating from its internal oscillator, MAX232 level translator for the RS232 interface, PC817 opto isolators for the inputs, ULN2803 for the outputs and a rail-to-rail OP for the analog output - that's pretty much it.

As you can see I've brought out both legs of the LEDs in the opto-isolators to the connectors. This provides the highest flexibillity when it comes to interfacing various sensors etc. The value of the series resistors (R15-R18) can be choosen to properly match any desired input voltage.

The ULN2803 darlington driver used to drive the outputs contains 8 drivers, each capable of sinking 500mA. Since the board only has 4 outputs I've connected two drivers in parallell for each output. Even so I'd try to stay around a maximum current of 500mA.

The two analog inputs are wired straight from the connector to the PICs analog input, the maximum input voltage is 5V. If, for example, 0-10 input range is desired an external voltage divider must be used.

The analog output is driven by the PICs ECCP module feeding an 8kHz PWM signal thru a low-pass filter and then thru an amplifier with a gain of 2. This makes the analog output 0-10V. It's not super accurate and/or ultra linear but for a cheap board like this I think it's good enough.


The board (86x65mm):


Click on the pictures for larger version.

(The photo of the board shows Rev.A while the screenshot shows Rev.C containing minor changes and additions)


The provided board layout uses all thru-hole parts for easy soldering, even at the kitchen table and assembling it is pretty straight forward. (All the passives first, then the powersupply components, verify that the powersupply is working then install the rest of the components).


You can of course build the circuit up on a piece of perf-board or you can modify (or redo) the provided boardfile to suit your particular needs if you wish. Perhaps you want relays directly on the board? Perhaps you want AC-coupled inputs? Perhaps you want differential analog inputs or +/-10V analog output? Perhaps you want 4-20mA current loop output instead of 0-10V? Those and other things are all possible by modifying the hardware. As long as the different inputs and outputs goes to the same pins on the PIC as in the above schematic the provided firmware will work.


The connectors are 3.5mm pitch screw terminals. I really like the pluggable ones so I used those on my prototype but you can obviously use any type you want as long as they fit - or you can solder wires directly to the board if that's your thing.


A BOM with Digikey part numbers is provided in the download at the bottom of the page, all in all the parts come in at around $25, PCB not included. However, most of the components are "jelly bean parts" and not critical at all. If you've been tinkering with electronic it's likely that you have several of the needed parts already and if you're able to read and understand the schematic you also know which parts you can swap for others that you may already have lying around.

  • X1 is the power supply connector, positive on (1) and negative on (2). There's a series diode to protect against reversed polarity. Supply voltage should be 15-30V (24V nominal) but may be as low as 8V if a full 10V swing isn't needed from the analog output.

  • X3 and X4 are the two analog inputs. Pins (1) and (3) provides 5V and GND respectively and pin (2) is the actual signal input. This caters for easy interfacing to potentiometers etc.

  • X5 carries the four digital inputs, (1) and (2) is input 0, (2) and (3) is input 1 and so on.

  • X6 is the connector for the four outputs. The ground of the powersupply feeding the devices switched by the outputs must be common with the ground of the board and connected to (6). The supply voltage for the outputs can be anything from 5-50V and it should be connected to (1) in order for the protection diodes to be able to their job. (See example further down on the page.)

  • X7 is the connector for the analog output. Signal on (1), GND on (2). The analog voltage is not galvanically isolated from the rest of the board.

  • The 6-pin header K1 is used to program the PIC18F14K22 microcontroller on board. The pinout matches that of the PICKit2/3 in-circuit serial programmer/debugger.

  • JP1 is used to enter Setup-mode for the provided firmware. In setup mode you can set baudrate and parity, toggle outputs and read inputs etc. More details on that further down on the page.

The firmware.

The firmware provided in the download package makes the board into a MODBUS RTU slave. Here's a short list of some of its features:

  • Selectable baudrate, 2400, 9600, 19200, 38400, 57600, 115200 baud

  • Selectable parity, EVEN or NONE (ODD parity is not supported)

  • Selectable slave adress (see note)

  • Analog inputs are oversampled, creating a psuedo-resolution of 12 bits.

  • MODBUS diagnostic counters.

  • Setup-mode can be used to set outputs and read inputs without the need for a MODBUS master device.

Note: The firmware allows you to set the device adress on the MODBUS network but the hardware implementation only supports a single device due to the RS232 interface. If you're in need of more I/O and/or multiple devices I have "larger" boards available as well.


There's only one RS232 interface on the board so once the firmware enters setup-mode it stops responding to MODBUS requests and will remain in setup-mode untill the board is restarted.


Getting the firmware into the PIC is just a matter of using you favorite PIC device programmer, personally I use the PICKit3. You can program the device in circuit or before mounting it on the board - which ever you prefer. Having an in circuit programmer is preferable since it allows you to update the firmware without having to remove the chip from the board. The pin header K1 matches the pinout of the PICKit2/3.


Using the setup-mode.

As soon as the JP1 jumper on the board is shorted the firmware stops responding to MODBUS requests, forces a baudrate of 57600-8-N-1 and enters setup mode. If you have a terminal emulator (Putty, Teraterm, Hyperterminal etc) connected you'll get a short menu, looking something like this:


  • A - Sending A3<ENTER> changes the slave adress to 3.

  • B - Changing the baudrate is just as easy but the various baudrates corresponds to a single digit number like this: 0=2400, 1=4800, 2=9600, 3=19200, 4=38400, 5=57600, 6=115200 so to change the baudrate to 115000 you type B6<ENTER>

  • C - Sending C<ENTER> will clear all the MODBUS diagnostic counters.

  • P - Sending P0<ENTER> gives you NONE as parity, sending P1<ENTER> gives you EVEN.

  • R - Sending R<ENTER> will restart the board. If changes have been made but not saved they will be lost. Remember that if you've placed a jumper across JP1 the board will immediately re-enter setup-mode. If that's not your intention make sure to remove the jumper prior to restarting the board.

  • S - The analog output can be controlled in 0.1% resolution by sending S123<ENTER> for 12.3%, S789<ENTER> for 78.9%, S1000<ENTER> for 100% and so on. Sending values above 1000 will set the output to 100%.

  • T - The digital outputs can be toggled by sending Tn<ENTER> where n is the number of output (0-3) you wish to toggle. Example: T2<ENTER>

  • W - If this is set to anything but 0 the watchdog feature is enabled. This feature will turn off the outputs if no MODBUS frame is received within the specifed time. The time is specified in units of 100ms so sending W15<ENTER> will set the timeout threshold to 1.5s. The state of the coil registers are left unaltered and the outputs will be renabled with states reflecting the coil registers as soon as any valid MODBUS frame is received. This feature was added in firmware v1.10

  • X - Will save your current settings (slave adress, baudrate and parity) to the non volatile EEPROM memory after which you need to restart the board by either sending R<ENTER> or cycling power to the board in order for the new settings to be used.

  • ? - Sending ?<ENTER> will reprint the menu with the current settings. Note that the displayed settings may or may not have beed saved.

  • D - Sending D<ENTER> gives you the following diagnostics menu:


The first 8 lines are the MODBUS diagnostics counters. The first shows how many MODBUS messages the device has detected - all in all. The 4th shows to how many of those messages the slave have responded. For more details about those and the other counters please see the MODBUS protocol specification.


At the bottom half you can see the state of digital outputs, digital inputs, the two analog inputs and the analog output. The values does not "auto-update" on screen so you need to send D<ENTER> again to "refresh" the screen.


Anytime you send a valid command you'll get a response. For example:

  • If you send B3 to change the baudrate to 19200 the board will respond with MODBUS Baudrate 19200

  • If you send T2 to toggle output 2 the board will respond with Done

  • If you send S750 to set the analog output to 75% the board responds with Analog Output 75.0%

  • If you send X to save the settings the board will respond with Parameters saved. Remove setup jumper and restart board.


MODBUS Adresses

MODBUS Adress Accesses Function code Comment
    Read Write  
Coil 0 Output 0 1 5, 15  
Coil 1 Output 1 1 5, 15  
Coil 2 Output 2 1 5, 15  
Coil 3 Output 3 1 5, 15  
Coil 4 Output 0 (blink) 1 5, 15 v1.10
Coil 5 Output 1 (blink) 1 5, 15 v1.10
Coil 6 Output 2 (blink) 1 5, 15 v1.10
Coil 7 Output 3 (blink) 1 5, 15 v1.10
Input 0 Input 0 2 N/A  
Input 1 Input 1 2 N/A  
Input 2 Input 2 2 N/A  
Input 3 Input 3 2 N/A  
Input reg 0 Analog input 0 4 N/A  
Input reg 1 Analog input 1 4 N/A  
Input reg 2 Inputs 0-3 4 N/A  
Input reg 3 Diag counter 0 4 N/A  
Input reg 4 Diag counter 3 4 N/A  
Holding reg 0 Analog out 0 3 6, 16  
Holding reg 1 Analog in 0 gain 3 6, 16  
Holding reg 2 Analog in 1 gain 3 6, 16  


A couple of quick notes here.

  • The four discrete inputs can be accessed either as single entities (function code 2) or they can be read as a bit-packed 16bit value thru input register 2 (function code 4). In the later case the lowest significant bit in the 16bit value corresponds to Input 0. Ie. a value of 9 means that Input 3 and Input 0 are "on".

  • Holding registers 1 and 2 can be used to control the gain of the analog inputs. By default they both contains the value 256 which is equal to a gain of 1. If the value 512 (a gain of 2) is written to Holding Register 1 the value returned in Input Register 0 will range from 0 to 8192 for the 0-5V input range of analog input 0. Likewise if the value 128 (a gain of 0.5) is written to Holding Register 2 the value returned in Input Register 1 will range from 0 to 2048 for the 0-5V input range of analog input 1. It does not alter the analog voltage in any way it just scales the value returned by the ADC.

  • As described earlier the MODBUS specification contains a number of diagnostics counters (8 to be precise). I've "mirrored" two of these to normal Input Registers making them readable even by MODBUS masters not supporting the proper function codes for accessing the diagnostics counters. Input Register 3 contains the content of Diagnostics counter 0 - which is the total number of MODBUS messages detected on the bus. Input Register 4 contains the content of Diagnostics counter 3 which is the number of MODBUS messages responded to by the slave.

  • Coils 4-7 accesses the same physical outputs as coils 0-3 but when coils 4-7 are used the output automatically toggles at ~1Hz. Coils 4-7 have precedence over coils 0-3 meaning that whenever coils 4-7 are '1' the output(s) will blink regardless of the state of coils 0-3.


Connecting to the real world


Here's an example of the board wired up to a couple of different devices. I apologize for the crude MS Paint drawing.



Because the inputs exposes both legs of the opto-isolator LED they are very flexible. They can easily be interfaced to both PNP and NPN type switches and since they are isolated from each other (and the rest of the board) they don't have to share the same powersupply or ground even if that is how it's pictured here. You can have two 5V inputs, one 12V and one 24V input if that's what you want.


The outputs are open collector type meaning they "switch to ground". This means that in theory the supply voltage for the devices being switched by the outputs can be different for all four outputs (12V lightbulb on output 1 and 48V relay on output 2) but that presents a problem for the internal clamp diodes in the ULN2803. If you wish to switch loads with different supply voltages you should add external protection/clamp diodes and leave terminal (1) on X6 unconnected. Note that the GND connection for the outputs is not isolated from GND for the board itself.

Finally, you don't have to use three separate powersupplies like shown above. If all your devices operates on the same voltage you can use a single supply.


Here you can download the various files needed for the project. The design file package contains the EAGLE schematic and board layout files, the Gerber and Excelon files needed to get the board fabricated by a board house (I used SeeedStudio), the BOM for the particular revision of the board and a .pdf version of the schematic.

The firmware package contains the .hex file to be programmed into the the PIC and a .txt file containing release/change notes.

Please note: The source code for the firmware is not included and I currently don't have any intention to release it. One of the reasons for doing this project was to show some of the capabilities of the MODBUS "driver" I've developed for the PBP compiler. My intention is to license that driver to other developers using PBP who are looking for a MODBUS driver. This application works as a "demo" for that driver. So, the source code is not available.


I've put together a small tutorial on how to setup Mach3 to talk to the MiniMODBUS board.


Kits and bare boards available

If you're interested in building a miniMODBUS board but don't want the hassle of making or ordering PCBs, sourcing components and getting the firmware flashed into the microcontroller I can now help with that.


Bare board ($15USD, shipping included)

You'll get a bare PCB of the latest revision (currently Rev.C), professionally manufactured. The cost is $15USD including a flat rate shipping (additional boards are $10USD). To keep the cost down the parcel is sent as normal mail so there's no tracking or insurance. If you feel that you want or need tracking etc please contact me.



Kits ($65USD, shipping included)

You'll get a PCB of the latest revision (currently Rev.C) and all components needed, including the microcontroller programmed with the latest firmware (currently v1.1). The cost is $65USD which includes flat rate international shipping with tracking.


Please note that the kits are supplied with the standard type 3.5mm pitch screwterminals, not the pluggable ones shown in the photos at the top of the page. You can see the ones supplied with the kit thru the plastic bag in the above photo.


If you want to sourde the components yourself but don't have access to a PIC device programmer I can also supply the PCB with the microcontroller mounted and programmed with the latest firmware version. The cost is $25USD including postage (no tracking).


Payment is best handled thru PayPal, my account is the same the same as the E-mail adress shown below.


If you build a device, in any way shape or form, please drop me a line. Same thing applies if you have a problem or question or if you're interested in a kit or blank PCB. Adress is:



Copyright 2012 Henrik Olsson. All Rights Reserved.
Template downloaded from:
FrontPage Templates