NAME
RPi::Serial - Basic read/write interface to a serial port
SYNOPSIS
use RPi::Serial;
my $dev = "/dev/ttyAMA0";
my $baud = 115200;
my $ser = RPi::Serial->new($dev, $baud);
# Write a single char
$ser->putc(5);
# Write a string
$ser->puts("hello, world!");
# Write a single byte by its integer value (0-255)
$ser->write(65);
my $char = $ser->getc;
# Get a string
my $num_bytes = 12;
my $str = $ser->gets($num_bytes);
# Send a CRC-framed payload between start/end delimiters
$ser->tx("payload", "<", ">");
# Receive a CRC-framed payload (call in a loop until it returns the data)
my $frame = $ser->rx("<", ">");
my $crc = $ser->crc($str);
$ser->flush;
my $bytes_available = $ser->avail;
$ser->close;
DESCRIPTION
Provides basic read and write functionality of a UART serial interface
WARNING
If using on a Raspberry Pi platform, the procedure to enable GPIO pins 14 (TXD) and 15 (RXD) as a serial interface differs by board. On all boards, first free the port from the kernel console: in raspi-config, under Interface Options -> Serial Port, answer no to the login shell and yes to the serial hardware.
Raspberry Pi 3 / 4 (and Zero W)
The on-board Bluetooth modem is wired to the primary PL011 UART, leaving GPIO 14/15 on the inferior, baud-unstable mini-UART (/dev/ttyS0). To move the good UART onto the header pins you must disable Bluetooth. Edit /boot/firmware/config.txt (/boot/config.txt on releases before Bookworm) and add:
enable_uart=1
dtoverlay=disable-bt
With that overlay the header serial port becomes /dev/ttyAMA0.
Raspberry Pi 5
Bluetooth has its own dedicated UART and is not shared with the GPIO 14/15 pins, so there is nothing to disable. Just enable the header UART in /boot/firmware/config.txt:
enable_uart=1
The header serial port is /dev/ttyAMA0. (Note that on the Pi 5 /dev/serial0 maps to the separate 3-pin debug-UART connector, not the header pins.)
Save the file, then reboot the Pi.
METHODS
new($device, $baud);
Opens the specified serial port at the specified baud rate, and returns a new RPi::Serial object.
Parameters:
$device
Mandatory, String: The serial device to open (eg: "/dev/ttyAMA0").
$baud
Mandatory, Integer: A valid baud rate to use.
close
Closes an already open serial device.
avail
Returns the number of bytes waiting to be read if any.
flush
Flush any data currently in the serial buffer.
fd
Returns the ioctl file descriptor for the current serial object.
getc
Retrieve a single character from the serial port.
gets($num_bytes)
Read up to a specified number of bytes and return them as a string.
The read blocks only until the port's configured read timeout (the VTIME value set when the port was opened) elapses, so the returned string may be shorter than $num_bytes if fewer bytes arrived in time (or the device closed). The result is binary-safe: embedded NUL bytes and trailing whitespace are preserved exactly as received.
Parameters:
$num_bytes
Mandatory, Integer; The maximum number of bytes to read. If this number is larger than what is available, the call returns the bytes received before the read timeout elapsed (possibly an empty string).
Returns: A string of the bytes actually read. Croaks on a read error.
putc($char)
Writes a single character to the serial device.
Parameters:
$char
Mandatory, Unsigned Char: The character to write to the port.
puts($string)
Write a character string to the serial device.
Parameters:
$string
Mandatory, String: Whatever you want to write to the serial line.
crc($string)
Calculate and return a CRC-16 checksum. Uses local crc16.c application to generate the CRC.
Parameters:
$string
Mandatory, String: The string to perform the checksum on.
write($byte)
Writes a single byte to the serial device. The byte is packed into an unsigned char before being sent, making this a convenience wrapper around "putc($char)" that accepts an integer value rather than a character.
Parameters:
$byte
Mandatory, Unsigned Integer (0-255): The byte value to write to the port. Croaks if not supplied.
rx($start, $end)
Reads a single character from the serial port and assembles framed data across successive calls. A frame begins when the $start delimiter is received and ends when the $end delimiter is received, at which point the two trailing CRC-16 bytes are read and validated against the assembled payload.
Call this repeatedly (eg: in a loop). Until a complete, CRC-valid frame has been received it returns undef; characters seen before the $start delimiter are discarded.
Parameters:
$start
Mandatory, Char: The single character that marks the beginning of a frame.
$end
Mandatory, Char: The single character that marks the end of a frame.
Returns: The assembled payload string once a full frame with a matching CRC has been received, or undef otherwise. Warns and discards the frame if the received CRC does not match the locally computed one.
tx($data, $tx_start, $tx_end)
Transmits a frame of data. The $data is wrapped between the $tx_start and $tx_end delimiters and written to the port, followed by the two bytes (most significant first) of the CRC-16 checksum calculated over $data.
Parameters:
$data
Mandatory, String: The payload to transmit.
$tx_start
Mandatory, Char: The single character to send before the payload.
$tx_end
Mandatory, Char: The single character to send after the payload.
AUTHOR
Steve Bertrand, <steveb at cpan.org>
LICENSE AND COPYRIGHT
Copyright 2026 Steve Bertrand.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.