Monday, August 27, 2012

Raspberry Pi Serial Port

Prototyping the serial port interface.
Many of the GPIO pins on the Pi have other special uses.  The most useful of these are the serial port pins #8 and #10, which are transmit and receive for an RS-232 serial port.  By default this port will output diagnostic messages during boot and then provide a user login.  The configuration is 8 bits, no parity, 1 stop bit, no hardware handshaking, at 115200 baud.  The device name is /dev/ttyAMA0.

I need to use this serial port to interface to my X10 system via a CM11A computer interface module.  That can be a topic for several future posts.

First lets cover some important facts about RS-232 and voltage levels.  The Pi uses levels that are 0V to represent a zero and 3.3V to represent a one.  RS-232 uses -3V to -15V to represent a zero and 3V to 15V to represent a one.  Thus, a level converter is required to create this interface.  The MAX232 series of chips was designed for this exact purpose.

External capacitors are needed to drive the charge pumps inside the chip.  Note: There are several variations of the MAX232 chip which have different requirements.  The one shown in the circuit here uses 0.1uF capacitors.  The ones I have use 1.0uF and some versions even have the capacitors built in.  When in doubt, check the datasheet for the chart that shows the requirements for each variation.
Data Sheet for MAX232 family

If, like me, you want to take complete control of the serial port for your own uses, there are two configuration changes to make:

First, disable the boot up and diagnostic output to the serial port.
sudo vi /boot/cmdline.txt
and remove the two options referring to the serial port.
So, this
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
becomes this
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Second, disable the login prompt
sudo vi /etc/inittab
find the line near the end
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
and delete it or comment it out by putting a # at the start of the line.

Reboot and the serial port will now be free for your exclusive use.


  1. How can I listen for data on AMA0 in the console without any other scripts?

  2. Need to stop OS from using the serial port as described in the post.
    (Feel free to use nano in place of vi as the editor.)

    Then set baud rate with command like:
    sudo setserial /dev/ttyAMA0 baud_base 9600

    The you could do something as simple as
    cat /dev/ttyAMA0
    and any data from the serial port would echo on the console.
    Hopefully not binary data, and line feeds (or a lack of them) can be a problem to readablility.
    Press Ctrl-C to stop

    If you want a full terminal emulator on the console, you could use minicom.
    If you are on X you could use gtkterm.

  3. Hy,

    Could you explain more about the purpose of the capacitors?

    I would use this IC

    Does that mean it has built in capacitors and i don't need to use extra ones?

    1. That is the typical MAX232 chip and does need capacitors.
      The chip has to take 5V and produce +15V and -15V. In reality, it will typically only produce around 9V.
      The chip uses a circuit called a "charge pump" to achieve this.
      Capacitors are needed to store the additional charge required for this circuit.

      MAX232 chips are intended for 5V circuits. Since the Raspberry Pi is a 3.3V device, a better choice would be the MAX3232 chip, which will work for 3.0 to 5.5V

      There are versions of the MAX232 that have built in capacitors. Also, some versions use external 1uF caps while others use 0.1uF caps.Check the data sheet for whatever chip you use to be sure you have it right. Using larger caps than required is OK.

    2. And the MAX3232 chip needs to be powered from the 3.3 Volt GPIO pin 1 NOT 5V.

    3. "which will work for 3.0 to 5.5V"
      It will work from either for power.
      However, the data pins are 3.3V so you don't need level convertors.

  4. Thanks for posting this! It's just what I was looking for.

  5. Dear Ted,
    thanks for this manual - this works just beautifully, especially thanks for the schematics. I'm using a MAX2323CPE here.
    Maybe it'd be nice pointing out that the voltage levels on the RPI Rx and Tx are +3.3V without having a RS232 device attached to the MAX232, while the Rx drops to 0 when a device is sending bits.
    Best regards! Steffen

  6. Hi,

    we can not use Rs232 direct normal port,


    we can use pi's usb ports convert to usb - rs232 and we can see our PC terminal send or receive any data so no problem all OK

    but when we use direct pi's rs232 port GPIO15 / 16 pins... connect to MAX3232 and change for 3.3V then connec to PC after we can Pi send but can not any data take...

    if we want take any data for Pi we do send data 20 times or 30 times after Pi can take and show to terminal page this data... but we must do 20 or 30 times send from PC to Pi....

    but if we use Pi's USB port to PC Rs232 port every thing is OK good work... but Pi'original Rx/Tx pins not normaly work...

    so Please help to us for about... you can send to me any email... I will wait...

    thanks alot...

  7. I've just written a neat little Bash script to automate the task of disabling the RPi's serial console, enabling it to be used as a regular 3.3V serial port.

  8. I find connecting two Raspberry Pi, that between 10 and 50 percent of echos go missing this way, am I doing something wrong?
    or to put it another way, I would like to send a single 8 bit number from one RPi to the other,
    is there a simple way to ensure it is received?

  9. Hi,
    I'm trying to do this on a Pi with Xbian installed. The project is for a PWM controlled fan for CPU cooling my aggressively over clocked media centre. My desire to use the UART port comes from the fact that I have a nice three pin plug that connects to the ground, 5V and the UART Tx pin (as they are all in a row). I'd thus like to use that Tx as the PWM pin.

    However the cmdline.txt file has no references to the serial controller, nor does the equivalent of the login prompt for Xbian, which appears to be /etc/init/tty1.conf and is referenced directly in the cmdline.txt file:

    sdhci-bcm2708.sync_after_dma=0 dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootflags=subvol=root/@,autodefrag,compress=lzo rootfstype=btrfs rootwait smsc95xx.turbo_mode=N elevator=cfq logo.nologo quiet noswap loglevel=0 mod_scsi.scan=sync partswap startevent=mountall splash nohdparm --startup-event mountall

    The tty1.conf file reads:
    start on stopped rc RUNLEVEL=[2345] and (
    not-container or
    container CONTAINER=lxc or
    container CONTAINER=lxc-libvirt)

    stop on runlevel [!2345]

    exec /sbin/getty -8 38400 tty1

    So, my question is: is there a way to disable the UART ports or is that step not even necessary?

  10. This comment has been removed by the author.

  11. This comment has been removed by a blog administrator.

  12. Hello Ted, Useful Post! Thanks for sharing :)

    I have a question:

    How to permanently disable the serial port?
    It seems that the changes suggested by you does not survive a reboot!
    So any insights upon how can I do that?

    1. The changes should survive a reboot. What OS are you using? I did this on Raspbian Linux. It is possible that there are changes related to device tree overlays in the latest version that affect the serial port. I will look into that.

  13. Thanks for posting this, but before I head down this path, I'm wondering if this is still a correct procedure for use with the Raspberry Pi 3?

    1. Yes, this is still the same for the Pi 3.
      One hardware change from the design above that I recommend is to use a MAX3232 instead of a MAX232. The MAX3232 is designed for 3.3V systems so you won't need to convert the voltage for the Pi.