Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Programming the BeagleBone

You're reading from  Programming the BeagleBone

Product type Book
Published in Jan 2016
Publisher
ISBN-13 9781784390013
Pages 180 pages
Edition 1st Edition
Languages

Table of Contents (21) Chapters

Programming the BeagleBone
Credits
About the Author
Acknowledgment
About the Reviewers
www.PacktPub.com
Preface
Cloud9 IDE Blinking Onboard LEDs Blinking External LEDs Controlling LED Using a Push Button Reading from Analog Sensors PWM – Writing Analog Information Internet of Things with BeagleBone Physical Computing in Python UART, I2C, and SPI Programming Internet of Things using Python GPIO Control in Bash BeagleBone Capes
Pinmux and the Device Tree Index

Chapter 6. PWM – Writing Analog Information

In the previous chapter, we read information from analog sensors. It is time to write information on analog devices like motors. Writing analog information is not that straightforward. The BeagleBone processor has a Pulse Width Modulation (PWM) subsystem that can write analog information on some specific GPIO pins. In this chapter, we will learn how PWM works and how it can be used to interface analog output devices. Then we will write a program to fade an LED and drive a servo motor using PWM. In this chapter, will cover the following topics:

  • What is PWM?

  • BeagleBone's PWM

  • Writing on analog components

  • Fading LED circuit setup

  • Program to fade in and fade out an LED

  • Micro servo motor circuit setup

  • Program to control micro servo motor

What is PWM?


Typically variable voltage is generated by analog circuits. Digital circuits generate only HIGH (3.3V) or LOW (0V) voltage. Digital microprocessors/microcontrollers cannot produce analog voltages themselves. They need a Digital to Analog Convertor (DAC). We have seen in the previous chapter that BeagleBone has a built-in ADC that converts captured analog voltage to a value. This raises our hope that BeagleBone might have a DAC to generate analog output voltage. But this is not true. Instead of providing a DAC, it uses a mechanism called PWM, which achieves similar results. Some of the GPIO digital pins are driven by BeagleBone's PWM subsystem. It can generate any voltage inside the 0V to 3.3V range on these pins.

Suppose that we have connected an analog output device DC motor to one of the GPIO pins on BeagleBone (with capacitor filter). The speed of a DC motor changes proportionally to the voltage applied. The more voltage applied, the higher the motor speed. The connected...

BeagleBone's PWM


PWM can be implemented via program. One can write a program with digitalWrite() and setInterval() to create the desired frequency and desired duty cycle. But context switching and interrupts will make it inaccurate. Also, it will keep the CPU busy. The correct solution is to support this functionality at hardware level inside the CPU. The BeagleBone CPU has a Pulse Width Modulation Subsystem (PWMSS), which allows the accurate creation of a PWM pattern without keeping the CPU busy. The CPU will be free to do other work while the PWM subsystem takes care of the PWM wave generation. This subsystem has control over only a few GPIO pins. It can switch output very fast on these pins and can control on/off timing. So, not all GPIO pins are capable of generating PWM.

PWMSS has a set of Time Base Counter (TBCNT) register and Output Compare Register (OCR) to generate the desired PWM pattern. OCRs are used to set the duty cycle. You can get detailed information about PWMSS in BeagleBone...

Writing on analog components


BoneScript provides the function analogWrite() to generate a PWM wave on any GPIO pin from the previous diagram. After a call to analogWrite(), the pin will generate PWM waves of a specified duty cycle. Here is the prototype of the analogWrite() function.

The code is as follows:

analogWrite(pin, value, [freq],[callback])

Where

pin – BeagleBone pin identifier string

value – duty cycle ratio of the PWM as value between 0 and 1

freq – frequency of PWM in Hz

callback – name of function which will be called automatically when analogWrite() finishes.

Here, freq and callback parameters are optional. If freq is not specified, the default value 2 kHz is used. The duty cycle ratio value is not taken as a percentage but as a ratio between 0 to 1. It is a ratio of time it was ON to period. We can get that by dividing the percentage value by 100. So, a 50% duty cycle will be 0.5 value. Sometimes, you need to read the datasheet of the analog output device to find out the correct...

Fading LED circuit setup


