HiPi
Perl Modules for Raspberry Pi
Version 0.91 - released 25 February 2024

HiPi::Interface::MAX7219LEDStrip

This module provides an interface to MAX7219 LED Strips.

It uses HiPi::Device::MAX7219 to drive the matrix modules.

The library creates a virtual buffer of unlimited size onto which you can write text for scrolling around matrix display.

Examples

Methods

Create a new instance of HiPi::Interface::MAX7219LEDStrip

You should specify the number of 8x8 matrices in your strip using the segments param.

You can also pass a secific device name if your strip is not connected to '/dev/spidev0.0'

use HiPi::Interface::MAX7219LEDStrip;
my $strip = HiPi::Interface::MAX7219LEDStrip->new(
    segments   => 8,
    devicename => '/dev/spidev0.0'
);

Write a string to the buffer. Returns the length, in pixels, of the written string.

  • $text: The text string to write
  • $x : Position the text along x (default 0)
  • $y : Position the text along y (default 0)

# Write a string to the buffer starting at the top left

my $len = $strip->write_string("Bilge!", 0, 0 );

Returns the length, in pixels, of the string without writing it to the buffer.

  • $text: The text string

my $len = $strip->get_string_extents( "Bilge!" );

Output the buffer to the display

A copy of the buffer will be scrolled and rotated according to settings before being drawn to the display.

$strip->show();

Clears the buffer of all settings and resets to its startup size:

  • Width = segments x 8
  • Height = 8

$strip->clear();

Set the state of a single pixel in the buffer. If the pixel falls outside the current buffer size, the buffer will be grown automatically.

  • $x: The x position of the pixel to set
  • $y: The y position of the pixel to set
  • $state: 1 or 0, == on or off ( default 1 )
$strip->set_pixel(13,5,1);

Set a whole column of the buffer. Only useful when not scrolling vertically

  • $x: The x position of the column to set
  • $columnbyte: An 8-bit integer, the 7 least significant bits correspond to each row
# set bottom 4 pixels in column 3 (index 2) to on
$strip->set_col( 2, 0b00001111 );
            
# set all pixels in column 3 (index 2) to on
$strip->set_col( 2, 0b01111111 );

Fill the entire current buffer setting all pixels on or off. Note, that unlike the 'clear' method, setting all pixels to 0 using 'fill' preserves buffer size and all other settings.

  • $state: 1 or 0, set all pixels on or off
$strip->fill ( 1 );

Set the display brightness.

  • $value: intensity setting between 0 and 15
$strip->set_intensity( 2 )

Scroll the buffer. Will scroll by 1 pixel horizontal if no arguments are supplied.

  • $x: amount to scroll in x direction
  • $y: amount to scroll in y direction
# scroll 1 pixel in x direction ( the default )
$strip->scroll();

# scroll 1 pixel in y direction
$strip->scroll( 0, 1 );

# scroll 1 pixel in both directions
$strip->scroll( 1, 1 );

Scroll the buffer horizontally by $amount

  • $amount: amount to scroll in x direction ( default 1 )
# scroll 1 pixel in x direction
$strip->scroll_horizontal( 1 );

Scroll the buffer vertically by $amount

  • $amount: amount to scroll in y direction ( default 1 )
# scroll 1 pixel in y direction
$strip->scroll_vertical( 1 );

Scroll buffer to given x, y position

  • $x: x position to scroll to
  • $y: y position to scroll to
$strip->scroll_to( 15, 12);

Set whether the display should be cleared on exit. Set this to 0 if you want to display a fixed message after your script exits. By default, the matrix strip will be cleared when your script exits.

$strip->set_clear_on_exit( 0 );

Set whether the display should be flipped left to right (mirrored) when drawn

$strip->set_mirror( 1 );

Set whether the display should be rotated 180 degrees when drawn

$strip->set_rotate180( 1 );

Returns the current width of the buffer.

my $w = $strip->width();

Returns the current height of the buffer.

my $h = $strip->height();

Examples

Advanced Scrolling Example

Advanced scrolling example which displays a message line-by-line and then skips back to the beginning

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

use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Advanced Scrolling
Advanced scrolling example which displays a message line-by-line
and then skips back to the beginning.
Press Ctrl+C to exit.
);

my $rewind = 1;
my $delay = 30;

my $line_height = $strip->pixel_height + 2;
my $offset_left = 0;

my @lines = ("Fifteen men on the dead man's chest",
         "Yo ho ho, and a bottle of rum!",
         "Drink and the devil had done for the rest",
         "Yo ho ho, and a bottle of rum!",
         "But one man of her crew alive,",
         "Yo ho ho, and a bottle of rum!",
         "What put to sea with seventy-five",
         "Yo ho ho, and a bottle of rum!");

my $numlines = scalar( @lines );

my @lengths = ( 0 ) x $numlines;


for (my $i = 0; $i < @lines; $i ++ ) {
    $lengths[$i] = $strip->write_string( $lines[$i], $offset_left, $line_height * $i );
    $offset_left += $lengths[$i];
}

my $current_line = 0;

$strip->set_intensity(1);
$strip->show;

$strip->sleep_milliseconds( 1000 );

