Tuesday, 29 March 2016

HiPi Modules 0.45 Released

- Added interface for SPI MCP23S17 GPIO extender
- added convenience methods for MCP23017/MCP23S17
- Fixed bug in MCP23017 write_register_bits
- Build HiPI::Wiring against standard Rasbpian package
- Updated docs for device tree usage

To upgrade an existing installation

hipi-upgrade

For a first time install installation instructions are here.

Tuesday, 15 March 2016

HiPi Perl Modues 0.44 Released

This release of the HiPi Perl modules provides essential fixes for the SPI interface and the build system.

The installer and modules  have been tested on an RPi 3, RPi 2 and RPi Zero running the latest Raspbian Jessie release. They have also been tested on a Model B+, Model B and Model A running the Rasbian Wheezy releases.

Monday, 7 March 2016

HiPi Perl Modules 0.35 Released


              - bcm2835 library updated to version 1.50
              - Support for 40 pin GPO Pis
              - Support for RPI 2, RPI 3 and RPI Zero
              - Support Raspbian - Jessie
              - Fixes for Perl > 5.14
              - changed location of downloads to raspberrypi.znix.com
              - Wx version updated to 0.9928
              - Wx::Demo version updated to 0.22
              - Wx::PdfDocument version updated to 0.20
              - Alien::wxWidgets version updated to 0.67

To upgrade an existing installation

hipi-upgrade

For a first time install installation instructions are here.

Tuesday, 21 May 2013

HiPi Perl Modules 0.33 release

HiPi Perl modules version 0.33 has been released.

Release Notes:

Version 0.33 - 20 May 2013
- Fixed regression in 0.32 breaking uid and gid settings
- Add build options to avoid apt calls during cpan tests
- changed location of downloads to Google Code
- Wx version updated to 0.9922
- Wx::Demo version updated to 0.21

To upgrade an existing installation

hipi-upgrade

For a first time install installation instructions are here.

Saturday, 27 April 2013

HiPi Perl Modules and Interrupts

HiPi::Perl modules version 0.32 have been released containing modules that support GPIO interrupt handling in Perl.

Edit: These interrupt modules were removed from HiPi in release 0.66

Threads are created to handle interrupt response and pin value polling. True interrupt handling is implemented via the kernel sysfs gpio filespace and HiPi::Device::GPIO. Direct polling of the bcm2835 registers is implemented using the HiPi:: BCM2835 module.

Documentation for the interrupt handling modules is available in the online application help pages.

There are also three example scripts showing usage of the interrupt modules:

  • Derived Class Example shows handling interrupts by implementing your own derived class and overriding the base class methods.
  • Callback Example shows handling interrupts by  registering callbacks with the base class.
  • Mixed Handler Example shows handling interrupts for pins managed by HiPi::Device::GPIO and HiPi::BCM2835 with the same process.

As with all releases, an existing installation can be upgraded by calling:

hipi-upgrade

Full installation instructions are available on the install page.

Tuesday, 9 April 2013

Second I2C Bus

Warning - note that on all recent versions of Raspbian the second I2C bus pins are used by default for several functions so you may not want to get access to it in the manner described here.

HiPi Perl modules version 0.27 has been released including tested support for using a second I2C bus on Model B Revision 2 and Model A boards. The modules also install a utility command that you can use from any scripting language or the command line to enable this second I2C bus. (Install or Upgrade Instructions).

To get access to this second I2C bus you need to solder some pins or a connector to the P5 header on your Raspberry Pi.



The eight through holes for the P5 pad are next to the GPIO Pad 1 pins but are offset slightly because they are designed for a connector to be attached on the reverse side of the board. There isn't actually room for a connector on the same side as the GPIO Pad 1 pins.  However, as demonstrated elsewhere in various blog posts, it is possible to solder pins at a slight angle so that there is room for a ribbon connector on the standard GPIO Pad 1 pins and individual connectors on each of the PAD 5 pins. I found Alex Eames' article and video at RasPi TV helped me make up my mind how to approach this.

The layout table for the P5 pins is:

Wiring GPIO Name Raspberry Pi Name GPIO Wiring
-------- ------ ---------- ---- ---- ---------- ------ --------
- - 5V0 1 2 3V3 - -
17 28 GPIO_28 3 4 GPIO_29 29 18
19 30 GPIO_30 5 6 GPIO_31 31 20
- - GND 7 8 GND - -

