Page 1 of 1

Zowie, mixed languages on a pi

PostPosted: Sat Feb 13, 2016 9:37 pm
by Doug Coulter
And then, wash your hands - you'll go blind if you do this too much. As things have turned out, a lot more work has gone into python for raspberry pi than perl, or at least, readily available work that, well, works right, insofar as it's possible. I qualify that because any preemptive multitasking operating system I know of - Windows, Linux, OSX, Android, iOS - will, in effect, go off on demented errands of its own from time to time - that's what we mean by preemption. It has other things to do just now - give some other app or driver some CPU cycles for example. Anything providing actual hard real time performance under such an opsys is in some way "faking it" via hardware, as often as not some other uP that just does this one thing, or specialized hardware like a UART, an I2C interface, a PWM setup, whatever. Efforts to use direct GPIO pins on a pi for anything actually real time are kind of futile (Well there is a DMA "runs all the time" module that exists, but man does it chew bus bandwidth and ram), but it's still nice to have pins that you can turn on and off "sometime in the near future" and detect slow things like buttons and such like. Further, most of the examples for the kiddies are written in the kiddie language, python (do I make my opinion clear?).

I prefer Perl for the possible elegance when time isn't the most important thing, and C when it is. (Yes, I know you can write horrible code in any language, some make it easy to write beautiful code too - and some don't). I know perl has a rep that only old neckbeards like it...oh well, I suppose I qualify for the club. At any rate, I wanted to be able to swipe functionality out of some python libraries and examples into perl for those times when the perl modules either don't exist, or don't always work right, whatever - the ones available for the pi are a subset of those for PC's as is, and some of the "special for arm" ones frankly smell bad, and poop on the carpet.

Thus the desire arose to pull in some python stuff for my perl work, right now, mainly for fusor data aq and remote control, but also the LAN of things work. As it turns out, there is an excellent set of perl modules available (I use cpanminus a lot) for doing inlining of other languages python, java, C and so on. For the C case they'll even build your C code into a shared library and link it in to your perl program...other things I believe are just interpreted as always.

In the spirit of documenting this kind of thing for myself as well as others, here's an example - a silly one that just blinks a led - but uses the python GPIO library that is trouble-free - and python's sub-second sleep function, since TIme::HiRes isn't available for perl in ARM. This took two perl modules, one for the Inline::Python, and one to let me have multiple files at the end of a perl program. I like that as when I'm doing a GUI, I use GLADE to make a big XML design for a GUI, and rather than have it as a separate file, like to include it right inside the Perl without confusing either one. Like Barney Stringdup, I like installs that are just a file copy. KISS.

Here's my example. Anything after the __DATA__ marker is just a magic file perl has open for you to read - that's where I paste in the GUI XML when I'm done editing it. But with the Inline::Files module and the Inline::Python one, you can have more than one "internal" file, which is kind of cool. Example:
Code: Select all
#!/usr/bin/perl
use strict;
use warnings;
use Inline::Files;
use Inline Python =>  'below';

print "compile made it\n";
while (<DATA>) {print;} # test data section for non-corruption

while (1) { # test python functions
reset_on();
psleep .01;
reset_off();
sleep 1;
}
END { # perl end block - hit after ctrl-c and whatnot.
reset_off();
GPIO_cleanup();
print "we died happy\n";
}

__DATA__
Some data crap
more crap - would be gtk3 XML here

__PYTHON__
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
RESET_PIN = 17
GPIO.setup(RESET_PIN,GPIO.OUT)

def reset_on():
   GPIO.output (RESET_PIN,True)
def reset_off():
   GPIO.output(RESET_PIN,False)
def psleep(sec):
   time.sleep(sec)
def GPIO_cleanup():
   GPIO.cleanup


In the example, anything after __DATA__ and before __PYTHON__ is in an already open file (handle) called, duh, DATA for use by your program. Everything after __PYTHON__ is used by Inline::Python and wrapped so perl can use it.
Note PYTHON is all caps in that label, unlike the module name, it's a perl convention. Presumably, you can do more languages, all in the same file, should you need or want to.
For those who would like this in file form, here ya go.
pytest.tar.bz2
Yes, this actually works and blinks a led on raspi GPIO pin 17.
(611 Bytes) Downloaded 265 times


Most of the time I prefer languages where one uses a semicolon to end a statement, rather than whitespace...and one that doesn't make everything an object unless I want an object...(Get off my lawn :lol: ) I do believe that computers were meant to be my servants, not the other way around...