Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

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); }

In reply to Displaying my PM post count and XP on an LCD with RPi::WiringPi by stevieb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • 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.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-18 22:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found