Peter's electronic projects

PBUS communication bus for connecting microcontroller-based devices

page 2 >


PBUS is a multi-drop communication bus for microcontrollers. Each slave node participating in the bus communication can be sent commands and data, and can respond to them with status and data. The device nodes are connected through 3 wires: GND (ground), +5VDC (power) and the PBUS signal. The bus communicates by half-duplex 2400 bps 8-bit asynchronous serial transmission, using the built-in UART of the microcontrollers. Each node has a static unique 4-bit address, which is used during communication. The master node has address 0. The maximum number of slaves is 15.

RS485 compatibility

The PBUS protocol is fully compatible with an RS485 bus. It means that you could connect the same nodes to an RS485 bus instead of the 3-wire bus described here. The PIC source code is ready for use with RS485 - it already contains the code to maintain a TE (transmitter enable) output which is necessary for controlling an RS485 interface.The current master (PC) code must be modified to support the TE switching.

3-wire hardware interface examples

Powering the bus

The PBUS is powered from a power supply

Connecting a computer

A computer or an embedded RISC board with a standard serial port can be employed as a bus master. If your computer doesn't have a serial port, an USB to serial converter can be used. See page 2 for an FT232-based USB interface.

Connecting a microcontroller

A maximum of 15 nodes can be connected. They can be powered directly from the bus. The TTL level serial TX/RX signals are directly connected to the PBUS line.


PBUS communication is packet based. The master node sends a request packet, and waits for the addressed slave to send an answer packet. The slave node must answer within an 1000 usec time, otherwise it is considered to be absent, or the request packet was corrupted on reception. Slaves will discard previous input received when a gap longer than 200 usec is detected. Slaves will also discard packets in the following cases without response:
The slave answers the request packet with a response packet containing 0 as destination device ID.

Packets consist of bytes sent as 2400 bps 8-bit asynchronous serial stream with 1 stop bit, no parity. The minimum length of packets is 3 bytes, maximum is 18 bytes. Packet structure:

byte offset bits name description
0 7-4 DEVID destination device PBUS ID (0=master, 1-15=slave addresses)
0 3-0 LEN optional data length (0 means packet is 3 bytes, no optional data)
1 7-0 CMD MASTER command or SLAVE response code
2 7-0 DATA[] optional data, length is given in LEN (LEN=0 means no data)
2+LEN 7-0 CHKSUM packet checksum. All the packet bytes, including the CHKSUM byte summed will result zero

Internally implemented commands

The PIC slaves implement a few commands (in the range 58h-5fh) internally in the PBUS library code. All other commands are handed over to the linked application through calling "pbus_handler". The commands are:

dev cmd
M 5e CVER (check node version)
S 60 ROK <pbus version> [main version] [optional string describing node] current nodes do not return the optional string by default
M 5f CPING [optional data] (test if a node is present and the link is up)
S 6f RECHO [optional data echoed] PB12 sources will not echo the supplied ping data back
M 58 CNOOP (no operation)
S 60 ROK  
M 5b CLAST (repeat last response)
S   (copy of the last response packet sent)  
M 5c CRES (reset statistics counters)
S 60 ROK  
M 5d CSTAT (get PBUS statistics)
S 60 ROK <e1> <e2> <e3> [optional counters] The CRES and CSTAT commands can be disabled.

dev: M=master node (request), S=slave node (response)

Meaning of counters:

name description
e1 number of checksum errors
e2 number of good packets received
e3 number of good packets sent for me (not necessarily answered)

master node request sent
slave node response
5e (chksum=52)
60 69 10 (chksum=25)
ROK pbus=69 main=10
5f de 6f 54 (chksum=ad)
CPING de 6f 54
6f de 6f 54 (chksum=ed)
RECHO de 6f 54
5b (chksum=55)
6f de 6f 54 (chksum=ed)
RECHO de 6f 54
5d (chksum=53)
60 00 00 04 00 04 00 (chksum=53)
ROK e1=0000 e2=0004 e3=0004

Additionally, a PBUS bootloader is planned, which would be implemented in self-programmable microcontrollers using new PBUS commands. The bootloader would contain a static library of PBUS and make the microcontroller externally available during programming, booting and also while the application code is running.

Source code for master node

The PC source is capable of being a master device. The command line pbus utility can be used to poll the slave nodes or to test the correct operation of the network. You can modify this utility into a daemon, which periodically polls all devices on the bus. The source code should compile on any POSIX-compatible OS. It has been successfully compiled and used on Linux and Openwrt MIPS (Ubiquiti routerstation, Asus WL500gP router) platforms.

