Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I've received quite a few pieces of great feedback from a variety of people since posting about writing my Perl/Raspberry Pi tutorial, and a lot of good has come from that feedback already.

One person who pointed out one minor mistake of mine with follow up with some other questions, asked about how to run a servo without needing a controller board. I realized that I hadn't exposed a couple of functions in the core WiringPi::API distribution that allowed a user to configure the PWM frequency, which is required as the Pi default doesn't play nice with typical servos.

The default PWM base frequency on a Pi is 19.2MHz, which is then divided by the clock signal (default: 32) and the PWM range (0-1023). So to get the default operating frequency:

# base range clck operational freq 19.2e6 / 1024 / 32 == 586Hz

To get this down to 50Hz required for a typical servo, I bumped up the range to 2000 (nice round number), and then just bounced around with the clock signal divider until I hit 50:

19.2e6 / 2000 / 192 == 50Hz

To be honest, I found the formula online, but then read through the datasheet for the Pi, and went on my way to not just copy and paste, but figure out exactly what frequency meant, what the divisors meant and then felt comfortable knowing exactly how PWM works ;)

So, for full left, the servo requires a pulse of 50Hz for ~1ms (PWM 50), centre is ~1.5ms (PWM 150) and full right is ~2.5ms (PWM 250). My servo required me to tweak these numbers a tiny bit to get the full 180 degree motion.

Anyway, to some code. I've commented the code as to what's happening and when, but an overall is that when started, the servo will go full-left, wait a sec, then swing from left-to-right, then back right-to-left until a SIGINT (CTRL-C) is caught, at which time, it puts the servo back to left position, then puts the pin back to INPUT mode so that if a different software is run after, the pin won't still be in PWM mode.

Unfortunately, at this time, we still require sudo for PWM functionality. It's being looked at. It's the *only* thing left that requires root.

use warnings; use strict; use RPi::WiringPi; use RPi::WiringPi::Constant qw(:all); die "need root!\n" if $> !=0; use constant { LEFT => 60, RIGHT => 255, CENTRE => 150, PIN => 18, DIVISOR => 192, RANGE => 2000, DELAY => 0.001, }; # set up a signal handler for CTRL-C my $run = 1; $SIG{INT} = sub { $run = 0; }; # create the Pi object my $pi = RPi::WiringPi->new; # create a signal pin, set mode to PWM output my $s = $pi->pin(PIN); $s->mode(PWM_OUT); # configure PWM to 50Hz for the servo $pi->pwm_mode(PWM_MODE_MS); $pi->pwm_clock(DIVISOR); $pi->pwm_range(RANGE); # set the servo to left max $s->pwm(LEFT); sleep 1; while ($run){ for (LEFT .. RIGHT){ # sweep all the way left to right $s->pwm($_); select(undef, undef, undef, DELAY); } sleep 1; for (reverse LEFT .. RIGHT){ # sweep all the way right to left $s->pwm($_); select(undef, undef, undef, DELAY); } sleep 1; } # set the pin back to INPUT $s->pwm(LEFT); $s->mode(INPUT);

It won't be until later today after I get some extra tests written and update a couple of other items that are lingering, but it is available on Github for now.

Note that the Pi may struggle to power the servo and it may cause a low-voltage situation, so it's best you power your 5v servo from an alternate source (I just happen to have a few powered-up Arduino's nearby all with 5v pins accessible). Also note that even though the +/- of the servo is 5v, you can safely connect the signal pin on it to the 3.3v GPIO on the Pi as on the servo, the pin is input only (ie. it doesn't feed back to the Pi).

In reply to Using a controllerless servo on the Raspberry Pi with Perl by stevieb

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

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others wandering the Monastery: (4)
    As of 2018-01-22 05:31 GMT
    Find Nodes?
      Voting Booth?
      How did you see in the new year?

      Results (231 votes). Check out past polls.