GPIO setting a value

159 views
Skip to first unread message

Bill Waggoner

unread,
Apr 24, 2013, 2:46:31 PM4/24/13
to HiPi Perl
I'm having trouble in the simplest way. I've written a simple program
because my main program wasn't doing what I thought it ought to. Ypu
can see the test program at: https://github.com/ctgreybeard/RaspberryPi/blob/Turnout1/play1/Blink1.pl

I'm using HiPi version 0.29

What I get for results is:

--> perl Blink1.pl
Using GPIO pin: 24
Current status is: DEV_GPIO_PIN_STATUS_NONE
Exporting...
Current status is: DEV_GPIO_PIN_STATUS_EXPORTED
Got the pin ...
Current mode is: RPI_PINMODE_OUTP
Setting to OUTP
Current mode is: RPI_PINMODE_OUTP
Current active_low is: 0
Setting active_low: off
Reading value...
Current value=1, setting to 0
Reading value...
Current value=1, setting to 0
Reading value...
Current value=1, setting to 0
Reading value...
Current value=1, setting to 0
Unexporting
Current status is: DEV_GPIO_PIN_STATUS_NONE


I don't understand why it isn't setting the value ...

Bill Waggoner

unread,
Apr 24, 2013, 4:08:36 PM4/24/13
to HiPi Perl
I think I found another problem but I don't think it's related to
this ...

HiPi""Device::GPIO::Pin _do_setvalue routine does not return the
current value that existed before setting the new value. Although
that doesn't affect the results above, the HiPi::Pin document says it
should.

Bill Waggoner

unread,
Apr 24, 2013, 4:52:51 PM4/24/13
to HiPi Perl
Got it! write does not work right.

There are probably some other changes, like returning the current
value, but here's a quick patch:

--- /home/pi/HiPi/hipi-latest/lib/HiPi/Device/GPIO/Pin.pm 2013-04-23
21:58:34.000000000 -0400
+++ /usr/local/lib/perl/5.14.2/HiPi/Device/GPIO/Pin.pm 2013-04-24
16:49:57.416860647 -0400
@@ -55,7 +55,7 @@

sub _do_setvalue {
my ($self, $newval) = @_;
- write($self->valfh, $newval);
+ $self->valfh->write($newval);
}

