Well, I've finally released RPi::WiringPi. This uses the WiringPi::API wrapper that wraps the C-based wiringPi Raspberry Pi hacking software.
Anyway, I thought I'd throw something together that's kind of silly to play around with it. A couple of points: a) I know this isn't the proper way to web-scrape, it's just an example ;) b) forgive the global variables. The interrupt code in wiringPi library does not allow you to pass in any parameters, so until I submit a possible patch, globals are all I have. This was not meant to be prod code :D
The following code, infinitely looping every 60 seconds, scrapes my number of posts and XP from PerlMonks (in a *very* crude way), collects up the current time, then prints the data out onto an LCD display attached to my Pi:
p: 1293 18:15
x: 10361
Number of posts and then the time on the top line, XP on the bottom.
We introduce a button connected to a pin, when pressed, triggers an interrupt, and the interrupt handler rewrites the bottom line with the amount of XP remaining until my next PM level, instead of current XP (changes from x: 10361 to r: 1638. Every button press flips this back and forth.
Pics: before button press, and after button press.
use warnings;
use strict;
use LWP::Simple;
use RPi::WiringPi;
use RPi::WiringPi::Constant qw(:all);
# catch a sigint. This allows us to
# safely exit the while() loop and perform
# emergency LCD/pin cleanup. The main class
# catches die()
my $continue = 1;
$SIG{INT} = sub { $continue = 0; };
# initialize a Raspberry Pi object using the
# BCM GPIO pin numbering scheme
my $pi = RPi::WiringPi->new(setup => 'gpio');
# prepare and initialize the LCD
my $lcd = $pi->lcd;
# the following list of args looks daunting, but
# it's very straightforward, and the docs are
# pretty clear
my %args = (
cols => 16,
rows => 2,
bits => 4,
rs => 21,
strb => 16,
d0 => 12,
d1 => 25,
d2 => 24,
d3 => 23,
d4 => 0,
d5 => 0,
d6 => 0,
d7 => 0,
);
$lcd->init(%args);
# set up a pin with a button, and set an
# interrupt handler to do something when
# the button is pressed
my $button_pin = $pi->pin(26);
# we're going to interrupt when the pin
# goes LOW (off), so we'll pull it HIGH
# with the built-in pull up resistor.
# only when the button is pressed, will the
# pin briefly go LOW, and this triggers
# an interrupt
$button_pin->pull(PUD_UP);
# the second arg to interrupt_set() is the
# name of the perl sub I've defined below
# that I want handling the interrupt
$button_pin->interrupt_set(
EDGE_FALLING,
'button_press'
);
my $button_presses = 0;
my ($posts, $xp, $next);
while ($continue){
my (
$sec,$min,$hour,$mday,$mon,
$year,$wday,$yday,$isdst
) = localtime();
$min = "0$min" if length $min == 1;
# get my post and xp count from PM
($posts, $xp) = perlmonks();
# manually get xp needed for next level
$next = 12000 - $xp;
# set the LCD cursor to top row, first
# column, and print my num of PM posts
$lcd->position(0, 0);
$lcd->print("p: $posts");
# sub for bottom line, because the
# code needs to be called also in our
# interrupt handler. What's printed depends
# on the cumulative number of button presses
display_xp();
# on top row of the LCD at column 12,
# we print the time
$lcd->position(11, 0);
$lcd->print("$hour:$min");
print "$hour:$min posts: $posts, " .
"xp: $xp, next lvl: $next\n";
# rinse, repeat every minute
sleep 60;
}
# wipe the LCD clean
$lcd->clear;
# reset pins to default state
$pi->cleanup;
sub button_press {
# this is the interrupt handler
print "button pressed\n";
$button_presses++;
display_xp();
}
sub display_xp {
# this is the manager for the bottom LCD
# row. It'll update things even when the
# main program is sleeping in the while()
# loop
# print XP for 0 and even number of button
# presses, and print XP remaining to next level
# on odd number of presses
$lcd->position(0, 1);
if ($button_presses % 2){
$lcd->print("r: $next");
}
else {
$lcd->print("x: $xp");
}
}
sub perlmonks {
my $url = "http://perlmonks.org/?node_id=789891";
my $page = get $url;
my @content = split /\n/, $page;
my ($xp, $posts);
my $i = 0;
for (@content){
if (/Experience:/){
my $line = $i;
$line += 2;
$xp = $1 if $content[$line] =~ /(\d+)/;
}
if (/Writeups:/){
my $line = $i;
$line += 2;
$posts = $1 if $content[$line] =~ />(\d+)/;
}
$i++;
}
return ($posts, $xp);
}
Here's the code without all of the comments....
use warnings;
use strict;
use LWP::Simple;
use RPi::WiringPi;
use RPi::WiringPi::Constant qw(:all);
my $continue = 1;
$SIG{INT} = sub { $continue = 0; };
my $pi = RPi::WiringPi->new(setup => 'gpio');
my $lcd = $pi->lcd;
my %args = (
cols => 16,
rows => 2,
bits => 4,
rs => 21,
strb => 16,
d0 => 12,
d1 => 25,
d2 => 24,
d3 => 23,
d4 => 0,
d5 => 0,
d6 => 0,
d7 => 0,
);
$lcd->init(%args);
my $button_pin = $pi->pin(26);
$button_pin->pull(PUD_UP);
$button_pin->interrupt_set(
EDGE_FALLING,
'button_press'
);
my $button_presses = 0;
my ($posts, $xp, $next);
while ($continue){
my (
$sec,$min,$hour,$mday,$mon,
$year,$wday,$yday,$isdst
) = localtime();
$min = "0$min" if length $min == 1;
($posts, $xp) = perlmonks();
$next = 12000 - $xp;
$lcd->position(0, 0);
$lcd->print("p: $posts");
display_xp();
$lcd->position(11, 0);
$lcd->print("$hour:$min");
print "$hour:$min posts: $posts, " .
"xp: $xp, next lvl: $next\n";
sleep 60;
}
$lcd->clear;
$pi->cleanup;
sub button_press {
print "button pressed\n";
$button_presses++;
display_xp();
}
sub display_xp {
$lcd->position(0, 1);
if ($button_presses % 2){
$lcd->print("r: $next");
}
else {
$lcd->print("x: $xp");
}
}
sub perlmonks {
my $url = "http://perlmonks.org/?node_id=789891";
my $page = get $url;
my @content = split /\n/, $page;
my ($xp, $posts);
my $i = 0;
for (@content){
if (/Experience:/){
my $line = $i;
$line += 2;
$xp = $1 if $content[$line] =~ /(\d+)/;
}
if (/Writeups:/){
my $line = $i;
$line += 2;
$posts = $1 if $content[$line] =~ />(\d+)/;
}
$i++;
}
return ($posts, $xp);
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.