Example usage of the command line utility:
pbus -s /dev/ttyS0 -d 5 -c 95 5 10 15 20 25 send a PING command (95 or 5fh) to node ID 5 containing 4 bytes of extra data. Use the serial port at /dev/ttyS0
pbus -s /dev/ttyS0 -d 5 -c 94 check the code version of the node ID 5

To compile the utility, enter cc -o pbus pbus.c

name version description download
pbus master utility, source code
pbus master utility, Openwrt package source
pbus master utility, compiled little-endian binary for MIPSEL linux platforms
(for example, Asus WL-500gP)
pbus master utility, compiled big-endian binary for MIPS linux platforms
(for example, Ubiquiti routerstation)

PIC source code for slave nodes

The PIC source is capable of being a slave device. It uses the built-in UART, the timer TMR1 and interrupts to participate in the communication of the bus. The code is organized into a separate library, and is fully interrupt-driven after initialization. The library is included with an example code which can set/get the PORTA digital I/O pins and direction bits in TRISA.

name version description download
PB628 069 PBUS interrupt driven slave node for devices with a free hardware UART. Written and tested on 16F628
PBUS interrupt driven slave node for devices with a free hardware UART. Written and tested on 16F88

The example code in main628.asm handles these custom 4 commands:

dev cmd
(get PORTA I/O bit states)
S 60 ROK <PORTA state>

M 54 PORTA <PORTA state>
(set PORTA I/O bit states)

(get TRISA bit states)
ROK <TRISA state>

(set TRISA bit states)

Example pbus commands for getting/setting the PORTA bits:

pbus -s/dev/ttyS0 -d5 -c84
get PORTA I/O state
pbus -s /dev/ttyS0 -d5 -c85 0
set all PORTA bits as output
pbus -s /dev/ttyS0 -d5 -c84 63
set all PORTA I/O bits (A0-A5) as HIGH


  1. Choose your device. Ready-made code is available for the PIC16F627/16F628/16F627A/16F628A and the PIC16F88 microcontrollers
  2. Download either the (16F628 version) or (16F88 version) project package
  3. Build the circuits under "powering the bus"  and "connecting to a computer"
  4. Use the circuit diagram found inside the package for connecting the microcontroller
  5. Connect all circuits using the 3 wires labeled "GND", "PBUS", "+5VDC"
  6. Optionally build the LCD interface found at and connect it to the microcontroller pins as shown:

    lcdif pin
    PIC16F88 (DIP18) pin
    PIC16F628 (DIP18) pin
    1 (GND)
    5 (GND)
    5 (GND)
    2 (EN)
    10 (RB4)
    10 (RB4)
    3 (CK)
    11 (RB5)
    12 (RB6)
    4 (DA)
    12 (RB6)
    13 (RB7)
    6 (+5VDC)
    14 (+5VDC)
    14 (+5VDC)

  7. Build the software HEX code. The code must be built as a linked project.

    - compile all assembler files
    gpasm -c main628.asm
    gpasm -c lcdlib.asm
    gpasm -c pbus628.asm
    - link all object files to HEX
    gplink -o pb628.hex -s 16f628.lkr main628.o lcdlib.o pbus628.o
    - start project wizard
    - select the target PIC device
    - choose the mplink object linker toolsuite
    - name your project
    - add all project files to the project
    - build the project
    - find the HEX output named as the project 
  8. Burn the resulting HEX file into the PIC mcu and put it inside the microcontroller circuit
  9. Build the code under "source code for master node" on a computer with Linux installed. Download pbus.c and compile with cc -o pbus pbus.c
  10. Connect the DB9F connector of the computer interface to a computer RS232 port. Power on the circuits through the power injector.
    The PIC slave LCD display first line should show "Pbus-069 s000000"
    The six zero digits are in HEX, and show the values of the e1, e2, e3 counters (checksum errors, packets received, packets for me). The second line shows the contents of the PIE, PIR, T1CON, RCSTA, TXSTA registers in HEX for debugging purposes
  11. Enter pbus -s /dev/ttyS0 -d 5 -c 94 on the computer. The default node id for the PIC slave is 5. If everything is OK, the PIC e2, e3 counters will increment on the first line of the LCD and the computer will show the response 60 69 10
  12. Optionally build another PIC slave and connect it with the 3 wires "GND", "PBUS", "+5VDC". Modify the main628.asm/main88.asm line movlw 0x50 to movlw0x60 (the node ID will be 6). Check if it works by entering pbus -s /dev/ttyS0 -d 6 -c 94 on the computer

page 2 >