Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
BeagleBone: Creative Projects for Hobbyists

You're reading from   BeagleBone: Creative Projects for Hobbyists Build amazing BeagleBone projects and maximize your skills with projects that walk, talk, and fly!

Arrow left icon
Product type Course
Published in Jul 2017
Publisher Packt
ISBN-13 9781788395656
Length 1020 pages
Edition 1st Edition
Languages
Concepts
Arrow right icon
Authors (3):
Arrow left icon
Rodolfo Giometti Rodolfo Giometti
Author Profile Icon Rodolfo Giometti
Rodolfo Giometti
Charles A. Hamilton Charles A. Hamilton
Author Profile Icon Charles A. Hamilton
Charles A. Hamilton
Richard Grimmett Richard Grimmett
Author Profile Icon Richard Grimmett
Richard Grimmett
Arrow right icon
View More author details
Toc

Chapter 3. Physical Computing Recipes Using JavaScript, the BoneScript Library, and Python

Now that you're armed to the…er, fingertips with your Linux commands and can happily control your BeagleBone Black remotely like a pro, it's time to get physical with the board. So, to begin with our exercises in physical computing, we're whipping up some essential recipes on the following topics:

  • Controlling external LEDs
  • Using buttons – button press function
  • Using analog sensors
  • Variable resistance sensor – photocell
  • Using motors

Our programming language of choice will principally be JavaScript in tandem with BoneScript, which is a Node.js and browser-side library. We will also include or reference a few Python script analogues to broaden our skills with the hardware.

Introduction

The basics of physical computing typically require understanding and shaping input and output on your hardware. We will begin with taking a look at the old chestnut, manipulating LEDs, an experience you're likely to have some familiarity with if you have read the last chapter, or if you're an Arduino or Raspberry Pi user. Next, we'll play a bit with buttons because who doesn't like to push a button? Then, it gets more interesting as we add sensors to the mix. After this, we'll give you some basic recipes for locomotion that use some motors. Finally, we'll wind it up with the ingredients and steps for setting up a connection between your BBB and an Arduino board.

We'll march across the BBB, draft the large army of pins that the board has at our disposal, the GPIOs, ADCs, PWMs, and UARTs, a phalanx that makes the Raspberry Pi look feeble. All of these acronyms may seem impenetrable; however, throughout the course of this book we will steadily learn something about all of them.

Introduction

Header pin array with their various functions designated by pin number

Although we will have a dash of Python code here and there, the recipes in this chapter will primarily consist of BoneScript/JavaScript ingredients and its powerful potions for physical computing. For an extensive documentation of the BoneScript Library and its up-to-date reference, refer to http://beagleboard.org/Support/BoneScript.

Before we head off to the recipe land (and since this chapter is actually about how to make some basic electrical circuits), we need to take a quick look at some of the foundational principles of electricity and current. Knowing a few things about them will prevent you from accidentally frying your board.

The essentials of electronics

How much power does an LED need? What would happen if I ran a 5V circuit with a 3V power supply? Will my 12V battery pack keep the robot going long enough to get the data I need? Also, most importantly, can I attach the Spottiswoode Great Induction Coil Cape to pins 9_11 and 37 on the BeagleBone Black?

Tip

The earlier versions of BeagleBones were larger than the Black version. However, you should never connect an old or new BeagleBone Black to a Spottiswoode Great Induction Coil.

The essentials of electronics

Source: William Spottiswoode and induction coil from Wikimedia Commons / The London, Edinburgh, and Dublin Philosophical Magazine, 1877. Image composite by Charles Hamilton.

To discover the answer to these and other (potentially) board burning questions, you need to know a bit about the three pillars of electronics wisdom and wiring: current, voltage, and resistance:

  • Current: The continuous flow of electrons, or the rate of "charge" through a given point in a circuit.
  • Voltage (potential difference): This indicates the size of the electrical potential in your circuit that allows electrons to flow. Specifically, voltage is the difference in the electrical potential between two given points that allows electrons to move. This is why it is known as the potential difference.
  • Resistance: This denotes that electrons get hung up from Point-A to Point-B, that is, there is friction that can impede their free flow of current, which we call resistance.

How do all these things relate to one another when it comes to circuitry?

The easy answer is Ohm's law. Much ink has been spilled in explaining this foundational principle of electricity; we will only say a few words and quickly throw a formula at you, the only one you will see in this book: V = I x R.

Knowing how to use this basic formula will help you determine the right combination of current and resistance to apply when you wire up your BBB circuits. Here is the breakdown of the formula:

  • V: This specifies voltage (expressed in volts)
  • I: This indicates current (expressed in amps)
  • R: This denotes resistance (expressed in ohms and commonly seen as Ω)

As long as we know any two of the three variables, we will use Ohm's law to calculate the third and remaining number. Typically, you will need to use Ohm's law to determine the right resistor to use when you wire up a circuit.

There are numerous and exhaustive free examples available online that show you how to use Ohm's law for your projects. Here are a few excellent ones:

Note

If you take nothing else from this section, at least heed this one warning: be very careful how you power your BeagleBone Black; otherwise, you may damage it.

Header pins and pinmuxing

The magical thing about microcomputers is that they give you the ability to interact with the physical world. This interaction is essentially possible via the GPIOs and other pins. These pins are intended to generate different voltage levels and pulses. This is the essential purpose of programming a GPIO: you will tell the board to generate a specific level of voltage or pulse on a specific pin.

Perusing our complement of I/O pins, we can count two rows of 46 pin slots on the two expansion headers. If you look closely, you will see that one block is labeled P8 and the other one P9. All the references to a specific pin begin with this block number first, followed by a number between 1 and 46. Therefore, the example pins look similar to P8_2, P8_15, P8_24, P9_2, P9_15, and so on.

But what do you do with all these pins? Not all of them are actually available. Some have been drafted for other purposes. According to the BBB reference manual, the board has the following breakdown for pin purposes and availability:

# of Pins

Purpose of pins

65

General purpose and digital IO pins

8

PWMs

4

Timers

7

1.8V analog inputs

4.5

UARTs

2

I2C

2

SPI

2

5V

2

3.3V

Note

The BBB also includes another six male pins to accommodate a serial debug cable on the main board (not the headers).

To understand the nitty-gritty of the pins that may be available, you can refer to the BeagleBone Black System Reference Manual at http://elinux.org/Beagleboard:BeagleBoneBlack. Page 84 describes the pins on the P8 header, and page 86 describes the pins on the P9 header. There are also numerous reference guides online that help you understand the BBB's pin layouts. Skip to the There's more… section for additional sources. In the meantime, the following image a snapshot view of the board's entire pinmux. You can also refer back to the pin mapping diagram at the beginning of this chapter.

Header pins and pinmuxing

The process of pinmuxing

A common frustration among new BBB users is that the pins do not always respond as expected. This is because, by default, some header pins are assigned to specific tasks, such as the HDMI output, some are used for multiple purposes, and many of its functions are only available after some tweaking. For example, pin 21 on the P9 header wants to be a GPIO at some time, whereas at other times, it wants to be a PWM, a UART, an I2C, or a SPI pin.

So, how do you get around this pin schizophrenia? Well, you have to reconfigure it for this purpose, a process known as pin multiplexing or pinmux. Pinmuxing is fairly straightforward and can be easily handled from the command line. We will encounter this technique later in this and subsequent chapters.

Although the BBB's sophisticated pin design can accept different types of signals, in this chapter, we will mainly take a look at the two types that are commonly used in physical computing:

  • Pulse width modulation (PWM)
  • Analog to digital converter (ADC)

Within our toolset is another software application that electronics and hardware makers rely heavily on: Fritzing. You may already be familiar with it, but if not, Fritzing is an extremely, handy open source graphical tool for creating diagrams of breadboards, schematics, and PCB layouts without the need for traditional engineering schematics.

Note

Before wiring up your breadboard, it's a good idea to reset the BBB each time you perform a new recipe by powering it down. This ensures that the pins are reset to their input state. Otherwise, if the pin is being used as an input in a new recipe that was previously used as an output, you may damage your BBB.

There's more…

Here are some of the sources and links to the BeagleBone Black's pin layouts:

Controlling external LEDs

In the last chapter, we looked at a quick blink recipe on how to control our on board LEDs. Now, the objective is to have an external LED on a breadboard blink. First, we will take a look at the circuit symbol of a basic LED so that we can recognize its proper usage, as shown in the following diagram:

Controlling external LEDs

The typical symbol for a light-emitting diode (LED)

In the following image, you will see what a real-life LED actually looks like. Not so straightforward as looking at the symbol, right?

Controlling external LEDs

Note

With LEDs, polarity matters to have a working circuit. Pay attention to the fact that the anode is the longer end, whereas the cathode is the shorter end. Although mixing them up will not cause any damage, the circuit will not work.

Getting ready

You'll need the following items to supplement your now happily perking BBB:

  • LED: Just a plain vanilla, inexpensive LED is fine; this is the type you'll find for pennies at your local hobby store or online. You may already have a bunch in your kit.
  • Resistor: Anything from 700 (700Ω) to 1k is fine. We will use a 700Ω version here (violet/black/brown/gold bands).
  • 2x jumper wires: These are easy to connect to the breadboard.
  • Breadboard.

How to do it...

