Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^9: Controlling USB on Raspberry Pi

by Bod (Curate)
on Dec 12, 2020 at 19:39 UTC ( #11125071=note: print w/replies, xml ) Need Help??


in reply to Re^8: Controlling USB on Raspberry Pi
in thread Controlling USB on Raspberry Pi

If you want to jump in and get your hands dirty with rolling your own, this is of course fine, but don't use Amazon reviews as a substitute for actual research, and expect to have to do a lot of that, research.

Oh you of little faith 😜

I have found this on GitHub which has been installed and allows the USB module to be controlled from the command line. Meanwhile, installing HiPi and RPi::WiringPi has taken 6 hours so far and is still going...lots of dependencies and some warnings about casting between types that look very C'ish to me...

Replies are listed 'Best First'.
Re^10: Controlling USB on Raspberry Pi
by afoken (Canon) on Dec 12, 2020 at 19:42 UTC
    Meanwhile, installing HiPi and RPi::WiringPi has taken 6 hours so far and is still going

    You don't need any of that for slow GPIO. Writing to files below /sys/class/gpio/ is completely sufficient. See Re: Controlling USB on Raspberry Pi and https://pinout.xyz/ for GPIO numbers.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Thanks afoken - that article was very, very useful and has moved me forward a long way. Probably far enough to complete the project.

      I am slightly stuck on the "best way" for a Perl program to interact with the underlying system. I have written a test script that works but not how I originally intended.

      #!usr/bin/perl use strict; open my $export, '>', "/sys/class/gpio/export" || die "Unable to open +export"; print $export "20"; close $export; open my $direction, '>', "/sys/class/gpio/gpio20/direction" || die "Un +able to open direction"; print $direction "out\n"; close $direction; open (my $value, '>', "/sys/class/gpio/gpio20/value") || die "Unable t +o open value"; sleep(1); print $value "0"; print "ON\n"; sleep(1); print $value "1"; print "OFF\n"; close $value;

      The relay is designed such that it switches ON when the GPIO pin is taken low.

      The relay on GPIO 20 switches on when the script starts. 1s later "ON" is written to STD and then a further 1s later, "OFF" is printed and the relay switches off. I would expect the relay to switch on at the same time as "ON" is printed - in other words 1s later than it does. Doing a bit of experimenting shows that it actually switches on not at print $value "0"; but when the direction is set to out at close $direction;. Strangely, it is necessary to set the direction even though it is already set before the script starts and remains set afterwards and the act of setting the direction switches on the relay.

      So I have looked at the source code for HiPi which uses a combination of system calls to echo and sysopen. I've also looked at RPi::WiringPi which again uses system but this time calls the RPi utility gpio and also uses `echo.

      I've been led to believe that system should not really be necessary in Perl if it is calling something like echo and I would rather implement a more Perlish solution. So some guidance would be very welcome.

      If I were to use sysopen instead of open and therefore interact with the filesystem at a lower level, is it likely that I would be able to set the direction without changing the state of the relay at the same time?

        I would expect the relay to switch on at the same time as "ON" is printed - in other words 1s later than it does. Doing a bit of experimenting shows that it actually switches on not at print $value "0"; but when the direction is set to out at close $direction;.

        The files in /sys/ are actually kernel drivers, much like in /proc/. Those file-based drivers are rather simple-minded and desigend to use by shell scripts, where each echo foo > /proc/some/magic/file ends in calling open(2), write(2), and close(2). So you should simulate that behaviour.

        At work, I had a client project where a Raspi was involved, running a daemon for a different purpose. Some more I/Os were needed, and so I added a tiny C module that implemented functions to configure and functions to set pins. Both just simulated a shell echo, i.e. called open, write, close. I/O switching was fast enough not to see a delay with the naked eye, so probably below 100 msec.

        Rewriting your code like this should help:

        #!/usr/bin/perl # untested! use strict; use warnings; use feature "say"; sub write_file { my ($fn,$content)=@_; open my $f,'>',$fn or die "Could not open $fn: $!"; say $f $content; close $f; } sub export { my $number=shift; write_file("/sys/class/gpio/export",$number); } sub direction { my ($number,$dir)=@_; write_file("/sys/class/gpio/gpio$number/direction",$dir); } sub write_value { my ($number,$level)=@_; write_file("/sys/class/gpio/gpio$number/value",$level); } sub read_file # unused { open my $f,'<',$fn or die "Could not open $fn: $!"; my $line=<$f>; close $f; chomp $line; return $line; } sub read_value # unused { my $number=shift; return read_file("/sys/class/gpio/gpio$number/value"); } # all of the functions above could move to a module export(20); direction(20,"out"); while (1) { write_value(20,0); say "on"; sleep 1; write_value(20,1); say "off"; sleep 1; }

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        " I've also looked at RPi::WiringPi which again uses system but this time calls the RPi utility gpio and also uses `echo`".

        The *only* place RPi::WiringPi shells out with system is where there is no other API call that can perform the tasks. Note that where you see system calls is only when operating the disk I/O LED and power LED, and in a couple of pieces of functionality to manually exporting and un-exporting pins. These calls are very, very rarely used in normal operation, and are literally for functionality I use to have, but removed it from public use, so realistically, they are now developer only functions.

        All GPIO functions, including interrupts and PWM are direct C calls that manipulate the hardware registers directly. This provides a vast increase in speed and performance, especially when dealing with more time sensitive operations.

        Just wanted to clear that up.

        RPi::WiringPi is a distribution that manages a couple dozen other distributions. The GPIO pin functionality is found in RPi::Pin. Almost all of the core functionality that performs tasks on the Pi itself are run through my WiringPi::API C/C++ library. The only functionality that's within the main RPi::WiringPi distribution are board-level functions, utility and helper functions, and code to load up all of the other various distributions for pins, ICs, devices etc. Have a look at the RPi:: distributions in my CPAN directory to get a bit better understanding of what I mean.

        Way too much file system work.

        use warnings; use strict; use RPi::Pin; use RPi::Const qw(:all); my $curtain_relay_pin = 5; my $pin = RPi::Pin->new($curtain_relay_pin); $pin->mode(OUTPUT); if (...) { $pin->write(LOW); } elsif ($pin->read == LOW) { $pin->write(HIGH); }

        Done. That assumes an active low relay. No need for super user access whatsoever. No touching of the file system whatsoever. Executed in fast C code that has access directly to the GPIO registers. No need for the entire RPi::WiringPi either. However, you don't get the pin security and cleanup that's provided by the encompassing distribution, but I digress.

        The RPi::Pin module provides access to all related GPIO pin functionality... pull up/down resistors, PWM, interrupts, setting of alternate pin modes etc.

        "The relay is designed such that it switches ON when the GPIO pin is taken low."

        For your information, when a device is on/enabled when the GPIO goes LOW, that's called "Active Low", so the relay is known to be an "active low relay". "Active High" is exactly the opposite.

      You don't need any of that for slow GPIO

      I wasn't paying attention it seems...
      Now to do some reading!

Re^10: Controlling USB on Raspberry Pi
by marto (Cardinal) on Dec 12, 2020 at 19:48 UTC

    This isn't a question of faith. Had you researched this, you'd have know about this before buying the kit and asking questions here, or being confused by reviews on Amazon, and telling us that a datasheet didn't show up with the device, even though that's almost never going to happen.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11125071]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (1)
As of 2022-07-06 14:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?