(For more resources related to this topic, see here.)
PWM allows us to drive a certain pin to on and off at desired frequency and duty cycle. This way we can pulse our LEDs much faster than our eyes can react, and while we only see a dimmer or a brighter LED, if one would look at it with a high speed camera, one would see that the LED still only turns on or off. Our eyes just perceive this differently.
There are three basic terms you need to understand about PWM:
- Frequency: This defines how many full on/off "cycles" are generated in a second
- Period: This defines how long one complete pulse cycle takes
- Duty cycle: This specifies the time the signal is high during one full period
Think about the following figure:
In the preceding figure, we have PWM generating first a 50 percent duty cycle and then dropping to 25 percent. The effective time the LED spends as on and off can be controlled with very high precision, and this way we can achieve smooth brightness fluctuations.
Let's try doing just that. First, we will design a schematic with two LEDs that are connected to two different PWMs. Nothing fancy here either really, we have a current limiting resistor after the LEDs and that's it.
This time we will be using input from both headers, as PWM1 and PWM2 are located on P9 and P8, respectively.
Our third and last program in this article will be called racing_PWMs.py. As usual, we need to include the Adafruit library here as well, this time the PWM part of it:
import Adafruit_BBIO.PWM as PWM
When you initialize a PWM, you can initialize it with two to four parameters listed as follows:
- Channel (header pin)
- Duty (as in percent, 0-100)
- Frequency (periods in a second, default is 2000)
- And polarity (0 or 1. With this you can invert the duty cycle, default is 0)
So, we will initialize both our channels:
PWM.start("P9_14", 50, 100) #50% duty and 100hz cycle PWM.start("P8_13", 50, 100)
At this point, the LEDs will light up, and now we can start changing our duty cycle in a loop to adjust the average voltage.
Full listing of racing_PWMs.py is as follows:
#!/usr/bin/python import time import Adafruit_BBIO.PWM as PWM sleep_time=0.005 #The lower the value the faster the activity PWM.start("P9_14", 50, 100) #50% duty and 100hz cycle PWM.start("P8_13", 50, 100) while True: for i in range(100,1, -1): PWM.set_duty_cycle("P9_14", i) # Dimming PWM.set_duty_cycle("P8_13", abs(i-100)+1) # Getting brighter time.sleep(sleep_time) for i in range(1, 100): PWM.set_duty_cycle("P9_14", i) PWM.set_duty_cycle("P8_13", abs(i-100)+1 ) time.sleep(sleep_time)
When you run the program, you should see both LEDs racing (blinking) in opposite phases.
As you see, the Adafruit BBIO library is extremely useful and easy to use. And so far we have only used two functionalities it provides. Actually, the library also supports easy access to SPI and I2C communication and Analog to Digital Converter(ADC) as well.
In this article we went through foundations of input and output on a very basic level. We talked about the general purpose I/O pins, and how they can be used to control external components, such as LEDs or buttons. As you must have gathered already, with proper application of voltage and care, we can operate many of the basic electronic components. You should now feel comfortable with the basic building blocks that can help you build some external inputs and outputs to your Beagle programs.
Resources for Article:
- Home Security by BeagleBone [Article]
- Introducing BeagleBoard [Article]
- Viewing on Mobile Devices [Article]