Now, let's begin with the following steps:

  1. From our fritzing tool, here's the diagram we made for our wiring:
    How to do it...
  2. Now, wire up your breadboard using the following steps:
    1. First, put the Ground wire into GND (P8_2) on the BBB.
    2. Then, insert the other wire to the P8_15 pin on the BBB.
    3. On the breadboard, put the LED's shorter end—the cathode (-) pin—into the GND rail and the longer end—the anode (+) pin—into the sixth slot of the breadboard.
    4. Now, insert your resistor and make sure that the top end is aligned in the slot with the GPIO wire and the bottom end is aligned with the LED's anode.
  3. Open up Cloud9 IDE at http://192.168.7.2:3000 and create a new file called blink_LED.js.
  4. Then, copy and paste the following code into the open IDE window:
    // Setup
    var b = require('bonescript'); // Call library
    var LED = "P8_15"; // Pin choice
    var state = 0; // LED state
    b.pinMode(LED, 'out'); // Pin function 
    
    setInterval(blink, 500);
    function blink() {
      state = !state;
      b.digitalWrite(LED, state);
    
  5. Before running the code, let's take a closer look at the parts. First, as noted in the prior chapter, you need to invoke the BoneScript library so you have access to all its functions:
    // Setup
    var b = require('bonescript');
    

    Please keep in mind that anything after the // are comments, and isn't functional code.

  6. Now, select the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin. Then, make the change on your board as well. Refer to the pin layout reference diagram at the beginning of this section for more background on the pin outs, as shown in the following code:
    var LED = "P8_15";
  7. This line defines the variable state of our pin, which in this case has a LED connected to it. Naturally, the state will vary as either on or off, where 0 is equal to off and 1 is equal to on:
    var state = 0;
    
  8. Following this, as the pin has no preassigned value, here, we have to use pinMode to tell the pin (P8_15) what type of pin it's supposed to be, either an INPUT (this would be used with a button) or an OUTPUT. In this case, as we will control a LED, our GPIO will be an output, as follows:
    b.pinMode(LED, b.OUTPUT);

    You can also write it this way:

    b.pinMode(LED, 'out');
  9. From the setup code, we then shift to instructing the LED to evoke the blink function (which we'll define in the next section of code). Then, flash on/off according to whatever interval we specify (in this case, every 500 milliseconds). This line is analogous to the commonly seen loop function in Arduino scripts. However, JavaScript and the event-driven Node.js environment greatly simplifies the code, as follows:
    setInterval(blink, 500);
  10. Finally, we will define the blink function. The ! before the state value inverts the value, and as the LED begins with a 0 (off) state (this isn't the same as 0 changing to 1 (on)). The last line (b.digitalWrite)—which happens to be Arduino-friendly syntax—establishes an output statement for the LED and its on/off state, as shown in the following code:
    function blink() {
      state = !state;
      b.digitalWrite(LED, state);
    }
  11. Finally, let's see what the script does. Click Run in the Cloud9 IDE. Your LED should now be blinking merrily at 500 millisecond increments.

    Note

    You can find more documentation on the BoneScript library functions at http://beagleboard.org/support/bonescript.

Writing an alternative script with Python

Starting from step 3, here's the Python version of the recipe that uses the Adafruit library:

  1. In the Cloud9 IDE terminal window, open a new file window in the editor and name it blink_LED.py.
  2. Copy and paste the following code to the window:
    import Adafruit_BBIO.GPIO as GPIO
    import time
    
    GPIO.setup ("P8_15", GPIO.OUT)
    
    while True:
            GPIO.output("P8_15", GPIO.HIGH)
            time.sleep(1.0)
            GPIO.output("P8_15", GPIO.LOW)
            time.sleep(1.0)
    
  3. Now, save the script.
  4. Click Run in the Cloud9 IDE. Your LED should begin blinking.

There's more…

You can find more support in these tutorials:

Getting ready

You'll need the following items to supplement your now happily perking BBB:

  • LED: Just a plain vanilla, inexpensive LED is fine; this is the type you'll find for pennies at your local hobby store or online. You may already have a bunch in your kit.
  • Resistor: Anything from 700 (700Ω) to 1k is fine. We will use a 700Ω version here (violet/black/brown/gold bands).
  • 2x jumper wires: These are easy to connect to the breadboard.
  • Breadboard.

How to do it...

Now, let's begin with the following steps:

  1. From our fritzing tool, here's the diagram we made for our wiring:
    How to do it...
  2. Now, wire up your breadboard using the following steps:
    1. First, put the Ground wire into GND (P8_2) on the BBB.
    2. Then, insert the other wire to the P8_15 pin on the BBB.
    3. On the breadboard, put the LED's shorter end—the cathode (-) pin—into the GND rail and the longer end—the anode (+) pin—into the sixth slot of the breadboard.
    4. Now, insert your resistor and make sure that the top end is aligned in the slot with the GPIO wire and the bottom end is aligned with the LED's anode.
  3. Open up Cloud9 IDE at http://192.168.7.2:3000 and create a new file called blink_LED.js.
  4. Then, copy and paste the following code into the open IDE window:
    // Setup
    var b = require('bonescript'); // Call library
    var LED = "P8_15"; // Pin choice
    var state = 0; // LED state
    b.pinMode(LED, 'out'); // Pin function 
    
    setInterval(blink, 500);
    function blink() {
      state = !state;
      b.digitalWrite(LED, state);
    
  5. Before running the code, let's take a closer look at the parts. First, as noted in the prior chapter, you need to invoke the BoneScript library so you have access to all its functions:
    // Setup
    var b = require('bonescript');
    

    Please keep in mind that anything after the // are comments, and isn't functional code.

  6. Now, select the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin. Then, make the change on your board as well. Refer to the pin layout reference diagram at the beginning of this section for more background on the pin outs, as shown in the following code:
    var LED = "P8_15";
  7. This line defines the variable state of our pin, which in this case has a LED connected to it. Naturally, the state will vary as either on or off, where 0 is equal to off and 1 is equal to on:
    var state = 0;
    
  8. Following this, as the pin has no preassigned value, here, we have to use pinMode to tell the pin (P8_15) what type of pin it's supposed to be, either an INPUT (this would be used with a button) or an OUTPUT. In this case, as we will control a LED, our GPIO will be an output, as follows:
    b.pinMode(LED, b.OUTPUT);

    You can also write it this way:

    b.pinMode(LED, 'out');
  9. From the setup code, we then shift to instructing the LED to evoke the blink function (which we'll define in the next section of code). Then, flash on/off according to whatever interval we specify (in this case, every 500 milliseconds). This line is analogous to the commonly seen loop function in Arduino scripts. However, JavaScript and the event-driven Node.js environment greatly simplifies the code, as follows:
    setInterval(blink, 500);
  10. Finally, we will define the blink function. The ! before the state value inverts the value, and as the LED begins with a 0 (off) state (this isn't the same as 0 changing to 1 (on)). The last line (b.digitalWrite)—which happens to be Arduino-friendly syntax—establishes an output statement for the LED and its on/off state, as shown in the following code:
    function blink() {
      state = !state;
      b.digitalWrite(LED, state);
    }
  11. Finally, let's see what the script does. Click Run in the Cloud9 IDE. Your LED should now be blinking merrily at 500 millisecond increments.

    Note

    You can find more documentation on the BoneScript library functions at http://beagleboard.org/support/bonescript.

Writing an alternative script with Python

Starting from step 3, here's the Python version of the recipe that uses the Adafruit library:

  1. In the Cloud9 IDE terminal window, open a new file window in the editor and name it blink_LED.py.
  2. Copy and paste the following code to the window:
    import Adafruit_BBIO.GPIO as GPIO
    import time
    
    GPIO.setup ("P8_15", GPIO.OUT)
    
    while True:
            GPIO.output("P8_15", GPIO.HIGH)
            time.sleep(1.0)
            GPIO.output("P8_15", GPIO.LOW)
            time.sleep(1.0)
    
  3. Now, save the script.
  4. Click Run in the Cloud9 IDE. Your LED should begin blinking.

There's more…

You can find more support in these tutorials:

How to do it...

Now, let's begin with the following steps:

  1. From our fritzing tool, here's the diagram we made for our wiring:
    How to do it...
  2. Now, wire up your breadboard using the following steps:
    1. First, put the Ground wire into GND (P8_2) on the BBB.
    2. Then, insert the other wire to the P8_15 pin on the BBB.
    3. On the breadboard, put the LED's shorter end—the cathode (-) pin—into the GND rail and the longer end—the anode (+) pin—into the sixth slot of the breadboard.
    4. Now, insert your resistor and make sure that the top end is aligned in the slot with the GPIO wire and the bottom end is aligned with the LED's anode.
  3. Open up Cloud9 IDE at http://192.168.7.2:3000 and create a new file called blink_LED.js.
  4. Then, copy and paste the following code into the open IDE window:
    // Setup
    var b = require('bonescript'); // Call library
    var LED = "P8_15"; // Pin choice
    var state = 0; // LED state
    b.pinMode(LED, 'out'); // Pin function 
    
    setInterval(blink, 500);
    function blink() {
      state = !state;
      b.digitalWrite(LED, state);
    
  5. Before running the code, let's take a closer look at the parts. First, as noted in the prior chapter, you need to invoke the BoneScript library so you have access to all its functions:
    // Setup
    var b = require('bonescript');
    

    Please keep in mind that anything after the // are comments, and isn't functional code.

  6. Now, select the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin. Then, make the change on your board as well. Refer to the pin layout reference diagram at the beginning of this section for more background on the pin outs, as shown in the following code:
    var LED = "P8_15";
  7. This line defines the variable state of our pin, which in this case has a LED connected to it. Naturally, the state will vary as either on or off, where 0 is equal to off and 1 is equal to on:
    var state = 0;
    
  8. Following this, as the pin has no preassigned value, here, we have to use pinMode to tell the pin (P8_15) what type of pin it's supposed to be, either an INPUT (this would be used with a button) or an OUTPUT. In this case, as we will control a LED, our GPIO will be an output, as follows:
    b.pinMode(LED, b.OUTPUT);

    You can also write it this way:

    b.pinMode(LED, 'out');
  9. From the setup code, we then shift to instructing the LED to evoke the blink function (which we'll define in the next section of code). Then, flash on/off according to whatever interval we specify (in this case, every 500 milliseconds). This line is analogous to the commonly seen loop function in Arduino scripts. However, JavaScript and the event-driven Node.js environment greatly simplifies the code, as follows:
    setInterval(blink, 500);
  10. Finally, we will define the blink function. The ! before the state value inverts the value, and as the LED begins with a 0 (off) state (this isn't the same as 0 changing to 1 (on)). The last line (b.digitalWrite)—which happens to be Arduino-friendly syntax—establishes an output statement for the LED and its on/off state, as shown in the following code:
    function blink() {
      state = !state;
      b.digitalWrite(LED, state);
    }
  11. Finally, let's see what the script does. Click Run in the Cloud9 IDE. Your LED should now be blinking merrily at 500 millisecond increments.

    Note

    You can find more documentation on the BoneScript library functions at http://beagleboard.org/support/bonescript.

Writing an alternative script with Python

Starting from step 3, here's the Python version of the recipe that uses the Adafruit library:

  1. In the Cloud9 IDE terminal window, open a new file window in the editor and name it blink_LED.py.
  2. Copy and paste the following code to the window:
    import Adafruit_BBIO.GPIO as GPIO
    import time
    
    GPIO.setup ("P8_15", GPIO.OUT)
    
    while True:
            GPIO.output("P8_15", GPIO.HIGH)
            time.sleep(1.0)
            GPIO.output("P8_15", GPIO.LOW)
            time.sleep(1.0)
    
  3. Now, save the script.
  4. Click Run in the Cloud9 IDE. Your LED should begin blinking.

There's more…

You can find more support in these tutorials:

Writing an alternative script with Python

Starting from step 3, here's the Python version of the recipe that uses the Adafruit library:

  1. In the Cloud9 IDE terminal window, open a new file window in the editor and name it blink_LED.py.
  2. Copy and paste the following code to the window:
    import Adafruit_BBIO.GPIO as GPIO
    import time
    
    GPIO.setup ("P8_15", GPIO.OUT)
    
    while True:
            GPIO.output("P8_15", GPIO.HIGH)
            time.sleep(1.0)
            GPIO.output("P8_15", GPIO.LOW)
            time.sleep(1.0)
    
  3. Now, save the script.
  4. Click Run in the Cloud9 IDE. Your LED should begin blinking.
There's more…

You can find more support in these tutorials:

There's more…

You can find more support in these tutorials:

Using buttons – button press function

Buttons come in all shapes and sizes. Some are quiet. Some are noisy. Some are expensive. Some cost pennies. We'll not only use the cheap and peppy, penny variety, but also show an example with a more interesting, whizzy personality and make it do something more than just turn the switch on and off.

Pull-up, pull-down, and floating

Frequently when wiring up circuits, you will hear references to pull-up, pull-down, and floating configurations. When your design is a pull-up circuit, this means that the resistor holds the positive or supply voltage (VCC) until you push the button pulling it up to ground. This is the most common scenario, and one you encounter when you design a circuit with a button press to activate something.

In the pull-down version of a circuit, the resistor in the circuit remains at ground unless you push (or pull down) the button, causing the circuit to switch from ground to positive or supply voltage (VCC).

Floating means the circuit is neither tied to ground or a particular voltage. This can create a situation where a pin may accumulate some kind of charge on it, thus throwing off incorrect values. You can create a more reliable circuit by writing code to correct for these potential false readings.

The purpose of this recipe is to read the state of a button press and have it turn an LED on and off. When the button is not pressed, the state of the input pin will be a 1 or high due to the resistor pulling the pin up. When the button is pressed, the input pin will be grounded low and have the value as 0.

Getting ready

You'll need the following items for this recipe:

  • 1 x LED: This is the same one you used in the previous section.
  • 1 x pushbutton: This is a simple, one button, four-pronged tactile switch. By default, the button pins are open (disconnected) and momentarily closed (connected) when the button is pressed.
  • Resistors: 2x 700 (700Ω) to 1k will be fine. We will use the 700Ω here (violet/black/brown/gold bands).
  • 5 x jumper wires: This is easy to connect to the breadboard.
  • Breadboard.

How to do it...

  1. Wire your board and breadboard in the following manner:
    1. Connect the GND wire to GND at P9_2 on the BBB and the other end to GND in the first slot at the top of the second row on the breadboard.
    2. Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
    3. The button will use the next wire. Connect a wire to the pin on the P9_15 BBB and to the first slot in the same row in the upper-left corner of the button on the breadboard.
    4. Take another wire and connect one end to P8_11 on BBB and the other end to row 2 and column 1 on the breadboard.
    5. The last wire serves as Ground for the button. Connect one end of this wire to the GND rail and the other end next to the button's GND leg.
    6. On the breadboard, connect the LED's cathode pin (the shorter end) to the GND rail and the anode or the positive lead (the longer end) into the sixth row of the breadboard
    7. Insert one resistor to regulate the current to the LED and the other to regulate the flow through the button, as shown in the following image:
    How to do it...
  2. Now, open your Cloud9 IDE at http://192.168.7.2:3000 and create a new file called button-led.js.
  3. Then, use the following code to turn the LED on and off with a push button. Copy and paste it into the open IDE window:
    // Setup
    var b = require('bonescript'); //Read library
    var LED = "P8_11"; //Pin where LED is connected
    var BUTTON = "P9_15";
    
    b.pinMode(LED, b.OUTPUT);
    b.pinMode(BUTTON, b.INPUT);
    
    setInterval(readBUTTON, 10);
    
    function readBUTTON() {
        b.digitalRead(BUTTON, writeLED);
    }
    
    function writeLED(x) {
        b.digitalWrite(LED, !x.value);
    }    
    • Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
      // Setup
      var b = require('bonescript'); //Read library
    • Now, choose the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin (see the pin layout reference diagram at the end of this section for more background on the GPIOs):
      var LED = "P8_11"; //Pin where LED is connected
    • Then, we will set the pin number for the button, as follows:
      var BUTTON = "P9_15";
    • Now, we will tell the previously specified pins to function in an OUTPUT mode for the LED and in an INPUT mode for the button, as shown in the following code:
      b.pinMode(LED, b.OUTPUT);
      b.pinMode(BUTTON, b.INPUT);

      You can also write it this way:

      b.pinMode(LED, "out");
      b.pinMode(BUTTON, "in");
    • Now, we need to check the status of the button at specific intervals, in this case, every 10 minutes, as shown in the following code:
      setInterval(readBUTTON, 10);
    • Then, we need to define another function, as shown in the following code, this time one that triggers an event based on when the button is pressed:
      function readBUTTON() {
      b.digitalRead(BUTTON, writeLED);
      }
    • Finally, we will define a function for the LED when the button is pressed with the following code:
      function writeLED(x) {
        b.digitalWrite(LED, !x.value);
      }
  4. Finally, we run the script by clicking the Run button. Your LED should now be blinking. Change the interval value to speed it up or slow it down.

    Note

    If you get an error in the IDE's console window, sometimes the fix is as simple as clicking on the Resume button in the upper-right corner panel or just restarting the script. You can also turn off the debugger to keep the script running.

There's more…

The ultimate circuit/resistor/capacitor cheat sheet—we recommend a couple of very useful smartphone apps that serve as exceptionally handy reference tools for resistor and capacitor codes, circuit calculators, and other useful component values. First, is AdaFruit's Circuit Playground app for iPhone and Android. Although not free (but available for just a few dollars), it sure beats getting it wrong on those resistor color value bands. Second, for the Android platform only is Electrodroid, which has free and pro (USD $2.99) versions available in the Google Play store.

Pull-up, pull-down, and floating

Frequently when wiring up circuits, you will hear references to pull-up, pull-down, and floating configurations. When your design is a pull-up circuit, this means that the resistor holds the positive or supply voltage (VCC) until you push the button pulling it up to ground. This is the most common scenario, and one you encounter when you design a circuit with a button press to activate something.

In the pull-down version of a circuit, the resistor in the circuit remains at ground unless you push (or pull down) the button, causing the circuit to switch from ground to positive or supply voltage (VCC).

Floating means the circuit is neither tied to ground or a particular voltage. This can create a situation where a pin may accumulate some kind of charge on it, thus throwing off incorrect values. You can create a more reliable circuit by writing code to correct for these potential false readings.

The purpose of this recipe is to read the state of a button press and have it turn an LED on and off. When the button is not pressed, the state of the input pin will be a 1 or high due to the resistor pulling the pin up. When the button is pressed, the input pin will be grounded low and have the value as 0.

Getting ready

You'll need the following items for this recipe:

  • 1 x LED: This is the same one you used in the previous section.
  • 1 x pushbutton: This is a simple, one button, four-pronged tactile switch. By default, the button pins are open (disconnected) and momentarily closed (connected) when the button is pressed.
  • Resistors: 2x 700 (700Ω) to 1k will be fine. We will use the 700Ω here (violet/black/brown/gold bands).
  • 5 x jumper wires: This is easy to connect to the breadboard.
  • Breadboard.

How to do it...

  1. Wire your board and breadboard in the following manner:
    1. Connect the GND wire to GND at P9_2 on the BBB and the other end to GND in the first slot at the top of the second row on the breadboard.
    2. Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
    3. The button will use the next wire. Connect a wire to the pin on the P9_15 BBB and to the first slot in the same row in the upper-left corner of the button on the breadboard.
    4. Take another wire and connect one end to P8_11 on BBB and the other end to row 2 and column 1 on the breadboard.
    5. The last wire serves as Ground for the button. Connect one end of this wire to the GND rail and the other end next to the button's GND leg.
    6. On the breadboard, connect the LED's cathode pin (the shorter end) to the GND rail and the anode or the positive lead (the longer end) into the sixth row of the breadboard
    7. Insert one resistor to regulate the current to the LED and the other to regulate the flow through the button, as shown in the following image:
    How to do it...
  2. Now, open your Cloud9 IDE at http://192.168.7.2:3000 and create a new file called button-led.js.
  3. Then, use the following code to turn the LED on and off with a push button. Copy and paste it into the open IDE window:
    // Setup
    var b = require('bonescript'); //Read library
    var LED = "P8_11"; //Pin where LED is connected
    var BUTTON = "P9_15";
    
    b.pinMode(LED, b.OUTPUT);
    b.pinMode(BUTTON, b.INPUT);
    
    setInterval(readBUTTON, 10);
    
    function readBUTTON() {
        b.digitalRead(BUTTON, writeLED);
    }
    
    function writeLED(x) {
        b.digitalWrite(LED, !x.value);
    }    
    • Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
      // Setup
      var b = require('bonescript'); //Read library
    • Now, choose the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin (see the pin layout reference diagram at the end of this section for more background on the GPIOs):
      var LED = "P8_11"; //Pin where LED is connected
    • Then, we will set the pin number for the button, as follows:
      var BUTTON = "P9_15";
    • Now, we will tell the previously specified pins to function in an OUTPUT mode for the LED and in an INPUT mode for the button, as shown in the following code:
      b.pinMode(LED, b.OUTPUT);
      b.pinMode(BUTTON, b.INPUT);

      You can also write it this way:

      b.pinMode(LED, "out");
      b.pinMode(BUTTON, "in");
    • Now, we need to check the status of the button at specific intervals, in this case, every 10 minutes, as shown in the following code:
      setInterval(readBUTTON, 10);
    • Then, we need to define another function, as shown in the following code, this time one that triggers an event based on when the button is pressed:
      function readBUTTON() {
      b.digitalRead(BUTTON, writeLED);
      }
    • Finally, we will define a function for the LED when the button is pressed with the following code:
      function writeLED(x) {
        b.digitalWrite(LED, !x.value);
      }
  4. Finally, we run the script by clicking the Run button. Your LED should now be blinking. Change the interval value to speed it up or slow it down.

    Note

    If you get an error in the IDE's console window, sometimes the fix is as simple as clicking on the Resume button in the upper-right corner panel or just restarting the script. You can also turn off the debugger to keep the script running.

There's more…

The ultimate circuit/resistor/capacitor cheat sheet—we recommend a couple of very useful smartphone apps that serve as exceptionally handy reference tools for resistor and capacitor codes, circuit calculators, and other useful component values. First, is AdaFruit's Circuit Playground app for iPhone and Android. Although not free (but available for just a few dollars), it sure beats getting it wrong on those resistor color value bands. Second, for the Android platform only is Electrodroid, which has free and pro (USD $2.99) versions available in the Google Play store.

Getting ready

You'll need the following items for this recipe:

  • 1 x LED: This is the same one you used in the previous section.
  • 1 x pushbutton: This is a simple, one button, four-pronged tactile switch. By default, the button pins are open (disconnected) and momentarily closed (connected) when the button is pressed.
  • Resistors: 2x 700 (700Ω) to 1k will be fine. We will use the 700Ω here (violet/black/brown/gold bands).
  • 5 x jumper wires: This is easy to connect to the breadboard.
  • Breadboard.

How to do it...

  1. Wire your board and breadboard in the following manner:
    1. Connect the GND wire to GND at P9_2 on the BBB and the other end to GND in the first slot at the top of the second row on the breadboard.
    2. Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
    3. The button will use the next wire. Connect a wire to the pin on the P9_15 BBB and to the first slot in the same row in the upper-left corner of the button on the breadboard.
    4. Take another wire and connect one end to P8_11 on BBB and the other end to row 2 and column 1 on the breadboard.
    5. The last wire serves as Ground for the button. Connect one end of this wire to the GND rail and the other end next to the button's GND leg.
    6. On the breadboard, connect the LED's cathode pin (the shorter end) to the GND rail and the anode or the positive lead (the longer end) into the sixth row of the breadboard
    7. Insert one resistor to regulate the current to the LED and the other to regulate the flow through the button, as shown in the following image:
    How to do it...
  2. Now, open your Cloud9 IDE at http://192.168.7.2:3000 and create a new file called button-led.js.
  3. Then, use the following code to turn the LED on and off with a push button. Copy and paste it into the open IDE window:
    // Setup
    var b = require('bonescript'); //Read library
    var LED = "P8_11"; //Pin where LED is connected
    var BUTTON = "P9_15";
    
    b.pinMode(LED, b.OUTPUT);
    b.pinMode(BUTTON, b.INPUT);
    
    setInterval(readBUTTON, 10);
    
    function readBUTTON() {
        b.digitalRead(BUTTON, writeLED);
    }
    
    function writeLED(x) {
        b.digitalWrite(LED, !x.value);
    }    
    • Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
      // Setup
      var b = require('bonescript'); //Read library
    • Now, choose the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin (see the pin layout reference diagram at the end of this section for more background on the GPIOs):
      var LED = "P8_11"; //Pin where LED is connected
    • Then, we will set the pin number for the button, as follows:
      var BUTTON = "P9_15";
    • Now, we will tell the previously specified pins to function in an OUTPUT mode for the LED and in an INPUT mode for the button, as shown in the following code:
      b.pinMode(LED, b.OUTPUT);
      b.pinMode(BUTTON, b.INPUT);

      You can also write it this way:

      b.pinMode(LED, "out");
      b.pinMode(BUTTON, "in");
    • Now, we need to check the status of the button at specific intervals, in this case, every 10 minutes, as shown in the following code:
      setInterval(readBUTTON, 10);
    • Then, we need to define another function, as shown in the following code, this time one that triggers an event based on when the button is pressed:
      function readBUTTON() {
      b.digitalRead(BUTTON, writeLED);
      }
    • Finally, we will define a function for the LED when the button is pressed with the following code:
      function writeLED(x) {
        b.digitalWrite(LED, !x.value);
      }
  4. Finally, we run the script by clicking the Run button. Your LED should now be blinking. Change the interval value to speed it up or slow it down.

    Note

    If you get an error in the IDE's console window, sometimes the fix is as simple as clicking on the Resume button in the upper-right corner panel or just restarting the script. You can also turn off the debugger to keep the script running.

There's more…

The ultimate circuit/resistor/capacitor cheat sheet—we recommend a couple of very useful smartphone apps that serve as exceptionally handy reference tools for resistor and capacitor codes, circuit calculators, and other useful component values. First, is AdaFruit's Circuit Playground app for iPhone and Android. Although not free (but available for just a few dollars), it sure beats getting it wrong on those resistor color value bands. Second, for the Android platform only is Electrodroid, which has free and pro (USD $2.99) versions available in the Google Play store.

How to do it...

  1. Wire your board and breadboard in the following manner:
    1. Connect the GND wire to GND at P9_2 on the BBB and the other end to GND in the first slot at the top of the second row on the breadboard.
    2. Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
    3. The button will use the next wire. Connect a wire to the pin on the P9_15 BBB and to the first slot in the same row in the upper-left corner of the button on the breadboard.
    4. Take another wire and connect one end to P8_11 on BBB and the other end to row 2 and column 1 on the breadboard.
    5. The last wire serves as Ground for the button. Connect one end of this wire to the GND rail and the other end next to the button's GND leg.
    6. On the breadboard, connect the LED's cathode pin (the shorter end) to the GND rail and the anode or the positive lead (the longer end) into the sixth row of the breadboard
    7. Insert one resistor to regulate the current to the LED and the other to regulate the flow through the button, as shown in the following image:
    How to do it...
  2. Now, open your Cloud9 IDE at http://192.168.7.2:3000 and create a new file called button-led.js.
  3. Then, use the following code to turn the LED on and off with a push button. Copy and paste it into the open IDE window:
    // Setup
    var b = require('bonescript'); //Read library
    var LED = "P8_11"; //Pin where LED is connected
    var BUTTON = "P9_15";
    
    b.pinMode(LED, b.OUTPUT);
    b.pinMode(BUTTON, b.INPUT);
    
    setInterval(readBUTTON, 10);
    
    function readBUTTON() {
        b.digitalRead(BUTTON, writeLED);
    }
    
    function writeLED(x) {
        b.digitalWrite(LED, !x.value);
    }    
    • Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
      // Setup
      var b = require('bonescript'); //Read library
    • Now, choose the pin number where your LED is wired. You can change this option easily; just be sure to choose from an available pin (see the pin layout reference diagram at the end of this section for more background on the GPIOs):
      var LED = "P8_11"; //Pin where LED is connected
    • Then, we will set the pin number for the button, as follows:
      var BUTTON = "P9_15";
    • Now, we will tell the previously specified pins to function in an OUTPUT mode for the LED and in an INPUT mode for the button, as shown in the following code:
      b.pinMode(LED, b.OUTPUT);
      b.pinMode(BUTTON, b.INPUT);

      You can also write it this way:

      b.pinMode(LED, "out");
      b.pinMode(BUTTON, "in");
    • Now, we need to check the status of the button at specific intervals, in this case, every 10 minutes, as shown in the following code:
      setInterval(readBUTTON, 10);
    • Then, we need to define another function, as shown in the following code, this time one that triggers an event based on when the button is pressed:
      function readBUTTON() {
      b.digitalRead(BUTTON, writeLED);
      }
    • Finally, we will define a function for the LED when the button is pressed with the following code:
      function writeLED(x) {
        b.digitalWrite(LED, !x.value);
      }
  4. Finally, we run the script by clicking the Run button. Your LED should now be blinking. Change the interval value to speed it up or slow it down.

    Note

    If you get an error in the IDE's console window, sometimes the fix is as simple as clicking on the Resume button in the upper-right corner panel or just restarting the script. You can also turn off the debugger to keep the script running.

There's more…

The ultimate circuit/resistor/capacitor cheat sheet—we recommend a couple of very useful smartphone apps that serve as exceptionally handy reference tools for resistor and capacitor codes, circuit calculators, and other useful component values. First, is AdaFruit's Circuit Playground app for iPhone and Android. Although not free (but available for just a few dollars), it sure beats getting it wrong on those resistor color value bands. Second, for the Android platform only is Electrodroid, which has free and pro (USD $2.99) versions available in the Google Play store.

There's more…

The ultimate circuit/resistor/capacitor cheat sheet—we recommend a couple of very useful smartphone apps that serve as exceptionally handy reference tools for resistor and capacitor codes, circuit calculators, and other useful component values. First, is AdaFruit's Circuit Playground app for iPhone and Android. Although not free (but available for just a few dollars), it sure beats getting it wrong on those resistor color value bands. Second, for the Android platform only is Electrodroid, which has free and pro (USD $2.99) versions available in the Google Play store.

Using analog sensors

Now it's time to grab some analog data. Wait a second? Analog? Isn't the world we live in—including the BBB's—all digital? Mostly, yes. But the world of sensors is vast, and many of the most ubiquitous, most useful, and least costly sensors are analog devices. A great deal of the embedded sensing world—motion, temperature, humidity, light intensity, pressure, and accelerometers—consists of analog animals. So, how do we capture all that analog data goodness?

With ADC (analog to digital converter) pins, of course. And the BBB comes with seven pre-assigned analog inputs on our board, so it's nearly plug and play! Well, not quite. But at least we don't have to fuss with pin muxing right away.

Temperature sensors

For this recipe, we're using the TMP36, a very low cost (USD $1.50) analog temperature sensor that you can find at many different electronics stores or suppliers. It outputs an analog voltage that is proportional to the ambient temperature. We will write a script that takes that proportional value and reads back the temperature into the Cloud9 console.

Getting ready

  • Temperature sensor: Available at SparkFun (http://bit.ly/OCGFDj)
  • 3x jumper wires: Easy to connect to the breadboard
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
    How to do it...

    Be sure that you…

    Put the GND into the special analog ground GNDA_ADC on the BBB. In our diagram, that's the black wire into pin P9_34.

    Put the 3V into the 3V on the BBB. In our case, that's the red wire into pin P9_3.

    Note

    Very Important!

    The analog inputs on the BeagleBone Black accept a maximum of 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    For the sensor (markings facing you), match up the pins as follows:

    Pin 1 (left pin): Power/3.3V

    Pin 2 (middle pin): Analog pin on the BBB which in our recipe is pin P9_38, or AIN3

    Pin 3 (right pin): Ground pin on the BBB

  2. Open up Cloud9 IDE at http://192.168.7.2:3000 and use the following code to begin capturing temperature readings:
    //Setup
    var b = require('bonescript'); // Read library
    var TMP36 = "P9_38"; // Pin location for sensor
    
    //Check the temperature every 4 seconds
    setInterval(readTMP, 4000);
    
    //Define the 'readTMP' function
    function readTMP() {
      b.analogRead(TMP36, writeTMP);
    }
    
    //Define the 'writeTMP' function
    function writeTMP(x) {
      var millivolts = x.value * 1800; // 1.8V
      var temp_c = (millivolts - 500) / 10;
      var temp_f = (temp_c * 9/5) + 32;
      console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
    }
  3. The code is broken down as follows:
    • Evoke the BoneScript library:
      // Setup
      var b = require('bonescript');
    • Now, choose the pin number where your sensor is wired. See the pin layout reference diagram at the end of this section for more background on the ADC input options:
      var TMP36 = "P9_38"; // Pin location for sensor 
    • Then, we'll check the temperature at specific intervals, in this case, every four seconds:
      setInterval(readTMP, 4000);
    • Now, we define the readTMP function:
      function readTMP() {
        b.analogRead(TMP36, writeTMP);
      }
    • Finally, we define the writeTMP function, which is where the voltage data captured is turned into temperature readings. We calculate the temperature from the voltage in millivolts with a simple formula, Temp C = 100 x (reading in V) - 50:
      function writeTMP(x) {
        var millivolts = x.value * 1800; // 1.8V
        var temp_c = (millivolts - 500) / 10;
        var temp_f = (temp_c * 9/5) + 32;
        console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
      }
  4. When you are ready to run the code, just click the Run button in the IDE. Your output should look like the following (with your local temperature, of course):
    Current temperature is 20 C and 68 F
    Current temperature is 22.4 C and 72.32 F

    Note

    If you get some funky temperature readings, reboot your board and rerun the script.

There's more…

You can try exactly the same exercise, this time with Python—https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc.

See also

Temperature sensors

For this recipe, we're using the TMP36, a very low cost (USD $1.50) analog temperature sensor that you can find at many different electronics stores or suppliers. It outputs an analog voltage that is proportional to the ambient temperature. We will write a script that takes that proportional value and reads back the temperature into the Cloud9 console.

Getting ready

  • Temperature sensor: Available at SparkFun (http://bit.ly/OCGFDj)
  • 3x jumper wires: Easy to connect to the breadboard
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
    How to do it...

    Be sure that you…

    Put the GND into the special analog ground GNDA_ADC on the BBB. In our diagram, that's the black wire into pin P9_34.

    Put the 3V into the 3V on the BBB. In our case, that's the red wire into pin P9_3.

    Note

    Very Important!

    The analog inputs on the BeagleBone Black accept a maximum of 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    For the sensor (markings facing you), match up the pins as follows:

    Pin 1 (left pin): Power/3.3V

    Pin 2 (middle pin): Analog pin on the BBB which in our recipe is pin P9_38, or AIN3

    Pin 3 (right pin): Ground pin on the BBB

  2. Open up Cloud9 IDE at http://192.168.7.2:3000 and use the following code to begin capturing temperature readings:
    //Setup
    var b = require('bonescript'); // Read library
    var TMP36 = "P9_38"; // Pin location for sensor
    
    //Check the temperature every 4 seconds
    setInterval(readTMP, 4000);
    
    //Define the 'readTMP' function
    function readTMP() {
      b.analogRead(TMP36, writeTMP);
    }
    
    //Define the 'writeTMP' function
    function writeTMP(x) {
      var millivolts = x.value * 1800; // 1.8V
      var temp_c = (millivolts - 500) / 10;
      var temp_f = (temp_c * 9/5) + 32;
      console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
    }
  3. The code is broken down as follows:
    • Evoke the BoneScript library:
      // Setup
      var b = require('bonescript');
    • Now, choose the pin number where your sensor is wired. See the pin layout reference diagram at the end of this section for more background on the ADC input options:
      var TMP36 = "P9_38"; // Pin location for sensor 
    • Then, we'll check the temperature at specific intervals, in this case, every four seconds:
      setInterval(readTMP, 4000);
    • Now, we define the readTMP function:
      function readTMP() {
        b.analogRead(TMP36, writeTMP);
      }
    • Finally, we define the writeTMP function, which is where the voltage data captured is turned into temperature readings. We calculate the temperature from the voltage in millivolts with a simple formula, Temp C = 100 x (reading in V) - 50:
      function writeTMP(x) {
        var millivolts = x.value * 1800; // 1.8V
        var temp_c = (millivolts - 500) / 10;
        var temp_f = (temp_c * 9/5) + 32;
        console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
      }
  4. When you are ready to run the code, just click the Run button in the IDE. Your output should look like the following (with your local temperature, of course):
    Current temperature is 20 C and 68 F
    Current temperature is 22.4 C and 72.32 F

    Note

    If you get some funky temperature readings, reboot your board and rerun the script.

There's more…

You can try exactly the same exercise, this time with Python—https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc.

See also

Getting ready

  • Temperature sensor: Available at SparkFun (http://bit.ly/OCGFDj)
  • 3x jumper wires: Easy to connect to the breadboard
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
    How to do it...

    Be sure that you…

    Put the GND into the special analog ground GNDA_ADC on the BBB. In our diagram, that's the black wire into pin P9_34.

    Put the 3V into the 3V on the BBB. In our case, that's the red wire into pin P9_3.

    Note

    Very Important!

    The analog inputs on the BeagleBone Black accept a maximum of 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    For the sensor (markings facing you), match up the pins as follows:

    Pin 1 (left pin): Power/3.3V

    Pin 2 (middle pin): Analog pin on the BBB which in our recipe is pin P9_38, or AIN3

    Pin 3 (right pin): Ground pin on the BBB

  2. Open up Cloud9 IDE at http://192.168.7.2:3000 and use the following code to begin capturing temperature readings:
    //Setup
    var b = require('bonescript'); // Read library
    var TMP36 = "P9_38"; // Pin location for sensor
    
    //Check the temperature every 4 seconds
    setInterval(readTMP, 4000);
    
    //Define the 'readTMP' function
    function readTMP() {
      b.analogRead(TMP36, writeTMP);
    }
    
    //Define the 'writeTMP' function
    function writeTMP(x) {
      var millivolts = x.value * 1800; // 1.8V
      var temp_c = (millivolts - 500) / 10;
      var temp_f = (temp_c * 9/5) + 32;
      console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
    }
  3. The code is broken down as follows:
    • Evoke the BoneScript library:
      // Setup
      var b = require('bonescript');
    • Now, choose the pin number where your sensor is wired. See the pin layout reference diagram at the end of this section for more background on the ADC input options:
      var TMP36 = "P9_38"; // Pin location for sensor 
    • Then, we'll check the temperature at specific intervals, in this case, every four seconds:
      setInterval(readTMP, 4000);
    • Now, we define the readTMP function:
      function readTMP() {
        b.analogRead(TMP36, writeTMP);
      }
    • Finally, we define the writeTMP function, which is where the voltage data captured is turned into temperature readings. We calculate the temperature from the voltage in millivolts with a simple formula, Temp C = 100 x (reading in V) - 50:
      function writeTMP(x) {
        var millivolts = x.value * 1800; // 1.8V
        var temp_c = (millivolts - 500) / 10;
        var temp_f = (temp_c * 9/5) + 32;
        console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
      }
  4. When you are ready to run the code, just click the Run button in the IDE. Your output should look like the following (with your local temperature, of course):
    Current temperature is 20 C and 68 F
    Current temperature is 22.4 C and 72.32 F

    Note

    If you get some funky temperature readings, reboot your board and rerun the script.

There's more…

You can try exactly the same exercise, this time with Python—https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc.

See also

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
    How to do it...

    Be sure that you…

    Put the GND into the special analog ground GNDA_ADC on the BBB. In our diagram, that's the black wire into pin P9_34.

    Put the 3V into the 3V on the BBB. In our case, that's the red wire into pin P9_3.

    Note

    Very Important!

    The analog inputs on the BeagleBone Black accept a maximum of 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    For the sensor (markings facing you), match up the pins as follows:

    Pin 1 (left pin): Power/3.3V

    Pin 2 (middle pin): Analog pin on the BBB which in our recipe is pin P9_38, or AIN3

    Pin 3 (right pin): Ground pin on the BBB

  2. Open up Cloud9 IDE at http://192.168.7.2:3000 and use the following code to begin capturing temperature readings:
    //Setup
    var b = require('bonescript'); // Read library
    var TMP36 = "P9_38"; // Pin location for sensor
    
    //Check the temperature every 4 seconds
    setInterval(readTMP, 4000);
    
    //Define the 'readTMP' function
    function readTMP() {
      b.analogRead(TMP36, writeTMP);
    }
    
    //Define the 'writeTMP' function
    function writeTMP(x) {
      var millivolts = x.value * 1800; // 1.8V
      var temp_c = (millivolts - 500) / 10;
      var temp_f = (temp_c * 9/5) + 32;
      console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
    }
  3. The code is broken down as follows:
    • Evoke the BoneScript library:
      // Setup
      var b = require('bonescript');
    • Now, choose the pin number where your sensor is wired. See the pin layout reference diagram at the end of this section for more background on the ADC input options:
      var TMP36 = "P9_38"; // Pin location for sensor 
    • Then, we'll check the temperature at specific intervals, in this case, every four seconds:
      setInterval(readTMP, 4000);
    • Now, we define the readTMP function:
      function readTMP() {
        b.analogRead(TMP36, writeTMP);
      }
    • Finally, we define the writeTMP function, which is where the voltage data captured is turned into temperature readings. We calculate the temperature from the voltage in millivolts with a simple formula, Temp C = 100 x (reading in V) - 50:
      function writeTMP(x) {
        var millivolts = x.value * 1800; // 1.8V
        var temp_c = (millivolts - 500) / 10;
        var temp_f = (temp_c * 9/5) + 32;
        console.log("Current temperature is " + temp_c + " C and " + temp_f + " F");
      }
  4. When you are ready to run the code, just click the Run button in the IDE. Your output should look like the following (with your local temperature, of course):
    Current temperature is 20 C and 68 F
    Current temperature is 22.4 C and 72.32 F

    Note

    If you get some funky temperature readings, reboot your board and rerun the script.

There's more…

You can try exactly the same exercise, this time with Python—https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc.

See also

There's more…

You can try exactly the same exercise, this time with Python—https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/adc.

See also

See also

Variable resistance sensor – photocell

Capturing the data generated from light sensors is one of those satisfying and highly useful examples of physical computing. Some of you may have used light sensors—also known as CdS cells, photoresistors, and photocells—in your Arduino or Raspberry Pi projects. If so, this recipe will be a snap for you.

A photocell is a variable resistor, which in this case means that it varies its resistance according to the intensity of light exposed to it. The value of that variable resistance is turned into data, which in turn means the sensor functions as an effective measurement tool for ambient light. In this recipe, we show you how to read analog values captured from a light sensor using BoneScript along with an alternative Python script.

Note

CdS stands for Cadmium Sulfide, a compound that is non-ROHs compliant due to the cadmium, a chemical severely restricted in Europe as hazardous waste.

Getting ready

Rustle up the items in the list below for this recipe:

  • Photoresistor (photocell): Nothing fancy for our purposes here. We're using one that costs less than USD $1.50 in many electronics stores such as SparkFun (http://bit.ly/1kwejIt).
  • Resistor: 10,000 (10kΩ); brown/black/orange/gold bands
  • 3x jumper wires: Easy to connect to breadboard.
  • Breadboard.

How to do it…

  1. First, make sure your BBB is powered down, then wire up your breadboard. Here's what your wiring should look like:
    How to do it…

    We wire this sensor up differently from the temperature sensor, so take care with the diagram. If you are reading this recipe and want to see color versions of the fritzing diagrams for better clarity on the wiring, you can find them online at http://bit.ly/1MP2UNo:

    Light sensor: Plug the light sensor's wires into the breadboard, positioning the wires four or five slots apart from one another for easier wiring management.

    Resistor: Plug the 10k resistor into the breadboard a couple of columns in front of the photocell with one end of the resistor aligned with the bottom wire of the sensor.

    Voltage wire: Plug the red wire into the P9_32 slot on the BBB. This is one of the board's specially designated pins (labeled VDD_ADC) for 1.8V reference voltage, a low power source for analog sensors like this. The other end of the wire should be inserted into the breadboard aligning with the phototcell's top wire.

    Ground wire: The blue wire is for ground (GND), and for this we will also use a special ground pin at P9_34 for 1.8V (GNDA_ADC).

    Note

    VERY IMPORTANT!

    The analog inputs on the BeagleBone Black accept a maximum 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    Sensor pin: Plug one end of the yellow wire into P9_37 on the BBB, and the other end into a breadboard slot in front of the resistor. It should align with the bottom wire of the light sensor.

  2. Open up Cloud9 IDE at http://192.168.7.2:3000.
  3. Create a new file called light_sensor.js, and paste the following BoneScript code into the window:
    var b = require('bonescript');
    function lightSensor() {
     b.analogRead('P9_37', lightValue);
    }
    
    function lightValue(reading) {
      var millivolts = reading.value * 1800;
      console.log("Light output in millivolts: " + millivolts + "\n");
    
    }
    
    setInterval(lightSensor, 1000);
  4. Press the Run button to begin capturing light intensity readings. Your console output should look something like this. Your readings, of course, will vary according to the strength of your light source:
    Light output in millivolts: 1387
    Light output in millivolts: 1386
    Light output in millivolts: 1159
    Light output in millivolts: 608
    

    Moving your hand over or close to the sensor should make the output numbers rise and fall based on how the light source hits the sensor. Notice that doing all this requires very few lines of code. So, let's take a quick look at what some of the parts of the script are doing

  5. Besides evoking the BoneScript library, the first section defines a read function on a specific analog pin that we will reference on the BBB:
    var b = require('bonescript');
    function lightSensor() {
      b.analogRead('P9_37', lightValue);
    }
  6. In the next section, we define a function that determines how the sensor data being captured will be crunched. That data is expressed in millivolts and varies at a constant rate:
    function lightValue(reading) {
      var millivolts = reading.value * 1800;
      console.log("Light output in millivolts: " + millivolts + "\n");
    }

    The \n in the code simply creates a space between each output for better legibility.

Optional Python code

Besides the code above, you can also test your light sensor with a Python script available on our Github repository. There is a ReadMe file on the repo, but here are the basic steps:

  1. Download the Python code with the following command:
    $ git clone 
    https://github.com/HudsonWerks/light-sensor.git
    
  2. Browse to the directory with the Python script and run it:
    $ cd light_sensor
    $ sudo python light_sensor.py
    

    Your output should be very similar to what you saw in the BoneScript example.

Getting ready

Rustle up the items in the list below for this recipe:

  • Photoresistor (photocell): Nothing fancy for our purposes here. We're using one that costs less than USD $1.50 in many electronics stores such as SparkFun (http://bit.ly/1kwejIt).
  • Resistor: 10,000 (10kΩ); brown/black/orange/gold bands
  • 3x jumper wires: Easy to connect to breadboard.
  • Breadboard.

How to do it…

  1. First, make sure your BBB is powered down, then wire up your breadboard. Here's what your wiring should look like:
    How to do it…

    We wire this sensor up differently from the temperature sensor, so take care with the diagram. If you are reading this recipe and want to see color versions of the fritzing diagrams for better clarity on the wiring, you can find them online at http://bit.ly/1MP2UNo:

    Light sensor: Plug the light sensor's wires into the breadboard, positioning the wires four or five slots apart from one another for easier wiring management.

    Resistor: Plug the 10k resistor into the breadboard a couple of columns in front of the photocell with one end of the resistor aligned with the bottom wire of the sensor.

    Voltage wire: Plug the red wire into the P9_32 slot on the BBB. This is one of the board's specially designated pins (labeled VDD_ADC) for 1.8V reference voltage, a low power source for analog sensors like this. The other end of the wire should be inserted into the breadboard aligning with the phototcell's top wire.

    Ground wire: The blue wire is for ground (GND), and for this we will also use a special ground pin at P9_34 for 1.8V (GNDA_ADC).

    Note

    VERY IMPORTANT!

    The analog inputs on the BeagleBone Black accept a maximum 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    Sensor pin: Plug one end of the yellow wire into P9_37 on the BBB, and the other end into a breadboard slot in front of the resistor. It should align with the bottom wire of the light sensor.

  2. Open up Cloud9 IDE at http://192.168.7.2:3000.
  3. Create a new file called light_sensor.js, and paste the following BoneScript code into the window:
    var b = require('bonescript');
    function lightSensor() {
     b.analogRead('P9_37', lightValue);
    }
    
    function lightValue(reading) {
      var millivolts = reading.value * 1800;
      console.log("Light output in millivolts: " + millivolts + "\n");
    
    }
    
    setInterval(lightSensor, 1000);
  4. Press the Run button to begin capturing light intensity readings. Your console output should look something like this. Your readings, of course, will vary according to the strength of your light source:
    Light output in millivolts: 1387
    Light output in millivolts: 1386
    Light output in millivolts: 1159
    Light output in millivolts: 608
    

    Moving your hand over or close to the sensor should make the output numbers rise and fall based on how the light source hits the sensor. Notice that doing all this requires very few lines of code. So, let's take a quick look at what some of the parts of the script are doing

  5. Besides evoking the BoneScript library, the first section defines a read function on a specific analog pin that we will reference on the BBB:
    var b = require('bonescript');
    function lightSensor() {
      b.analogRead('P9_37', lightValue);
    }
  6. In the next section, we define a function that determines how the sensor data being captured will be crunched. That data is expressed in millivolts and varies at a constant rate:
    function lightValue(reading) {
      var millivolts = reading.value * 1800;
      console.log("Light output in millivolts: " + millivolts + "\n");
    }

    The \n in the code simply creates a space between each output for better legibility.

Optional Python code

Besides the code above, you can also test your light sensor with a Python script available on our Github repository. There is a ReadMe file on the repo, but here are the basic steps:

  1. Download the Python code with the following command:
    $ git clone 
    https://github.com/HudsonWerks/light-sensor.git
    
  2. Browse to the directory with the Python script and run it:
    $ cd light_sensor
    $ sudo python light_sensor.py
    

    Your output should be very similar to what you saw in the BoneScript example.

How to do it…

  1. First, make sure your BBB is powered down, then wire up your breadboard. Here's what your wiring should look like:
    How to do it…

    We wire this sensor up differently from the temperature sensor, so take care with the diagram. If you are reading this recipe and want to see color versions of the fritzing diagrams for better clarity on the wiring, you can find them online at http://bit.ly/1MP2UNo:

    Light sensor: Plug the light sensor's wires into the breadboard, positioning the wires four or five slots apart from one another for easier wiring management.

    Resistor: Plug the 10k resistor into the breadboard a couple of columns in front of the photocell with one end of the resistor aligned with the bottom wire of the sensor.

    Voltage wire: Plug the red wire into the P9_32 slot on the BBB. This is one of the board's specially designated pins (labeled VDD_ADC) for 1.8V reference voltage, a low power source for analog sensors like this. The other end of the wire should be inserted into the breadboard aligning with the phototcell's top wire.

    Ground wire: The blue wire is for ground (GND), and for this we will also use a special ground pin at P9_34 for 1.8V (GNDA_ADC).

    Note

    VERY IMPORTANT!

    The analog inputs on the BeagleBone Black accept a maximum 1.8V. Never apply more voltage than 1.8V to the analog pins or you will damage your board.

    Sensor pin: Plug one end of the yellow wire into P9_37 on the BBB, and the other end into a breadboard slot in front of the resistor. It should align with the bottom wire of the light sensor.

  2. Open up Cloud9 IDE at http://192.168.7.2:3000.
  3. Create a new file called light_sensor.js, and paste the following BoneScript code into the window:
    var b = require('bonescript');
    function lightSensor() {
     b.analogRead('P9_37', lightValue);
    }
    
    function lightValue(reading) {
      var millivolts = reading.value * 1800;
      console.log("Light output in millivolts: " + millivolts + "\n");
    
    }
    
    setInterval(lightSensor, 1000);
  4. Press the Run button to begin capturing light intensity readings. Your console output should look something like this. Your readings, of course, will vary according to the strength of your light source:
    Light output in millivolts: 1387
    Light output in millivolts: 1386
    Light output in millivolts: 1159
    Light output in millivolts: 608
    

    Moving your hand over or close to the sensor should make the output numbers rise and fall based on how the light source hits the sensor. Notice that doing all this requires very few lines of code. So, let's take a quick look at what some of the parts of the script are doing

  5. Besides evoking the BoneScript library, the first section defines a read function on a specific analog pin that we will reference on the BBB:
    var b = require('bonescript');
    function lightSensor() {
      b.analogRead('P9_37', lightValue);
    }
  6. In the next section, we define a function that determines how the sensor data being captured will be crunched. That data is expressed in millivolts and varies at a constant rate:
    function lightValue(reading) {
      var millivolts = reading.value * 1800;
      console.log("Light output in millivolts: " + millivolts + "\n");
    }

    The \n in the code simply creates a space between each output for better legibility.

Optional Python code

Besides the code above, you can also test your light sensor with a Python script available on our Github repository. There is a ReadMe file on the repo, but here are the basic steps:

  1. Download the Python code with the following command:
    $ git clone 
    https://github.com/HudsonWerks/light-sensor.git
    
  2. Browse to the directory with the Python script and run it:
    $ cd light_sensor
    $ sudo python light_sensor.py
    

    Your output should be very similar to what you saw in the BoneScript example.

Using motors

Whether it's a robot, an RC toy, a CNC, a 3D printer, or a high-end industrial machine, motion control is one of the most popular subjects in physical computing.

In our examples, we'll be using BoneScript to run our devices, beginning with a DC motor and then following with a servomotor.

However, first you should learn a little about the type of pins that we will use in the following recipes.

DC motors

They're fun. They're cheap. They're everywhere. The little motors that have been driving toys for decades still remain a mainstay for projects where locomotion is part of the picture. Understanding how to drive a DC motor requires more complex and powerful mechanisms, such as robotics.

Getting ready

You will need several items for this recipe:

  • DC motor: This is a standard issue 2-lead motor prevalent in toys and cheaper RC devices.
  • H-Bridge IC motor driver: This Texas instrument component SN754410 is available at Sparkfun (https://www.sparkfun.com/products/315) and other similar sources for approximately 2.50 USD. It is also commonly used in the L293D version. This little circuit is an important piece of the puzzle because it is the mechanism used to send the voltage that drives the motor's direction and regulates its speed. More details about this IC are described later in this recipe.
    • 13x jumper wires
    • 1x pushbutton/switch
    • 1x 1k resistor
    • 9V battery and holder
    • Breadboard

How to do it...

Perform the following steps to test the DC motors:

  1. Make sure that your BBB is powered down first and then wire your breadboard as follows. Clearly, this is a thicket of wires, so be methodical as you follow the diagram:
    How to do it...

    To help with the diagram above, here are some further details for the wiring setup:

    Hardware

    Pin#

    Color

    Location/purpose

    BBB

    P8_7

    Blue

    Pin 2 (1A, motor logic 1) on H-bridge

    BBB

    P8_13

    Yellow

    Pin 1 (1,2EN/PWM) on H-bridge

    BBB

    P8_19

    Green

    Pin 7 (2A, motor logic 1) on H-bridge

    BBB

    P8_8

    Blue

    GND on breadboard button—aligned with 1k resistor

    BBB

    P9_1

    Black

    GND on breadboard rail

    BBB

    P9_7

    Red

    5V power to button

    Motor Wire 1

      

    Attached at pin 3 (1Y) on H-bridge

    Motor Wire 2

      

    Attached at pin 6 (2Y) on H-bridge

    Battery wire 1

    Black

    GND rail on breadboard

    Battery wire 2

    RED to PWR rail on breadboard

    Bus wire 1

    Black

    GND

    Bus wire 2

    Red

    VCC

  2. Open the Cloud9 IDE at http://192.168.7.2:3000 and navigate to File | New From Template | Javascript.
  3. Save the new file as DC_motor1.js.
  4. Paste the new document to the following BoneScript code:
    var b = require('bonescript');
    
    var enablePin = "P8_13"; //pin 1 (1,2EN/PWM) on H-Bridge
    var motorPin1 = "P8_7"; //pin 2 (1A, motor logic 1) on H-Bridge
    var motorPin2 = "P8_19"; //pin 7 (2A, motor logic 1) on H-Bridge
    var buttonPin = "P8_8"; //pin for button
    
    b.pinMode(enablePin, b.OUTPUT);
    b.pinMode(motorPin1, b.OUTPUT);
    b.pinMode(motorPin2, b.OUTPUT);
    
    b.pinMode(buttonPin, b.INPUT);
    
    
    function loop() {
        // if the button is high, motor will turn off
        if (b.digitalRead(buttonPin) == b.HIGH) {
            b.digitalWrite(enablePin, b.HIGH);
            b.digitalWrite(motorPin1, b.LOW); // set pin 2 on H-Bridge low
            b.digitalWrite(motorPin2, b.HIGH); // set pin 7 on H-Bridge high
        }
        // if the button is low, motor will turn on
        else {
            b.digitalWrite(enablePin, b.LOW);
            b.digitalWrite(motorPin1, b.LOW);
            b.digitalWrite(motorPin2, b.HIGH);
        }
    }
    
    setInterval(loop, 50);
  5. To start your engines, click on the Run button in the IDE. The motor should rotate when you press the button and stop when you release it.

How it works...


Here is some context for what's happening with the wiring:

  1. H-Bridge motor driver: Although our component can drive two motors (one on each side of the chip), in our example, we will only run one. Besides controlling the direction and speed, the motor driver also protects the BBB from the higher output needed to drive the motor. The name H-Bridge is derived from the way the circuit is typically drawn with four switches. When switch 1 (s1) and switch 4 (s4) are closed and switch 2 (s2) and switch 3 (s3) are open, then a positive voltage flows across the motor. To reverse the direction of the motor, the switches are then reversed from their open or closed state.

    In the following illustration, the image on the left-hand side shows the voltage flowing across s1 and s4 for one motor direction and on the right-hand side across s2 and s3 for the reverse direction. In our recipe's code, we will only turn the motor in one direction, so the voltage will only flow across one bridge circuit, as shown in the following image:

    How it works...


    Note

    The preceding image has been taken from Wikipedia.

    The H-bridge controller has 16 pins for interfacing, although only a few of them are used in our recipe:

    How it works...


    Pin outs on H-bridge

  2. DC power: Instead of powering from the BBB directly, we offload the power for the motor to a separate 9V battery source. This both ensures a reliable and consistent voltage to the motor and removes any possibility of damaging the board.

Servo motors

For those new to servomechanisms, commonly referred to as servos, it may be useful to understand the basics of the device because the ingredients in the recipe reveal the unique nature of this type of motor.

Servos are typically used as actuators in embedded electronics scenarios, such as CNC machinery, robotics, and automated manufacturing, and even for radio-controlled toys. For their size, these motors are incredibly powerful, deliver a considerable torque, and consume a small amount of power.

A servo is really just a motor with an output shaft connected to a sensor. The sensor provides feedback of a position to control the motor's motion and final position. The shaft is able to turn around 180 degrees.

In order to run properly, the servo requires a fairly robust controller. Communication between the servo and the controller can be either digital or analogue. On the BBB front, the servo requires PWM to send pulsed signals, which we discuss later in this section. The length of the pulse drives the position of the motor.

Regardless of the signal type, the input signal's purpose is to send data that determines the motor output shaft's position. In more sophisticated servos, the signal also includes data on the speed. However, in our recipe, we will use a low cost servo that is typically used in RC toys. These kinds of devices handle only shaft position.

Servos are also distinctive for their three wires:

  • Power (+5 volts): This is often red
  • Ground: This is sometimes black, but more often, this is brown in cheaper servos
  • Control: This is commonly yellow or white

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

DC motors

They're fun. They're cheap. They're everywhere. The little motors that have been driving toys for decades still remain a mainstay for projects where locomotion is part of the picture. Understanding how to drive a DC motor requires more complex and powerful mechanisms, such as robotics.

Getting ready

You will need several items for this recipe:

  • DC motor: This is a standard issue 2-lead motor prevalent in toys and cheaper RC devices.
  • H-Bridge IC motor driver: This Texas instrument component SN754410 is available at Sparkfun (https://www.sparkfun.com/products/315) and other similar sources for approximately 2.50 USD. It is also commonly used in the L293D version. This little circuit is an important piece of the puzzle because it is the mechanism used to send the voltage that drives the motor's direction and regulates its speed. More details about this IC are described later in this recipe.
    • 13x jumper wires
    • 1x pushbutton/switch
    • 1x 1k resistor
    • 9V battery and holder
    • Breadboard

How to do it...

Perform the following steps to test the DC motors:

  1. Make sure that your BBB is powered down first and then wire your breadboard as follows. Clearly, this is a thicket of wires, so be methodical as you follow the diagram:
    How to do it...

    To help with the diagram above, here are some further details for the wiring setup:

    Hardware

    Pin#

    Color

    Location/purpose

    BBB

    P8_7

    Blue

    Pin 2 (1A, motor logic 1) on H-bridge

    BBB

    P8_13

    Yellow

    Pin 1 (1,2EN/PWM) on H-bridge

    BBB

    P8_19

    Green

    Pin 7 (2A, motor logic 1) on H-bridge

    BBB

    P8_8

    Blue

    GND on breadboard button—aligned with 1k resistor

    BBB

    P9_1

    Black

    GND on breadboard rail

    BBB

    P9_7

    Red

    5V power to button

    Motor Wire 1

      

    Attached at pin 3 (1Y) on H-bridge

    Motor Wire 2

      

    Attached at pin 6 (2Y) on H-bridge

    Battery wire 1

    Black

    GND rail on breadboard

    Battery wire 2

    RED to PWR rail on breadboard

    Bus wire 1

    Black

    GND

    Bus wire 2

    Red

    VCC

  2. Open the Cloud9 IDE at http://192.168.7.2:3000 and navigate to File | New From Template | Javascript.
  3. Save the new file as DC_motor1.js.
  4. Paste the new document to the following BoneScript code:
    var b = require('bonescript');
    
    var enablePin = "P8_13"; //pin 1 (1,2EN/PWM) on H-Bridge
    var motorPin1 = "P8_7"; //pin 2 (1A, motor logic 1) on H-Bridge
    var motorPin2 = "P8_19"; //pin 7 (2A, motor logic 1) on H-Bridge
    var buttonPin = "P8_8"; //pin for button
    
    b.pinMode(enablePin, b.OUTPUT);
    b.pinMode(motorPin1, b.OUTPUT);
    b.pinMode(motorPin2, b.OUTPUT);
    
    b.pinMode(buttonPin, b.INPUT);
    
    
    function loop() {
        // if the button is high, motor will turn off
        if (b.digitalRead(buttonPin) == b.HIGH) {
            b.digitalWrite(enablePin, b.HIGH);
            b.digitalWrite(motorPin1, b.LOW); // set pin 2 on H-Bridge low
            b.digitalWrite(motorPin2, b.HIGH); // set pin 7 on H-Bridge high
        }
        // if the button is low, motor will turn on
        else {
            b.digitalWrite(enablePin, b.LOW);
            b.digitalWrite(motorPin1, b.LOW);
            b.digitalWrite(motorPin2, b.HIGH);
        }
    }
    
    setInterval(loop, 50);
  5. To start your engines, click on the Run button in the IDE. The motor should rotate when you press the button and stop when you release it.

How it works...


Here is some context for what's happening with the wiring:

  1. H-Bridge motor driver: Although our component can drive two motors (one on each side of the chip), in our example, we will only run one. Besides controlling the direction and speed, the motor driver also protects the BBB from the higher output needed to drive the motor. The name H-Bridge is derived from the way the circuit is typically drawn with four switches. When switch 1 (s1) and switch 4 (s4) are closed and switch 2 (s2) and switch 3 (s3) are open, then a positive voltage flows across the motor. To reverse the direction of the motor, the switches are then reversed from their open or closed state.

    In the following illustration, the image on the left-hand side shows the voltage flowing across s1 and s4 for one motor direction and on the right-hand side across s2 and s3 for the reverse direction. In our recipe's code, we will only turn the motor in one direction, so the voltage will only flow across one bridge circuit, as shown in the following image:

    How it works...


    Note

    The preceding image has been taken from Wikipedia.

    The H-bridge controller has 16 pins for interfacing, although only a few of them are used in our recipe:

    How it works...


    Pin outs on H-bridge

  2. DC power: Instead of powering from the BBB directly, we offload the power for the motor to a separate 9V battery source. This both ensures a reliable and consistent voltage to the motor and removes any possibility of damaging the board.

Servo motors

For those new to servomechanisms, commonly referred to as servos, it may be useful to understand the basics of the device because the ingredients in the recipe reveal the unique nature of this type of motor.

Servos are typically used as actuators in embedded electronics scenarios, such as CNC machinery, robotics, and automated manufacturing, and even for radio-controlled toys. For their size, these motors are incredibly powerful, deliver a considerable torque, and consume a small amount of power.

A servo is really just a motor with an output shaft connected to a sensor. The sensor provides feedback of a position to control the motor's motion and final position. The shaft is able to turn around 180 degrees.

In order to run properly, the servo requires a fairly robust controller. Communication between the servo and the controller can be either digital or analogue. On the BBB front, the servo requires PWM to send pulsed signals, which we discuss later in this section. The length of the pulse drives the position of the motor.

Regardless of the signal type, the input signal's purpose is to send data that determines the motor output shaft's position. In more sophisticated servos, the signal also includes data on the speed. However, in our recipe, we will use a low cost servo that is typically used in RC toys. These kinds of devices handle only shaft position.

Servos are also distinctive for their three wires:

  • Power (+5 volts): This is often red
  • Ground: This is sometimes black, but more often, this is brown in cheaper servos
  • Control: This is commonly yellow or white

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

Getting ready

You will need several items for this recipe:

  • DC motor: This is a standard issue 2-lead motor prevalent in toys and cheaper RC devices.
  • H-Bridge IC motor driver: This Texas instrument component SN754410 is available at Sparkfun (https://www.sparkfun.com/products/315) and other similar sources for approximately 2.50 USD. It is also commonly used in the L293D version. This little circuit is an important piece of the puzzle because it is the mechanism used to send the voltage that drives the motor's direction and regulates its speed. More details about this IC are described later in this recipe.
    • 13x jumper wires
    • 1x pushbutton/switch
    • 1x 1k resistor
    • 9V battery and holder
    • Breadboard

How to do it...

Perform the following steps to test the DC motors:

  1. Make sure that your BBB is powered down first and then wire your breadboard as follows. Clearly, this is a thicket of wires, so be methodical as you follow the diagram:
    How to do it...

    To help with the diagram above, here are some further details for the wiring setup:

    Hardware

    Pin#

    Color

    Location/purpose

    BBB

    P8_7

    Blue

    Pin 2 (1A, motor logic 1) on H-bridge

    BBB

    P8_13

    Yellow

    Pin 1 (1,2EN/PWM) on H-bridge

    BBB

    P8_19

    Green

    Pin 7 (2A, motor logic 1) on H-bridge

    BBB

    P8_8

    Blue

    GND on breadboard button—aligned with 1k resistor

    BBB

    P9_1

    Black

    GND on breadboard rail

    BBB

    P9_7

    Red

    5V power to button

    Motor Wire 1

      

    Attached at pin 3 (1Y) on H-bridge

    Motor Wire 2

      

    Attached at pin 6 (2Y) on H-bridge

    Battery wire 1

    Black

    GND rail on breadboard

    Battery wire 2

    RED to PWR rail on breadboard

    Bus wire 1

    Black

    GND

    Bus wire 2

    Red

    VCC

  2. Open the Cloud9 IDE at http://192.168.7.2:3000 and navigate to File | New From Template | Javascript.
  3. Save the new file as DC_motor1.js.
  4. Paste the new document to the following BoneScript code:
    var b = require('bonescript');
    
    var enablePin = "P8_13"; //pin 1 (1,2EN/PWM) on H-Bridge
    var motorPin1 = "P8_7"; //pin 2 (1A, motor logic 1) on H-Bridge
    var motorPin2 = "P8_19"; //pin 7 (2A, motor logic 1) on H-Bridge
    var buttonPin = "P8_8"; //pin for button
    
    b.pinMode(enablePin, b.OUTPUT);
    b.pinMode(motorPin1, b.OUTPUT);
    b.pinMode(motorPin2, b.OUTPUT);
    
    b.pinMode(buttonPin, b.INPUT);
    
    
    function loop() {
        // if the button is high, motor will turn off
        if (b.digitalRead(buttonPin) == b.HIGH) {
            b.digitalWrite(enablePin, b.HIGH);
            b.digitalWrite(motorPin1, b.LOW); // set pin 2 on H-Bridge low
            b.digitalWrite(motorPin2, b.HIGH); // set pin 7 on H-Bridge high
        }
        // if the button is low, motor will turn on
        else {
            b.digitalWrite(enablePin, b.LOW);
            b.digitalWrite(motorPin1, b.LOW);
            b.digitalWrite(motorPin2, b.HIGH);
        }
    }
    
    setInterval(loop, 50);
  5. To start your engines, click on the Run button in the IDE. The motor should rotate when you press the button and stop when you release it.

How it works...


Here is some context for what's happening with the wiring:

  1. H-Bridge motor driver: Although our component can drive two motors (one on each side of the chip), in our example, we will only run one. Besides controlling the direction and speed, the motor driver also protects the BBB from the higher output needed to drive the motor. The name H-Bridge is derived from the way the circuit is typically drawn with four switches. When switch 1 (s1) and switch 4 (s4) are closed and switch 2 (s2) and switch 3 (s3) are open, then a positive voltage flows across the motor. To reverse the direction of the motor, the switches are then reversed from their open or closed state.

    In the following illustration, the image on the left-hand side shows the voltage flowing across s1 and s4 for one motor direction and on the right-hand side across s2 and s3 for the reverse direction. In our recipe's code, we will only turn the motor in one direction, so the voltage will only flow across one bridge circuit, as shown in the following image:

    How it works...


    Note

    The preceding image has been taken from Wikipedia.

    The H-bridge controller has 16 pins for interfacing, although only a few of them are used in our recipe:

    How it works...


    Pin outs on H-bridge

  2. DC power: Instead of powering from the BBB directly, we offload the power for the motor to a separate 9V battery source. This both ensures a reliable and consistent voltage to the motor and removes any possibility of damaging the board.

Servo motors

For those new to servomechanisms, commonly referred to as servos, it may be useful to understand the basics of the device because the ingredients in the recipe reveal the unique nature of this type of motor.

Servos are typically used as actuators in embedded electronics scenarios, such as CNC machinery, robotics, and automated manufacturing, and even for radio-controlled toys. For their size, these motors are incredibly powerful, deliver a considerable torque, and consume a small amount of power.

A servo is really just a motor with an output shaft connected to a sensor. The sensor provides feedback of a position to control the motor's motion and final position. The shaft is able to turn around 180 degrees.

In order to run properly, the servo requires a fairly robust controller. Communication between the servo and the controller can be either digital or analogue. On the BBB front, the servo requires PWM to send pulsed signals, which we discuss later in this section. The length of the pulse drives the position of the motor.

Regardless of the signal type, the input signal's purpose is to send data that determines the motor output shaft's position. In more sophisticated servos, the signal also includes data on the speed. However, in our recipe, we will use a low cost servo that is typically used in RC toys. These kinds of devices handle only shaft position.

Servos are also distinctive for their three wires:

  • Power (+5 volts): This is often red
  • Ground: This is sometimes black, but more often, this is brown in cheaper servos
  • Control: This is commonly yellow or white

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

How to do it...

Perform the following steps to test the DC motors:

  1. Make sure that your BBB is powered down first and then wire your breadboard as follows. Clearly, this is a thicket of wires, so be methodical as you follow the diagram:
    How to do it...

    To help with the diagram above, here are some further details for the wiring setup:

    Hardware

    Pin#

    Color

    Location/purpose

    BBB

    P8_7

    Blue

    Pin 2 (1A, motor logic 1) on H-bridge

    BBB

    P8_13

    Yellow

    Pin 1 (1,2EN/PWM) on H-bridge

    BBB

    P8_19

    Green

    Pin 7 (2A, motor logic 1) on H-bridge

    BBB

    P8_8

    Blue

    GND on breadboard button—aligned with 1k resistor

    BBB

    P9_1

    Black

    GND on breadboard rail

    BBB

    P9_7

    Red

    5V power to button

    Motor Wire 1

      

    Attached at pin 3 (1Y) on H-bridge

    Motor Wire 2

      

    Attached at pin 6 (2Y) on H-bridge

    Battery wire 1

    Black

    GND rail on breadboard

    Battery wire 2

    RED to PWR rail on breadboard

    Bus wire 1

    Black

    GND

    Bus wire 2

    Red

    VCC

  2. Open the Cloud9 IDE at http://192.168.7.2:3000 and navigate to File | New From Template | Javascript.
  3. Save the new file as DC_motor1.js.
  4. Paste the new document to the following BoneScript code:
    var b = require('bonescript');
    
    var enablePin = "P8_13"; //pin 1 (1,2EN/PWM) on H-Bridge
    var motorPin1 = "P8_7"; //pin 2 (1A, motor logic 1) on H-Bridge
    var motorPin2 = "P8_19"; //pin 7 (2A, motor logic 1) on H-Bridge
    var buttonPin = "P8_8"; //pin for button
    
    b.pinMode(enablePin, b.OUTPUT);
    b.pinMode(motorPin1, b.OUTPUT);
    b.pinMode(motorPin2, b.OUTPUT);
    
    b.pinMode(buttonPin, b.INPUT);
    
    
    function loop() {
        // if the button is high, motor will turn off
        if (b.digitalRead(buttonPin) == b.HIGH) {
            b.digitalWrite(enablePin, b.HIGH);
            b.digitalWrite(motorPin1, b.LOW); // set pin 2 on H-Bridge low
            b.digitalWrite(motorPin2, b.HIGH); // set pin 7 on H-Bridge high
        }
        // if the button is low, motor will turn on
        else {
            b.digitalWrite(enablePin, b.LOW);
            b.digitalWrite(motorPin1, b.LOW);
            b.digitalWrite(motorPin2, b.HIGH);
        }
    }
    
    setInterval(loop, 50);
  5. To start your engines, click on the Run button in the IDE. The motor should rotate when you press the button and stop when you release it.

How it works...


Here is some context for what's happening with the wiring:

  1. H-Bridge motor driver: Although our component can drive two motors (one on each side of the chip), in our example, we will only run one. Besides controlling the direction and speed, the motor driver also protects the BBB from the higher output needed to drive the motor. The name H-Bridge is derived from the way the circuit is typically drawn with four switches. When switch 1 (s1) and switch 4 (s4) are closed and switch 2 (s2) and switch 3 (s3) are open, then a positive voltage flows across the motor. To reverse the direction of the motor, the switches are then reversed from their open or closed state.

    In the following illustration, the image on the left-hand side shows the voltage flowing across s1 and s4 for one motor direction and on the right-hand side across s2 and s3 for the reverse direction. In our recipe's code, we will only turn the motor in one direction, so the voltage will only flow across one bridge circuit, as shown in the following image:

    How it works...


    Note

    The preceding image has been taken from Wikipedia.

    The H-bridge controller has 16 pins for interfacing, although only a few of them are used in our recipe:

    How it works...


    Pin outs on H-bridge

  2. DC power: Instead of powering from the BBB directly, we offload the power for the motor to a separate 9V battery source. This both ensures a reliable and consistent voltage to the motor and removes any possibility of damaging the board.

Servo motors

For those new to servomechanisms, commonly referred to as servos, it may be useful to understand the basics of the device because the ingredients in the recipe reveal the unique nature of this type of motor.

Servos are typically used as actuators in embedded electronics scenarios, such as CNC machinery, robotics, and automated manufacturing, and even for radio-controlled toys. For their size, these motors are incredibly powerful, deliver a considerable torque, and consume a small amount of power.

A servo is really just a motor with an output shaft connected to a sensor. The sensor provides feedback of a position to control the motor's motion and final position. The shaft is able to turn around 180 degrees.

In order to run properly, the servo requires a fairly robust controller. Communication between the servo and the controller can be either digital or analogue. On the BBB front, the servo requires PWM to send pulsed signals, which we discuss later in this section. The length of the pulse drives the position of the motor.

Regardless of the signal type, the input signal's purpose is to send data that determines the motor output shaft's position. In more sophisticated servos, the signal also includes data on the speed. However, in our recipe, we will use a low cost servo that is typically used in RC toys. These kinds of devices handle only shaft position.

Servos are also distinctive for their three wires:

  • Power (+5 volts): This is often red
  • Ground: This is sometimes black, but more often, this is brown in cheaper servos
  • Control: This is commonly yellow or white

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

How it works...


Here is some context for what's happening with the wiring:

  1. H-Bridge motor driver: Although our component can drive two motors (one on each side of the chip), in our example, we will only run one. Besides controlling the direction and speed, the motor driver also protects the BBB from the higher output needed to drive the motor. The name H-Bridge is derived from the way the circuit is typically drawn with four switches. When switch 1 (s1) and switch 4 (s4) are closed and switch 2 (s2) and switch 3 (s3) are open, then a positive voltage flows across the motor. To reverse the direction of the motor, the switches are then reversed from their open or closed state.

    In the following illustration, the image on the left-hand side shows the voltage flowing across s1 and s4 for one motor direction and on the right-hand side across s2 and s3 for the reverse direction. In our recipe's code, we will only turn the motor in one direction, so the voltage will only flow across one bridge circuit, as shown in the following image:

    How it works...


    Note

    The preceding image has been taken from Wikipedia.

    The H-bridge controller has 16 pins for interfacing, although only a few of them are used in our recipe:

    How it works...


    Pin outs on H-bridge

  2. DC power: Instead of powering from the BBB directly, we offload the power for the motor to a separate 9V battery source. This both ensures a reliable and consistent voltage to the motor and removes any possibility of damaging the board.

Servo motors

For those new to servomechanisms, commonly referred to as servos, it may be useful to understand the basics of the device because the ingredients in the recipe reveal the unique nature of this type of motor.

Servos are typically used as actuators in embedded electronics scenarios, such as CNC machinery, robotics, and automated manufacturing, and even for radio-controlled toys. For their size, these motors are incredibly powerful, deliver a considerable torque, and consume a small amount of power.

A servo is really just a motor with an output shaft connected to a sensor. The sensor provides feedback of a position to control the motor's motion and final position. The shaft is able to turn around 180 degrees.

In order to run properly, the servo requires a fairly robust controller. Communication between the servo and the controller can be either digital or analogue. On the BBB front, the servo requires PWM to send pulsed signals, which we discuss later in this section. The length of the pulse drives the position of the motor.

Regardless of the signal type, the input signal's purpose is to send data that determines the motor output shaft's position. In more sophisticated servos, the signal also includes data on the speed. However, in our recipe, we will use a low cost servo that is typically used in RC toys. These kinds of devices handle only shaft position.

Servos are also distinctive for their three wires:

  • Power (+5 volts): This is often red
  • Ground: This is sometimes black, but more often, this is brown in cheaper servos
  • Control: This is commonly yellow or white

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

Servo motors

For those new to servomechanisms, commonly referred to as servos, it may be useful to understand the basics of the device because the ingredients in the recipe reveal the unique nature of this type of motor.

Servos are typically used as actuators in embedded electronics scenarios, such as CNC machinery, robotics, and automated manufacturing, and even for radio-controlled toys. For their size, these motors are incredibly powerful, deliver a considerable torque, and consume a small amount of power.

A servo is really just a motor with an output shaft connected to a sensor. The sensor provides feedback of a position to control the motor's motion and final position. The shaft is able to turn around 180 degrees.

In order to run properly, the servo requires a fairly robust controller. Communication between the servo and the controller can be either digital or analogue. On the BBB front, the servo requires PWM to send pulsed signals, which we discuss later in this section. The length of the pulse drives the position of the motor.

Regardless of the signal type, the input signal's purpose is to send data that determines the motor output shaft's position. In more sophisticated servos, the signal also includes data on the speed. However, in our recipe, we will use a low cost servo that is typically used in RC toys. These kinds of devices handle only shaft position.

Servos are also distinctive for their three wires:

  • Power (+5 volts): This is often red
  • Ground: This is sometimes black, but more often, this is brown in cheaper servos
  • Control: This is commonly yellow or white

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

A crash course in pulse width modulation

Pulse width modulation (PWM) is a way to send very fast on/off digital signal pulses to a pin. These pulses can be modulated in order to smoothly control certain kinds of device like. LEDs, audio components, and motors.

When coding a PWM-driven device or component, you are basically setting a pin HIGH or LOW in rapid succession. Often, you will find that three control parameters can be set:

  • Duty cycle: This is the percentage of time when the pin is HIGH or on over a specific span of time. In your code, you express duty cycle as a percentage. For example, 100 percent would be high power being applied and would be fully on. Whereas, a low duty cycle of 1 percent would result in low power since power is off for most of the cycle.
  • Period: This is the combined time it takes to complete an on/off cycle.
  • Frequency: In our case, frequency is how many times per second the pulse signal went ON (HIGH) and OFF (LOW). Taking the inverse of the period gives us the frequency. Getting the frequency setting right is crucial since some devices may not work properly if your setting is too high or too low.

    Working with servos comes with taking care with the power input into your board. Under no circumstance do a 5V draw to run the motor or you will likely meet Merlin's magic smoke. And nothing cuts BBB recipes down to size like magic smoke.

    Note

    Inside every servo, there is a potentiometer that provides feedback to the motor about its position on its 180-degree sweep.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

Getting ready

You'll need a few things for this recipe:

  • Servo: These small but mighty motors come in many varieties and price ranges. If you already have fancy ones in your kit, congratulations! If not, purchase either a standard or mini size because our recipe will work with both these sizes. AdaFruit and Sparkfun have vetted collections, although you can certainly get them cheaper on Amazon.
  • Resistor: 10,000 (10kΩ) version with brown/black/orange/gold bands
  • 6x jumper wires
  • Breadboard

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

How to do it...

  1. Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
    How to do it...
  2. Here are the details for the wiring if the diagram isn't clear:
    • Connect your 10k resistor to row 5 of your breadboard with the ends spanning the bridge. In this recipe, the resistor is not vital, but it is good practice to keep the voltage under control and protect the board if the servo is malfunctioning.
    • For the servo cable, attach three jumper wires and match them as follows:

      The brown servo lead (GND): This is the black jumper wire

      The red servo lead (PWR): This indicates the red jumper wire

      The orange (looks almost yellow) servo lead: This denotes the yellow jumper wire

    • Now, attach the second set of jumper wires to the BBB as follows:

      Connect one end of the GND (black wire) to the P9_1 pin on the BBB and the other end to the breadboard, following the diagram's position

      Connect one end of the 3V red wire to the P9_3 pin on the BBB and the other end to the breadboard, following the diagram's position

    • Now we'll hook up the yellow jumper wire, which we'll connect to our PWM output on the BBB. Connect one end to the 9_42 pin on the BBB and the other end to the breadboard in the same row and on the left-hand side of the resistor, following the diagram's position. We could also have used P9_14, P9_16, P8_13 or P8_19.
    • Finally, attach the servo + jumper wires to the breadboard as follows:

      GND black wire into the GND rail coming from the BBB

      3V red wire into the 3V power rail coming from the BBB

      PWM yellow wire into breadboard on the other side of the resistor

  3. Open the Cloud9 IDE at http://192.168.7.2:3000:

    Use the following code to begin firing up the servo. In order to control the PWM signal, we need to specify the period, run, and duty cycle. Here's the script to run the servo:

    #!/usr/bin/env node
    
    // Include the bonescript library
    var b = require('bonescript');
    
    // Servo motor's PWM pin
    var servo = 'P9_42';
    
    var duty_min = 0.03;
    var duty_max = 2.5;
    var position = 0;
    var increment = 0.1;
    
    // Set up the mode for the servo pin
    b.pinMode(servo, b.ANALOG_OUTPUT);
    updateDuty();
    
    console.log('Use keyboard Control-C to stop');
    
    function updateDuty() {
        // This function calculates and adjusts the duty cycle based on a desired position in range 0..1
        var duty_cycle = (position*0.115) + duty_min;
        b.analogWrite(servo, duty_cycle, 60, scheduleNextUpdate);
    
        console.log('Duty Cycle: ' + 
            parseFloat(duty_cycle*100).toFixed(1) + '%' + 'Position: ' + position);
            
    }
    
    function scheduleNextUpdate() {
        // adjust position by increment and 
        // reverse if it exceeds range of 0..1
        position = position + increment;
        if(position < 0) {
            position = 0;
            increment = -increment;
        } else if(position > 1) {
            position = 1;
            increment = -increment;
        }
        
        // call updateDuty after 500ms
        setTimeout(updateDuty, 500);
    
    }
  4. The motor will begin by first moving to a starting position, then move forward in small increments. Then, it will reset its starting point and begin moving backward in small increments. In the IDE terminal window, press Ctrl + C on your keyboard to stop the script.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

There's more…

To check your PWM pinmux, run the following commands:

$ sudo -i
# cat < /sys/kernel/debug/pwm

Your output should look something like this:

platform/48304100.ecap, 1 PWM device
 pwm-0   ((null)              ):

platform/48304200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48302200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

platform/48300100.ecap, 1 PWM device
 pwm-0   (PWM_P9_42           ): requested enabled

platform/48300200.ehrpwm, 2 PWM devices
 pwm-0   ((null)              ):
 pwm-1   ((null)              ):

Note that our referenced pin in our code that we just ran, P9_42, is marked as requested enabled.

For an alternative method of driving the servo using Python, check out Adafruit's tutorial at https://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black.

You have been reading a chapter from
BeagleBone: Creative Projects for Hobbyists
Published in: Jul 2017
Publisher: Packt
ISBN-13: 9781788395656
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime