« Back to home

Serial Programming - Part 3 (PIC16F628A)

This is the fourth in a series of articles describing the construction of an interface board suitable for controlling 2 motors, 2 servos and providing a collection of binary inputs and outputs; previous posts are ...

  1. Microcontrollers - The PIC16F628A
  2. Serial Programming - Part 1 (PIC16F628A)
  3. Serial Programming - Part 2 (PIC16F628A)

    The board provides limited onboard intelligence (only enough to protect the motors and servos from invalid operations) - it is designed to be controlled from an external computer through an RS232 connection.

I've spent the last few days playing with Fritzing which is a great tool for the home electronics hobbyist - I'll do a full post on it in the near future. The schematic and breadboard layout images in this post were prepared with Fritzing, I'm strongly considering using it as the default tool for all future electronics related posts.

RS232 Electrical Characteristics

The RS232 standard defines the voltage levels needed to indicate a logic 1 or logic 0 in a way you may not expect. A logic '1' is a voltage between -3V and -12V, a logic '0' is a voltage between 3V and 12V. Any serial connection that has a D type connection will most likely adhere to these principles. Serial connections that are accessed by pin headers (on the Raspberry Pi for example) will use voltage levels that are native to the device. For the Raspberry Pi this means that a logic '1' on the Tx pin is 3.3V and a logic '0' on the Tx pin is 0V (and these are the voltage levels expected on the Rx input pin).

USB to RS232

The circuit I provide here uses a MAX232 chip to convert from native logic levels to standard RS232 levels. It is very important that you do not connect the output from this chip directly to the inputs of devices that are expecting native levels (such as the Raspberry Pi) - you run a good chance of frying your board.

Unfortunately most modern computers don't provide an RS232 port - you can get around this by using a USB to Serial adaptor - this plugs into the USB port of your computer and provides one or more 9 pin RS232 connectors. See the image on the left for an example of this type of device.

The Serial Circuit

Serial Interface

Since this is simply a test for serial IO the circuit (shown to the right) is fairly simple - we run the TX and RX pins from the PIC to the MAX232 chip. I've added LED's (with appropriate current limiting resitors) to both TX and RX lines so we can get a quick visual indication of data transfer taking place - each LED will flicker as data is transfered on the given line. The remaining discrete components (5 x 1uF capacitors) are required by the MAX232 chip. One of the capacitors acts as a filter across the positive voltage input and ground (this minimises the effect of changing load on the power supply - here is a good description of their purpose) and the remaining capacitors are used as charge pumps to increase the base voltage. The 1uF values here let the MAX232 generate output voltages of -9V and 9V - well within the defined range for RS232.

Breadboarding the Circuit

Serial Breadboard

Putting the breadboard together is fairly simple - the layout is shown in the image to the left (this was generated by Fritzing - one of the main features of this tool that makes it especially useful for hobbyists).

There are three important things to take note of here:

  1. The orientation of the IC's. The MAX232 is upside down relative to the PIC chip, the 'notch' on the PIC should face left, the MAX232 faces right.
  2. Make sure the orientation of the capacitors is correct when you place them.
  3. I've represented the power supply and serial connections as pin headers in this diagram. The power supply is on the left hand side - positive is the left pin, negative the right one. The serial connection is on the right hand side of the board and is ordered (from left to right) ground, TX and RX.

    Meet Reality

    The actual breadboard I made for testing can be seen on the right and is nowhere near as neat as the source image. I like to keep my connector wires as short as they need to be (using big loops of wire is not only messy it can lead to confusion and add electrical noise to the circuit through induction) - using packs of pre-cut wires helps but can get expensive over time (and they don't have all the lengths you need). I have an idea for a simple 3D printable tool that will help with this that I'm going to work on.

Serial Cables

Wiring up serial cables can be a real pain (here is a description of just some of the combinations) so for this project I've kept it very simple. The controller board is wired as a DCE device so connection wise it can by treated as if it were a modem. This way if you have an old modem cable lying around you can use that to connect the circuit to your PC - if you do need to wire up a cable it can be a simple 'straight through' cable (pin 1 to pin 1, pin 2 to pin 2, etc).

Serial Connector

I wired a female DB9 connector to a header using about 10cm of ribbon cable (see the image on the right). The USB to serial adaptor I am using has a long enough lead that I can plug the female connector directly into it without needing an intervening cable. In this configuration GND goes to pin 5, TX goes to pin 3 and RX to pin 2. The other pins on the DB9 connector can remain unconnected as they are unused in this configuration.


To test you need to configure your terminal program to communicate at 9600 baud, no parity, one stop bit and no flow control. Once everything is connected you should get the output described for the previous two serial programming posts. If you loaded the code from 'Serial Programming - Part 1 (PIC16F628A)' you will get the upper case characters A through Z repeated over and over. If you load the code from 'Serial Programming - Part 2 (PIC16F628A)' you will get each character you type sent back to you shifted up by one (so type 'A' and you will get 'B' - if you see the original character followed by the shifted character you probably have local echo enabled, you should turn it off).

One problem I did come across during testing was sporadic failures as the batteries discharged. The indicator LED's continued blinking but there was no display. This is because the internal clock is sensitive to voltage levels and will drift from it's nominated level of 4MHz as the battery output voltage drop, because the UART timing is derived from the clock speed the serial signals can no longer be interpreted by the PC. I switched to using a steady 5V output from a USB cable and the problem went away. It seems that any timing sensitive applications are going to require the use of a crystal oscillator, I'll design this functionality in for future circuits.

What Comes Next?

That's going to be it for serial communication for a while, the next article in this series will concentrate on digital input and output. We'll also look at using the built in timer on the PIC and how to use indirect addressing. That article will go up next weekend, I'm going to spend the rest of the week catching up on some other topics. I hope you've found it interesting and useful so far, I look forward to hearing your feedback.