You can see from the picture above  that I have soldered pins next to the GPIO 1 Pad rather than in the manner the P5 header was designed for, on the reverse of the board. If you do this too, remember that the pins are effectively the 'wrong way around' from left to right as shown in the picture on the left.

At the raw level, the way to enable the second i2c bus is to set the function of GPIO pins 28 and 29 to ALT0 and then activate internal pull up resistors on each pin. However, there is one slight caveat. By default and during load of the i2c kernel device driver, the Broadcom I2C0 peripheral is assigned to pins on the S5 connector of the Raspberry Pi by setting the ALT0 function on GPIO Pins 0 and 1. You may note that on Model B revision 1 boards GPIO Pins 0 and 1 were broken out on the main GPIO Header Pad 1 for use as the default i2c pins used by /dev/i2c-0. The new arrangement on Model B Revision 2 and Model A boards is to use the I2C0 peripheral to support the Raspsberry Pi Camera Module that will plug into the connector on S5 and to break out peripheral I2C1 as the default i2c bus on the GPIO Pad 1 header. To use the I2C0 peripheral on the pins 28 and 29 broken out by P5 you must first remove the existing assignment to pins 0 and 1 on S5. This is achieved by setting pins 0 and 1 to simple inputs before assigning pins 28 and 29 to ALT0. Of course this means you can have either S5 supporting a Raspberry Pi Camera or P5 supporting a second i2c bus, but not both at the same time. You can switch back and forth at any time.

The HiPi modules give you a number of ways to set up your i2c bus which conveniently wrap the necessary settings for S5, P5 and P1 where appropriate. You can set up the second I2C0 bus directly in code with:

use HiPi::BCM2835;
my $dev = HiPi::BCM2835->new;
$dev->set_I2C0(1);

Similarly you can disable the I2C0 bus and restore its operation on the S5 camera connector with:

$dev->set_I2C0(0);

If you are running as an unprivileged user or you want to make a command line call or a call for some other language you can enable the I2C0 bus using the hipi-i2c utility:

hipi-i2c e 0 1
   or to disable
hipi-i2c e 0 0

This may prove useful if you want to access the I2C0 bus using the standard kernel i2c device drivers. After the kernel module is loaded you can call "hipi-i2c e 0 1" to make the I2C0 bus available on the P5 header pins. Finally, you can also use the HiPi Control GUI application to enable and disable the I2C0 bus on the P5 header manually.

Soldering Is Easy?

It is worth making a few points about the actual soldering for any reader new to this. I have 50 year old eyes and hands and use soldering equipment that cost lest than the Raspberry Pi itself. I am a novice in it its usage. I would count myself as reasonably adept at manual tasks. Where precision is required I find I've naturally developed techniques to compensate for the declining precision of my fingertip touch and movement. So I thought I'd report on just how easy soldering actually is in general and for connecting to the P5 pad in particular.

In general, many breakout boards sold by electronics hobby suppliers come with pre-tinned pads and are simplicity itself to solder. Just wave the soldering iron vaguely in the right place and solder flows just where it is meant to. Perfect volcanoes every time. (Bizarrely although I have no prior experience of actually soldering something, I do have a pretty good idea of what a good connection should look like.)

I found soldering pins to the Raspberry Pi P5 header a different experience altogether. I'm fully aware that the cause of my problem was cheap / old soldering tips - but I reckon that is what a huge number of Raspberry Pi owners will end up using - initially at least. Given the proximity of other pin-outs and surface mounted components I found it all rather difficult to get right. However, it turns out that removing quantities of misplaced solder is not so difficult and the Pi is quite robust given any reasonable level of care with the soldering iron. I only ever achieved the 'perfect volcano' shape on pin 1 which I would guess is down to the much greater surface area of the square pin 1 pad but visual inspection under the eyeglass told me that the other seven connections were probably good enough for my purposes and a check with the multimeter confirmed that continuity was where continuity should be.

I decided that overall it is a bit pointless having a Raspberry Pi unless you are willing to take a soldering iron to it and encourage others to do the same. Be aware of what might happen when you grab the bare uncased Pi with your sweaty hand dressed in your polyester and nylon fleecy. Then grab it anyway. Earth yourself first if you're not adventurous. I can assure that the current financial austerity in place at chez Wallasey would not allow the automatic replacement of a fried Pi. But you have to do stuff if you are going to learn and that's the reason for me having a couple of Raspberry Pi's in the first place.