while (1) {
    my $starttime = time;
    my $pos_x = 0;
    my $pos_y = 0;
    for ( my $current_line = 0; $current_line < $numlines; $current_line ++) {
        $strip->sleep_milliseconds( $delay * 10 );
        for (my $y = 0; $y < $lengths[$current_line]; $y ++) { 
            $strip->scroll(1,0);
            $pos_x += 1;
            $strip->sleep_milliseconds( $delay );
            $strip->show();
        }
        if ( $current_line == $numlines - 1 && $rewind ) {
            for ( my $y = 0; $y < $pos_y; $y ++ ) {
                $strip->scroll(- int($pos_x/$pos_y), - 1);
                $strip->show();
                $strip->sleep_milliseconds( $delay );
            }
            $strip->scroll_to(0,0);
            $strip->show();
            $strip->sleep_milliseconds( $delay );
            my $endtime = time;
            $starttime = time;
        } else {
            for (my $i = 0; $i < $line_height; $i++) {
                $strip->scroll(0,1);
                $pos_y += 1;
                $strip->show();
                $strip->sleep_milliseconds( $delay );
            }
        }
    }
    
}

1;
return to example list

Clock

Displays the time in hours, minutes and seconds

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

use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Clock
Displays the time in hours, minutes and seconds
Press Ctrl+C to exit.
);

my $offsetx = 0;
my $offsety = 0;

while(1) {
    $strip->clear();
    my($sec,$min,$hour) = localtime(time);
    
    $strip->write_string( sprintf('%02d:%02d:%02d', $hour, $min, $sec ), $offsetx ,$offsety );
    $strip->show;
    $strip->sleep_milliseconds( 50 );
}

1;
return to example list

Fading text

Uses the brightness control to fade between messages.

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

use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Fading Text
Uses the intensity control to fade between messages.
Press Ctrl+C to exit
);

my @strings = ("One", "Two", "Three", "Four");
my $string = 0;
my $shown = 1;
my $intensity = 0;
my $direction = 1;
while(1) {
   
    $strip->set_intensity($intensity);
    
    if( $intensity == 0 ) {
        $direction = 1;
        $strip->clear();
        $strip->write_string($strings[$string]);

        $string += 1;
        $string %=  scalar @strings;
        
        $strip->show();
    }
    
    $intensity += $direction;
    if( $intensity > 15 ) {
        $direction = -1;
        $intensity = 14;
    }
    
    $strip->sleep_milliseconds( 100 );
}

1;
return to example list

Graph

Plots random numbers scross the screen in a bar graph.

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

use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Graph
Plots random numbers scross the screen in a bar graph.
Press Ctrl+C to exit.
);

my @graph = ();
my $filled = 0;

while(1) {
    $strip->clear();
    push @graph, int(rand(7));
    
    while( @graph > 64 ) {
        shift @graph;
    }
    
    for (my $x = 0; $x < @graph; $x ++ ) {
        if ($filled ) {
            # bar graph
            $strip->set_col($x + ($strip->width- scalar @graph ), (
                0,
                0b1000000,
                0b1100000,
                0b1110000,
                0b1111000,
                0b1111100,
                0b1111110,
                0b1111111)[$graph[$x]] );
        } else {
            # plot
            $strip->set_col($x, 1 << ( 7 -  $graph[$x] ));
        }
    }

    $strip->show();
    $strip->sleep_milliseconds( 50 );
}

1;
return to example list

Sine Wave

Displays a sine wave across your LED strip.

#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes;
use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Sine Wave
Displays a sine wave across your LED strip.
Press Ctrl+C to exit.
);

my $x = 0;

while (1) {
    $strip->clear();
    my $t = Time::HiRes::time() * 10;
    for ( my $x = 0; $x < $strip->width; $x ++) {
        my $y = int((sin($t + ($x/2.5)) + 1) * 3.5);
        $strip->set_pixel($x, $y, 1);
    }
    $strip->show();
    $strip->sleep_milliseconds( 50 );
}


1;
return to example list

Thermal

Displays the temperature measured from thermal zone 0, using /sys/class/thermal/thermal_zone0/temp

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

use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Thermal
Displays the temperature measured from thermal zone 0 using
/sys/class/thermal/thermal_zone0/temp
Press Ctrl+C to exit.
);

my $delay = 1000;

while(1) {
    $strip->clear();
    my $path = '/sys/class/thermal/thermal_zone0/temp';
    my $temp_raw = qx(cat $path);
    chomp( $temp_raw );
    my $temp = $temp_raw / 1000.0;
    $strip->write_string( sprintf('%.2fc', $temp ) );
    $strip->show;
    $strip->sleep_milliseconds( $delay );
}

1;
return to example list

Vertical Text

Scrolls text messages vertically.

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

use HiPi::Interface::MAX7219LEDStrip;

my $strip = HiPi::Interface::MAX7219LEDStrip->new( segments => 8, devicename => '/dev/spidev0.0' );

print q(Vertical Text
Scrolls text messages vertically.
Press Ctrl+C to exit.
);

my @lines = ( 'One 1', 'Two 2', 'Three 3', 'Four 4', 'Five 5',  'Six 6',  'Seven 7',  'Eight 8' );

my $line_height = 8;

for(my $i = 0; $i < @lines; $i ++ ) {
    $strip->write_string( $lines[$i], 0, $i * $line_height);
}

$strip->show;

while (1) {
    $strip->sleep_milliseconds( 1000 );
    my $iter = 0;
    while( $iter < $line_height ) {
        $iter++;
        $strip->scroll_vertical();
        $strip->show();
        $strip->sleep_milliseconds( 50 );
    }
}


1;
return to example list