sub _do_getmode {
@@ -70,9 +70,9 @@
sub _do_setmode {
my ($self, $newdir) = @_;
if( ($newdir == RPI_PINMODE_OUTP) || ($newdir eq 'out') ) {
- write($self->dirfh, 'out');
+ $self->valfh->write($self->dirfh, 'out');
} else {
- write($self->dirfh, 'in');
+ $self->valfh->write($self->dirfh, 'in');
}
return $newdir;
}

Mark Dootson

unread,
Apr 24, 2013, 4:58:24 PM4/24/13
to hipi...@googlegroups.com
Bill,

I've inflicted a none working version on you?

Not sure how.

But - indeed write does not work.
I replaced it with syswrite - I thought for the 0.29 upload?

The issue is that write is buffered - syswrite is not.
Using the IO::File method $fh->write is also not buffered.

Anyhow, I've gone with syswrite / sysread etc throughout the code.
I have some vague recollection of needing to use sysseek / sysread in
connection with polling.

Since picking up your post a short while ago, I've been fixing the
return values too.

I'll be uploaded a fix shortly - I'm just in the process of testing it
against a 'clean' Wheezy.

Cheers

Mark

Bill Waggoner

unread,
Apr 24, 2013, 4:59:59 PM4/24/13
to HiPi Perl
Oops. Not quite. And there are still some lingering issues. The
basic patch should be:

--- /home/pi/HiPi/hipi-latest/lib/HiPi/Device/GPIO/Pin.pm 2013-04-23
21:58:34.000000000 -0400
+++ /usr/local/lib/perl/5.14.2/HiPi/Device/GPIO/Pin.pm 2013-04-24
16:57:15.595645467 -0400
@@ -55,7 +55,7 @@

sub _do_setvalue {
my ($self, $newval) = @_;
- write($self->valfh, $newval);
+ $self->valfh->write($newval);
}

sub _do_getmode {
@@ -70,9 +70,9 @@
sub _do_setmode {
my ($self, $newdir) = @_;
if( ($newdir == RPI_PINMODE_OUTP) || ($newdir eq 'out') ) {
- write($self->dirfh, 'out');
+ $self->valfh->write('out');
} else {
- write($self->dirfh, 'in');
+ $self->valfh->write('in');
}
return $newdir;
}

Mark Dootson

unread,
Apr 24, 2013, 5:08:33 PM4/24/13
to hipi...@googlegroups.com, Bill Waggoner
Bill,

V 0.30 now uploaded with fixes.

hipi-upgrade

should get these issues fixed.

Note that you can always check the basic operation of the modules by
loading the control GUI

gksudo hipi-control-gui

In that you can open the GPIO device tab and toggle the various
available options for pins. If the code is working changes should
appear as expected.

Note I'll have to fix the documentation on the methods

$pin->value
$pin->mode

etc.

They should return a value ( and now they in fact do ) but this will
always be the value you have just set, if you pass a new value.

Cheers

Mark

Bill Waggoner

unread,
Apr 24, 2013, 5:23:01 PM4/24/13
to HiPi Perl
Mark, I think (according to the Perl docs I read) that syswrite will
NOT work correctly. syswrite is unbuffered, read is buffered. You
need to use the IO::Handle routines exclusively.

Here's a patch that works for me and returns the prior value (or
should, I wanted to post this before I had fully tested ...) It uses
the IO::Handle routines for all the file IO and works for my limited
testing.

Bill

--- a/hipi-latest/lib/HiPi/Device/GPIO/Pin.pm
+++ b/hipi-latest/lib/HiPi/Device/GPIO/Pin.pm
@@ -46,23 +46,25 @@ sub _open {

sub _do_getvalue {
my $self = shift;
- seek($self->valfh,0,0);
+ $self->valfh->seek(0,0);
my $result;
- read($self->valfh, $result, 16);
+ $self->valfh->read($result, 16);
chomp($result);
return $result;
}

sub _do_setvalue {
my ($self, $newval) = @_;
- write($self->valfh, $newval);
+ my $oldval = _do_getvalue($self);
+ $self->valfh->write($newval);
+ return $oldval;
}

sub _do_getmode {
my $self = shift;
- seek($self->dirfh,0,0);
+ $self->dirfh->seek(0,0);
my $result;
- read($self->dirfh, $result, 16);
+ $self->dirfh->read($result, 16);
chomp($result);
return ( $result eq 'out' ) ? RPI_PINMODE_OUTP :
RPI_PINMODE_INPT;
}
@@ -70,16 +72,16 @@ sub _do_getmode {
sub _do_setmode {
my ($self, $newdir) = @_;
if( ($newdir == RPI_PINMODE_OUTP) || ($newdir eq 'out') ) {
- write($self->dirfh, 'out');
+ $self->dirfh->write('out');
} else {
- write($self->dirfh, 'in');
+ $self->dirfh->write('in');
}
return $newdir;
}

sub _reset_value_handle {
my $self = shift;
- close($self->valfh);
+ $self->valfh->close();
my $filepath = $self->pinroot . '/value';
my $newfh = IO::File->new($filepath, O_RDWR, 0) or croak
qq(failed to open $filepath : $!);
$self->valfh($newfh);
@@ -168,8 +170,8 @@ sub active_low {

sub DESTROY {
my $self = shift;
- close($self->valfh);
- close($self->dirfh);
+ $self->valfh->close();
+ $self->dirfh->close();
}

1;

Bill Waggoner

unread,
Apr 24, 2013, 5:55:46 PM4/24/13
to HiPi Perl
Well, something's still not right and I don't know if it's my program
or elsewhere. It does seem to be changing the output but not
consistently for me.
Reply all
Reply to author
Forward
0 new messages