Raspberry Pi - concept priceless, implementation $25. Get soldering and have fun.

Thursday, 28 March 2013

Postfix - Mail Solution for RPi

I recently wrote about setting up nullmailer as an ideal solution for mailing out of a Raspberry Pi. It turns out that nullmailer has some severe limitations. Not least of which is that it continues to try to send rejected emails. Forever. Every minute ( by default ).

That's not good. Perhaps there are some configuration tricks for nullmailer that get over this problem. I decided to take a look at how easy it was to setup Postfix as a null (send only) smtp service. It turned out it is relatively simple. Once set up it is very easy to reconfigure Postfix to handle your outgoing mail in any number of ways.

I wondered if first time mail configurers might have trouble getting to grips with what's needed. So I produced a commented script that will do it for you (below).

First, install Postfix and sasl.

sudo apt-get -y update
sudo apt-get -y install libsasl2-modules postfix

You will be asked for a hostname, the type of postfix server to setup and an smtp server during the postfix package install. It does not really matter what you enter as the script will overwrite the configuration anyway but you can accept the defaults for hostname and smtp server while selecting 'Satellite Server' as the type to install.

Alter the 8 configuration variables at the top of the script to suit your requirement and then run with:

sudo perl setuppostfix.txt

As always when running as root ( sudo ) make sure you have read the script and are happy with what it does,

Downloadable settuppostfix.txt here.

If you intend to use your GMail account as an outbound smtp server, you can set up an App Password for authentication.

The script is fully commented but a brief outline of what it does:

given:

  • your hostname is raspberrypi
  • your mailername is raspberrypi.local
  • smtp server smtp.gmail.com on port 587,
  • smtp login name yourname@gmail.com with password 'mypasswd',
  • want to send root and pi mail to mymail@mydomain.com
  • want to use a 'from/replyto' address of raspiadmin@mydomain.com

writes your mailername to /etc/mailname
raspberrypi.local

writes to /etc/aliases
postmaster:    root
root:          mymail@mydomain.com
pi:            mymail@mydomain.com

writes to /etc/postfix/generic
@raspberrypi            raspiadmin@mydomain.com
@raspberrypi.local      raspiadmin@mydomain.com
@localhost.localdomain  raspiadmin@mydomain.com

@localhost              raspiadmin@mydomain.com

writes to /etc/postfix/smtp_auth
[smtp.gmail.com]:587 yourname@gmail.com:mypasswd

writes to /etc/postfix/main.cf using the template at the end of the script.

I hope it proves useful. I'm certainly pleased with the 'upgrade' myself.

-------------------------------------------------------------
#!/usr/bin/perl
use strict;
use warnings;

#----------------------------------------
# THIS SCRIPT WILL OVERWRITE ANY EXISTING
# POSTFIX CONFIGURATION
#----------------------------------------

#----------------------------------------
# This script will perform a simple setup
# of the Postfix mail agent for use as
# a send-only mailer on the Raspberry Pi
# running Raspbian Wheezy/Squeeze/Buster.
# It has been tested as a setup for using
# a Google Mail account for sending email
# and using an ISP smart smtp relay.
# Read through the script to check what it
# does and then run using sudo as a user
# with sudo permissions.
#
# sudo perl setuppostfix.txt
#----------------------------------------

#----------------------------------------
# Configuration
# Alter the 8 items below to suit
# your required configuration. The items
# are described in the following sections
#----------------------------------------

my $fromuser      = 'yourname@gmail.com';
my $adminuser     = 'yourname@gmail.com';
my @adminmaps     = qw( root pi );
my $smtpserver    = 'smtp.gmail.com';
my $smtpport      = 587;
my $loginname     = 'yourname@gmail.com';
my $loginpassword = 'yourloginpassword';
my $mailname      = 'raspberrypi.local';