Though we have studied LEDs as digital devices, they are not actually digital devices. They emit light as per voltage put across them. If the voltage is high, they emit more light. If we provide an LED with a digital value, it will be ON or OFF. It will either light up with full brightness or not at all. If we provide intermediate values, it will still glow. But not with its full intensity. As we can apply any voltage between 0V to 3.3V using PWM on an LED now, we can change the brightness of the LED from lowest to highest and from highest to lowest. This will look like the LED is fading in and out.

The circuit setup is similar to what we did in Chapter 3, Blinking External LEDs to blink external LEDs. At that time, we used P8_10 as the GPIO pin. Now we are connecting the LED to pin P9_21, which supports the PWM. You will need an LED, 470Ω resistor and a breadboard to set up this circuit. Power off the board and attach components to BeagleBone as shown in the diagram...

Program to fade in and fade out LED


Write the following code in Cloud9 and save it as fadeLED.js. Run the program and you should see the LED fading in and out alternatively.

The code for fadeLED.js is as follows:

var b = require('bonescript');
var led = "P9_21";
var loopTime = 20;
var duty_cycle=0;
var increment = true;

var loopTimer = setInterval(fadeLED, loopTime);

function fadeLED()
{
    if(duty_cycle == 100 )
        increment = false;
    if(duty_cycle == 0)
        increment = true;

    if(increment == true)
        duty_cycle = duty_cycle + 1;
    else
        duty_cycle = duty_cycle - 1;

    console.log("duty_cycle = ",duty_cycle/100);
    b.analogWrite(led,duty_cycle/100);
}

Explanation

In Chapter 3, Blinking External LEDs we used the function digitalWrite() with a similar setup. Here, we are using the analogWrite() function. We are initializing the variable duty_cycle with a value of zero. We use the variable increment as a Boolean flag to keep track of fading in or fading out...

Micro servo motor circuit setup


We are going to control a micro servo motor. Servo motors are special types of DC motors tightly coupled with a feed-backing control circuit that positions a shaft in a precise angle. They are used where fast, accurate, and limited angle movement is needed, for example, robot arm movement and CNC machine. The position of the motor shaft can be controlled through PWM. There is no need for extra motor driver chip.

A micro servo motor can rotate 180 degrees. The frequency/period is specific as per the servo motor. A typical servo motor expects approximately a 20 millisecond period to drive the motor. A servo motor changes shaft angle as per pulse width. If the specified pulse width is 1 millisecond or less, it remains at angle zero. That translates to approximately 3% duty cycle. If the pulse width is 1.5 milliseconds, then the servo shaft will change to a 90 degree angle. If a 2 millisecond pulse is given, the servo shaft will be at a maximum 180 degrees. It...

Program to control a micro servo motor


Write the following code in Cloud9 and save it as microServo.js. Run the program and you should see the servo motor moving from 0 to 180 degrees to and fro.

The code for is microServo.js as follows:

var b = require('bonescript');
var servo = 'P9_14';
var duty_min = 3;
var loopTime = 5;
var angle = 0;
var increment = true;

b.pinMode(servo, b.OUTPUT);
var loopTimer = setInterval(updateAngle, loopTime);

function updateAngle(x)
{
   
    if(angle == 180 )
        increment = false;
    if(angle == 0)
        increment = true;

    if(increment == true)
        angle = angle + 1;
    else
        angle = angle - 1;
   
        var duty_cycle = (angle * 0.064) + duty_min;
    console.log("angle =",angle);
    console.log("duty cycle = ",duty_cycle);
    b.analogWrite(servo, duty_cycle/100, 60);
}

Explanation

In this program, we created loopTimer, which will increment/decrement the shaft angle by one degree. We know that we have a limit of 3% to 14.5% to drive...

Summary


In this chapter, we learned some theory about PWM. We saw that PWM is a way of creating analog values on digital pins. It can be used to drive analog output devices like motors, LEDs, speakers, and so on. We studied PWM waves and how a duty cycle can be used to control analog devices. BeagleBone has a special subsystem dedicated to generating PWM that work on subset of GPIO pins. Then we wrote a program to control the brightness of an LED via PWM. We also wrote a program to control the servo motor angle. Until now, we have done many physical computing exercises. Let's connect our BeagleBone to the Internet and control these physical components from the Internet. We will do this in next chapter. That will be our first step toward the Internet of Things (IoT).

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