Raspi_Perl_Notes

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Disable it by adding a # character to the beginning. Save the file.

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Then update:

/boot/cmdline.txt

The contents of the file look like this

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Remove all references to ttyAMA0 (which is the name of the serial port). The file will now look like this

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Reboot

Below are notes specific to using Perl on Raspberry Pi

Serial Port Communication:

Note: See this web page about device names for RaspPi 3 vs. previous models:

https://www.raspberrypi.org/documentation/configuration/uart.md

(from that page):

By default, on Raspberry Pis equipped with the wireless/Bluetooth module (Raspberry Pi 3 and Raspberry Pi Zero W), the PL011 UART is connected to the BT module, while the mini UART is used for Linux console output. On all other models the PL011 is used for the Linux console output.

In Linux device terms, by default, /dev/ttyS0 refers to the mini UART, and /dev/ttyAMA0 refers to the PL011. The primary UART is that assigned to the Linux console, which depends on the Raspberry Pi model as described above, and can be accessed via /dev/serial0.

....

By default, the UART transmit and receive pins are on GPIO 14 and GPIO 15 respectively, which are pins 8 and 10 on the GPIO header.

================================

Before trying to write serial code - you need to install the Device module on the Raspi:

sudo apt-get install libdevice-serialport-perl

You also have to disable the Pi from writing all the console debug info to the serial port.

There are two files that need to be edited. Both must be edited by root. You can function as ROOT by executing:

sudo su - root

Once root, then you can edit the two files. If Emacs in installed, use it. Otherwise, use vi.

Files to update:

/etc/inittab

COMMENT OUT the line that starts with: T0:23

Then, you can include the code below in a script:

#!/usr/bin/perl -w

use strict;

BEGIN{

push @INC,"/usr/lib/perl5/";

}

use lib '/usr/lib/perl5/Device';

use Device::SerialPort;

my $port = Device::SerialPort->new("/dev/ttyAMA0");

$port->baudrate(9600);

$port->databits(8);

$port->parity("none");

$port->stopbits(1);

# to write:

$port->write("stuff to write\n");

# to read:

$char=$port->lookfor();

if($char){

print "Got stuff: $char\n";

}

Getting the command line in a Perl script:

use strict;

use FindBin;

use Cwd 'abs_path';

my $cmdfile = abs_path(__FILE__);

my $scriptname;

$scriptname=$cmdfile;

$scriptname=~s/.*\///; # chomp off path

my $cpath=$cmdfile;

$cpath=~s/\/[^\/]+$//; # get just the path to the command file

Perl timer functions with higher resolution than 1 second:

#!/usr/bin/perl

use strict;

use warnings;

use Time::HiRes qw(usleep nanosleep);

# 1 millisecond == 1000 microseconds

usleep(1000);

# 1 microsecond == 1000 nanoseconds

nanosleep(1000000);

Socket Communications over TCP:

http://xmodulo.com/how-to-write-simple-tcp-server-and-client-in-perl.html

In this example, client connects to a server with well-known IP address and port. Once client is connected to the server, it sends data to the server, and waits for a reply. Upon receiving data from client, server responds with an acknowledgement message.

The purpose of shutdown(SOCKET, 1) in the example is to tell the other end that you have finished sending data, without closing SOCKET. Note that you can still receive data afterward.

TCP server example in Perl

use IO::Socket::INET;

# auto-flush on socket

$| = 1;

# creating a listening socket

my $socket = new IO::Socket::INET (

LocalHost => '0.0.0.0',

LocalPort => '7777',

Proto => 'tcp',

Listen => 5,

Reuse => 1

);

die "cannot create socket $!\n" unless $socket;

print "server waiting for client connection on port 7777\n";

while(1)

{

# waiting for a new client connection

my $client_socket = $socket->accept();

# get information about a newly connected client

my $client_address = $client_socket->peerhost();

my $client_port = $client_socket->peerport();

print "connection from $client_address:$client_port\n";

# read up to 1024 characters from the connected client

my $data = "";

$client_socket->recv($data, 1024);

print "received data: $data\n";

# write response data to the connected client

$data = "ok";

$client_socket->send($data);

# notify client that response has been sent

shutdown($client_socket, 1);

}

$socket->close();

TCP client example in Perl

use IO::Socket::INET;

# auto-flush on socket

$| = 1;

# create a connecting socket

my $socket = new IO::Socket::INET (

PeerHost => '192.168.1.10',

PeerPort => '7777',

Proto => 'tcp',

);

die "cannot connect to the server $!\n" unless $socket;

print "connected to the server\n";

# data to send to a server

my $req = 'hello world';

my $size = $socket->send($req);

print "sent data of length $size\n";

# notify server that request has been sent

shutdown($socket, 1);

# receive a response of up to 1024 characters from server

my $response = "";

$socket->recv($response, 1024);

print "received response: $response\n";

$socket->close();

TIME - EPOCH conversions:

See code below for sample of how to do epoch to date and back...

#!/usr/intel/bin/perl

$|=1; # turns off buffering

## This is a simple script to demonstrate using localtime and timelocal

## functions to convert a datestamp to epoch and back.

## The time(); function is used to get the current epoch time.

## use Time::localtime; ### DO NOT USE Time::localtime - it will return

## a *structure*(?) from the localtime function

use Time::Local; ## required for the 'timelocal' function to convert

## an array to an epoch time

my $i,j,k,e;

my @weekday = qw(Sun, Mon, Tues, Wed, Thu, Fri, Sat);

my $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst;

$e=time();

print "local time epoch: $e\n";

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($e);

$year = $year + 1900;

$mon += 1;

print "Formated time = $mday/$mon/$year $hour:$min:$sec $weekday[$wday]\n";

print "\nDo it again...\n";

$e+=3742;

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($e);

$year = $year + 1900;

$mon += 1;

print "Formated time = $mday/$mon/$year $hour:$min:$sec $weekday[$wday]\n\n";

## now convert back...

$year=2018;

$mon=5;

$mday=28;

$hour=13;

$min=37;

$sec=51;

$j=timelocal($sec,$min,$hour,$mday,$mon,$year);

print "Epoch time is: $j\n";

# convert forward...

($sec,$min,$hour,$mday,$mon,$year) = (localtime($j))[0,1,2,3,4,5];

$year = $year + 1900;

$mon += 1;

print "Printing scalar localtime of epoch: ";

print scalar localtime($j);

print "\nFormated time = $mon/$mday/$year $hour:$min:$sec \n";

SCP Stuff:

Copying files to your Raspberry Pi

Copy the file myfile.txt from your computer to the pi user's home folder of your Raspberry Pi at the IP address 192.168.1.3 with the following command:

scp myfile.txt pi@192.168.1.3:

Copy the file to the /home/pi/project/ directory on your Raspberry Pi (the project folder must already exist):

scp myfile.txt pi@192.168.1.3:project/

Copying files from your Raspberry Pi

Copy the file myfile.txt from your Raspberry Pi to the current directory on your other computer:

scp pi@192.168.1.3:myfile.txt .

Copying multiple files

Copy multiple files by separating them with spaces:

scp myfile.txt myfile2.txt pi@192.168.1.3:

Alternatively, use a wildcard to copy all files matching a particular search with:

scp *.txt pi@192.168.1.3:

(all files ending in .txt)

scp m* pi@192.168.1.3:

(all files starting with m)

scp m*.txt pi@192.168.1.3:

(all files starting with m and ending in .txt)

Filenames with spaces

Note that some of the examples above will not work for file names containing spaces. Names like this need to be encased in quotes:

scp "my file.txt" pi@192.168.1.3:

See this page for info on ssh keys: https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md