#----------------------------------------
# $fromuser
#----------------------------------------
# Provide an email address to be used for
# the from and reply-to addresses in emails
# FROM local users on this raspberry Pi.
# When you send mail through your ISP's or
# your own smart smtp relay, there must be
# a valid return address where smtp servers
# between you and the final destination can
# return messages. That ought to be your
# Raspberry Pi but as it is unlikely that
# you have your Pi set up as a visible
# internet server, you must provide an email
# address to be used as the From and
# Reply-To address when local users on your
# Raspberry Pi ( e.g. root@raspberrypi or
# pi@raspberrypi ) send email. The reply
# addresses will be rewritten so that the
# $fromuser email address is used instead.
# This only applies to mail that carries
# a 'local' From address. If your programs
# specifiy a real email address in sent mail
# that won't be rewritten.
# This re-writing is implemented by the
# Postfix  smtp_generic_maps facility.
# If you are using a Google Mail account
# to send your email, it doesn't really
# matter what you put in here. The Google
# servers will re-write whatever you put
# with your Google Mail address.
# If you are using your ISP smtp smarthost
# a genuine email address is probably
# mandatory. 

#----------------------------------------
# $adminuser and @adminmaps
#----------------------------------------
# If you wish, you may send mail destined
# for local users to an external email
# address. That is mail TO local users
# originating on this Raspberry Pi.
# The $adminuser variable contains
# the email address that you want to send
# these mails to. @adminmaps is a space
# separated list of local users whose mail
# you want to forward on.
# This is implemented using the /etc/aliases
# file. For the initial setup this is kept
# to a minimal simple implementation, but
# you can edit the file at any time to
# modify the settings and then run
# sudo newaliases
# to load them into Postfix

#----------------------------------------
# $smtpserver
#----------------------------------------
# This is the the remote smtp relay or
# mail account server. The server for
# Google Mail is already in the script
# so if you are using that you can leave
# it unchanged. Put your smart smtp relay
# in here if you are using one.

#----------------------------------------
# $smtpport
#----------------------------------------
# The port that your smtp server listens
# on. If you are using Google Mail then the
# correct port, 587, is already in the script
# so you can leave that.
# If you are using a smart smtp relay then that
# also most likely listens on port 587.
# You might be using an internal service that
# still listens on port 25, but if you are
# you'll most probably know about that anyway.
#------------------------------------------
# NOTE:
# starttls port 587 Vs wrapped ssl port 465
#------------------------------------------
# Postfix doesn't support 'wrapped ssl'
# communication directly. Servers that require
# this normally listen on Port 465. It is
# possible to use Postfix with wrapped ssl
# but it is beyond the scope of this simple
# script. Google for 'smtp 465 ssl Postfix'.
# Wrapped ssl is quite an old method of
# encrypting the smtp conversation so hopefully
# few people will come across this issue.

#------------------------------------------
# $loginname & $loginpassword
#------------------------------------------
# If you are communicating with a secure
# mail server on port 587 you'll need to
# provide login credentials. For your
# Google Mail account that will be your
# Google Email address and your Google
# login password, OR an app password you
# have created for GMail.
# This will be stored in
# /etc/postfix/smtp_auth and
# /etc/postfix/smtp_auth.db so it is
# essential that these files are readable
# only by root.

#----------------------------------------
# $mailname
#----------------------------------------
# The fully qualified domain name for your
# mail server. This will get written to
# /etc/mailname.
#------------------------------------------
# SCRIPT INNARDS START HERE - You don't
# need to edit anything from here on in
# but there's nothing to stop you if you
# wish.
#------------------------------------------

my $maincf   = '/etc/postfix/main.cf';
my $smtpauth = '/etc/postfix/smtp_auth';
my $generic  = '/etc/postfix/generic';
my $aliases  = '/etc/aliases';

my $servername = $smtpserver;
$servername =~ s/[\[\]]//g;
unless( $smtpport) {
    die 'You must provide an smtp port';
}
$servername = qq([$servername]:$smtpport);

#------------------------------------------
# Make sure we are running via sudo and
# have the necessary permissions.
#------------------------------------------

die 'run this script as root using sudo' if $<;
#------------------------------------------
# Fix mailname and hostname 
#------------------------------------------
my $mailhostname = qx(hostname); chomp($mailhostname); $mailhostname =~ s/[\s\r\n]//g; system(qq(echo "$mailname" > /etc/mailname)) and die 'failed to write /etc/mailname'; #------------------------------------------ # write the main /etc/postfix/main.cf file #------------------------------------------

