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.
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.
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:
- Sparkfun's tutorial on Voltage, Current, Resistance, and Ohm's Law is one of the best for beginners and is available at https://learn.sparkfun.com/tutorials/voltage-current-resistance-and-ohms-law
- Collin Cunningham, formerly of Make magazine and now an Adafruiter, gives us the video version skinny at https://www.youtube.com/watch?v=-mHLvtGjum4
- A very handy online Ohm's law calculator tool is available at http://www.onlineconversion.com/ohms_law.htm
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.
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:
- One of the best pin-mapping guides is Eskimon's interactive overlay at http://eskimon.fr/beaglebone-black-gpio-interactive-map.
- The full expansion header layout is at http://elinux.org/Beagleboard:Cape_Expansion_Headers
- A more succinct diagram of GPIOs is available at http://stuffwemade.net/post/beaglebone-pinout-new.
- Collars that you can attach to the BBB that provide easy call outs for the GPIO pins is available at http://www.doctormonk.com/2014/01/beaglebone-black-collars.html.
- Take a look at how to use BeagleBone Black GPIOs at http://www.armhf.com/using-beaglebone-black-gpios/.
- A quick guide on how to pinmux is available at http://beaglebone.cameon.net/home/pin-muxing.
- Derek Molloy's Beaglebone: GPIO Programming on ARM Embedded Linux tutorial and video is another comprehensive and thoughtful introduction available at http://derekmolloy.ie/beaglebone/beaglebone-gpio-programming-on-arm-embedded-linux/.
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:
In the following image, you will see what a real-life LED actually looks like. Not so straightforward as looking at the symbol, right?
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:
- From our fritzing tool, here's the diagram we made for our wiring:
- Now, wire up your breadboard using the following steps:
- First, put the Ground wire into GND (P8_2) on the BBB.
- Then, insert the other wire to the P8_15 pin on the BBB.
- 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.
- 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.
- Open up Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledblink_LED.js
. - 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);
- 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. - 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";
- 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 and1
is equal to on:var state = 0;
- 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 anINPUT
(this would be used with a button) or anOUTPUT
. 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');
- 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 seenloop
function in Arduino scripts. However, JavaScript and the event-driven Node.js environment greatly simplifies the code, as follows:setInterval(blink, 500);
- Finally, we will define the
blink
function. The!
before thestate
value inverts the value, and as the LED begins with a0
(off) state (this isn't the same as0
changing to1
(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); }
- 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:
- In the Cloud9 IDE terminal window, open a new file window in the editor and name it
blink_LED.py
. - 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)
- Now, save the script.
- Click Run in the Cloud9 IDE. Your LED should begin blinking.
There's more…
You can find more support in these tutorials:
- Sparkfun's multipage tutorial on LEDs provides a top-notch further study at https://learn.sparkfun.com/tutorials/light-emitting-diodes-leds
- For a beginner, instructables delivers excellent and additional background on LEDs at http://www.instructables.com/id/LEDs-for-Beginners/
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:
- From our fritzing tool, here's the diagram we made for our wiring:
- Now, wire up your breadboard using the following steps:
- First, put the Ground wire into GND (P8_2) on the BBB.
- Then, insert the other wire to the P8_15 pin on the BBB.
- 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.
- 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.
- Open up Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledblink_LED.js
. - 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);
- 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. - 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";
- 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 and1
is equal to on:var state = 0;
- 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 anINPUT
(this would be used with a button) or anOUTPUT
. 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');
- 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 seenloop
function in Arduino scripts. However, JavaScript and the event-driven Node.js environment greatly simplifies the code, as follows:setInterval(blink, 500);
- Finally, we will define the
blink
function. The!
before thestate
value inverts the value, and as the LED begins with a0
(off) state (this isn't the same as0
changing to1
(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); }
- 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:
- In the Cloud9 IDE terminal window, open a new file window in the editor and name it
blink_LED.py
. - 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)
- Now, save the script.
- Click Run in the Cloud9 IDE. Your LED should begin blinking.
There's more…
You can find more support in these tutorials:
- Sparkfun's multipage tutorial on LEDs provides a top-notch further study at https://learn.sparkfun.com/tutorials/light-emitting-diodes-leds
- For a beginner, instructables delivers excellent and additional background on LEDs at http://www.instructables.com/id/LEDs-for-Beginners/
How to do it...
Now, let's begin with the following steps:
- From our fritzing tool, here's the diagram we made for our wiring:
- Now, wire up your breadboard using the following steps:
- First, put the Ground wire into GND (P8_2) on the BBB.
- Then, insert the other wire to the P8_15 pin on the BBB.
- 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.
- 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.
- Open up Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledblink_LED.js
. - 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);
- 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. - 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";
- 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 and1
is equal to on:var state = 0;
- 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 anINPUT
(this would be used with a button) or anOUTPUT
. 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');
- 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 seenloop
function in Arduino scripts. However, JavaScript and the event-driven Node.js environment greatly simplifies the code, as follows:setInterval(blink, 500);
- Finally, we will define the
blink
function. The!
before thestate
value inverts the value, and as the LED begins with a0
(off) state (this isn't the same as0
changing to1
(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); }
- 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:
- In the Cloud9 IDE terminal window, open a new file window in the editor and name it
blink_LED.py
. - 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)
- Now, save the script.
- Click Run in the Cloud9 IDE. Your LED should begin blinking.
There's more…
You can find more support in these tutorials:
- Sparkfun's multipage tutorial on LEDs provides a top-notch further study at https://learn.sparkfun.com/tutorials/light-emitting-diodes-leds
- For a beginner, instructables delivers excellent and additional background on LEDs at http://www.instructables.com/id/LEDs-for-Beginners/
Writing an alternative script with Python
Starting from step 3, here's the Python version of the recipe that uses the Adafruit library:
- In the Cloud9 IDE terminal window, open a new file window in the editor and name it
blink_LED.py
. - 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)
- Now, save the script.
- Click Run in the Cloud9 IDE. Your LED should begin blinking.
You can find more support in these tutorials:
- Sparkfun's multipage tutorial on LEDs provides a top-notch further study at https://learn.sparkfun.com/tutorials/light-emitting-diodes-leds
- For a beginner, instructables delivers excellent and additional background on LEDs at http://www.instructables.com/id/LEDs-for-Beginners/
There's more…
You can find more support in these tutorials:
- Sparkfun's multipage tutorial on LEDs provides a top-notch further study at https://learn.sparkfun.com/tutorials/light-emitting-diodes-leds
- For a beginner, instructables delivers excellent and additional background on LEDs at http://www.instructables.com/id/LEDs-for-Beginners/
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...
- Wire your board and breadboard in the following manner:
- 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.
- Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
- 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.
- 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.
- 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.
- 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
- 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:
- Now, open your Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledbutton-led.js
. - 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 anINPUT
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); }
- Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
- 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...
- Wire your board and breadboard in the following manner:
- 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.
- Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
- 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.
- 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.
- 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.
- 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
- 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:
- Now, open your Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledbutton-led.js
. - 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 anINPUT
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); }
- Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
- 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...
- Wire your board and breadboard in the following manner:
- 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.
- Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
- 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.
- 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.
- 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.
- 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
- 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:
- Now, open your Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledbutton-led.js
. - 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 anINPUT
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); }
- Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
- 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...
- Wire your board and breadboard in the following manner:
- 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.
- Insert a red wire into the 3V slot at P9_3 and the other end into the power rail on the breadboard.
- 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.
- 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.
- 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.
- 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
- 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:
- Now, open your Cloud9 IDE at
http://192.168.7.2:3000
and create a new file calledbutton-led.js
. - 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 anINPUT
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); }
- Before running the code, let's look at how the script breaks down. First, as always, evoke the BoneScript library with the following code:
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
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
- 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"); }
- 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"); }
- Evoke the BoneScript library:
- 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
- More support for analog inputs can be found at Reading the analog inputs—http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
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...
- Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
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
- 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"); }
- 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"); }
- Evoke the BoneScript library:
- 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
- More support for analog inputs can be found at Reading the analog inputs—http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
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...
- Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
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
- 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"); }
- 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"); }
- Evoke the BoneScript library:
- 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
- More support for analog inputs can be found at Reading the analog inputs—http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
How to do it...
- Make sure your BBB is powered down first, then wire up your breadboard. Here's what your wiring should look like:
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
- 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"); }
- 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"); }
- Evoke the BoneScript library:
- 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
- More support for analog inputs can be found at Reading the analog inputs—http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
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
- More support for analog inputs can be found at Reading the analog inputs—http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
See also
- More support for analog inputs can be found at Reading the analog inputs—http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
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…
- First, make sure your BBB is powered down, then wire up your breadboard. Here's what your wiring should look like:
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.
- Open up Cloud9 IDE at
http://192.168.7.2:3000
. - 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);
- 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
- 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); }
- 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:
- Download the Python code with the following command:
$ git clone https://github.com/HudsonWerks/light-sensor.git
- 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…
- First, make sure your BBB is powered down, then wire up your breadboard. Here's what your wiring should look like:
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.
- Open up Cloud9 IDE at
http://192.168.7.2:3000
. - 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);
- 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
- 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); }
- 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:
- Download the Python code with the following command:
$ git clone https://github.com/HudsonWerks/light-sensor.git
- 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…
- First, make sure your BBB is powered down, then wire up your breadboard. Here's what your wiring should look like:
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.
- Open up Cloud9 IDE at
http://192.168.7.2:3000
. - 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);
- 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
- 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); }
- 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:
- Download the Python code with the following command:
$ git clone https://github.com/HudsonWerks/light-sensor.git
- 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:
- 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:
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
- Open the Cloud9 IDE at
http://192.168.7.2:3000
and navigate to File | New From Template | Javascript. - Save the new file as
DC_motor1.js
. - 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);
- 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:
- 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:
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:
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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:
- 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:
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
- Open the Cloud9 IDE at
http://192.168.7.2:3000
and navigate to File | New From Template | Javascript. - Save the new file as
DC_motor1.js
. - 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);
- 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:
- 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:
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:
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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:
- 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:
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
- Open the Cloud9 IDE at
http://192.168.7.2:3000
and navigate to File | New From Template | Javascript. - Save the new file as
DC_motor1.js
. - 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);
- 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:
- 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:
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:
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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:
- 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:
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
- Open the Cloud9 IDE at
http://192.168.7.2:3000
and navigate to File | New From Template | Javascript. - Save the new file as
DC_motor1.js
. - 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);
- 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:
- 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:
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:
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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:
- 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:
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:
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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...
- Make sure your BBB is powered down first, then wire up your breadboard according to the following fritzing diagram:
- 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
- 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); }
- 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.