my $maincftemplate;

{
    my $protocols = 'ipv4';
    my $networks = '127.0.0.0/8';
    
    # check for ipv6
    my $procmods = qx(cat /proc/modules);
    die qq(failed reading /proc/modules : $?) if $?;
    if($procmods =~ /ipv6/) {
        $protocols .= ', ipv6';
        $networks .= ' [::ffff:127.0.0.0]/104 [::1]/128';
    }
    
    $maincftemplate = main_cf_template();
    $maincftemplate =~ s/REPLACEMAILNAME/$mailname/g;
    $maincftemplate =~ s/REPLACEHOSTNAME/$mailhostname/g
    $maincftemplate =~ s/REPLACESERVERNAME/$servername/g;
    $maincftemplate =~ s/REPLACEPROTOCOLS/$protocols/g;
    $maincftemplate =~ s/REPLACENETWORKS/$networks/g;
    
    open my $fh, '>', $maincf
        or die qq(failed to open $maincf : $!);
    print $fh $maincftemplate;
    close( $fh );
    chmod( 0644, $maincf );
}

#-----------------------------------------
# Write the generics file
#-----------------------------------------
if($fromuser){
    open my $fh, '>', $generic
        or die qq(failed to open $generic : $!);
        
    my($host, @discards) = split(/\./, $mailname);
    
    print $fh qq(\@$mailname    $fromuser\n);
    if($host ne $mailname) {
        print $fh qq(\@$host    $fromuser\n);
    }
    print $fh qq(\@localhost.localdomain    $fromuser\n);
    print $fh qq(\@localhost    $fromuser\n);
    close($fh);
    system(qq(postmap $generic))
       and die qq(failed to map generics : $!);
}

#-----------------------------------------
# Write the smtpauth
#-----------------------------------------
if($loginname && $loginpassword) {
    open my $fh, '>', $smtpauth
        or die qq(failed to open $smtpauth : $!);
    
    print $fh qq($servername $loginname:$loginpassword\n);
    close($fh);
    chmod(0600, $smtpauth) or
        die qq(failed to set permissions on $smtpauth : $!);
    
    system(qq(postmap $smtpauth))
       and die qq(failed to map generics : $!);
}

#-----------------------------------------
# Write the aliases
#-----------------------------------------

if( $adminuser && @adminmaps ){
    open my $fh, '>', $aliases
        or die qq(failed to open $aliases : $!);
        
    # add default post address
    print $fh qq(postmaster:    root\n);
    # add maps
    for( @adminmaps ) {
        print $fh qq($_:    $adminuser\n);
    }
    close($fh);
    system('newaliases')
        and die qq(failed calling newaliases : $!);
}

#------------------------------------------
# Restart Postfix and end
#------------------------------------------

system('/etc/init.d/postfix reload')
    and die qq(problems reloading Postfix : $!);
    
    
#------------------------------------------
# Send an email
#------------------------------------------

my $emailtext =
qq(From: root
To: root
Subject: Raspberry Mail Configuration
Content-type: text/plain

Your Raspberry Postfix is configured on $mailname
with the following configuration:

/etc/postfix/main.cf <<
$maincftemplate
);

{
    open my $fh, '|/usr/sbin/sendmail -t'
        or die 'could not open pipe to sendmail';
    print $fh $emailtext;
    close($fh);
}

print qq(Postfix configuration complete\n);

#-----------------------------------------
# Templates
#-----------------------------------------

sub main_cf_template {
    my $template = <<'MAINCFTEMPLATE'
# Basic Null ( send only ) Postfix

smtpd_banner = Raspberry Pi Mail
biff = no
append_dot_mydomain = no
readme_directory = no
myhostname = REPLACEMAILNAME
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = REPLACEHOSTNAME, REPLACEMAILNAME, localhost.localdomain, localhost
relayhost = REPLACESERVERNAME
inet_protocols = REPLACEPROTOCOLS
mynetworks = REPLACENETWORKS
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
smtp_generic_maps = hash:/etc/postfix/generic

# TLS

smtp_use_tls=yes
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/smtp_auth
tls_random_source=dev:/dev/urandom
smtp_sasl_security_options=noanonymous
smtp_tls_security_level=may

MAINCFTEMPLATE
;
    return $template;
}

1;