shows how to connect a tactile push switch, using a breadboard and jumper wires.
29 |
30 |
31 | Connecting a push switch to a Raspberry Pi
32 |
33 |
34 |
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called switch.py.
35 |
36 |
This example code displays a message when the button is pressed:
You will notice that the switch is wired so that when it is pressed, it will connect pin 18 configured as an input to GND. The input pin is normally pulled up to 3.3V by the optional argument pull_up_down=GPIO.PUD_UP in GPIO.setup. This means that when you read the input value using GPIO.input, False will be returned if the button is pressed. This is a little counterintuitive.
66 |
67 |
Each GPIO pin has software configurable pull-up and pull-down resistors. When using a GPIO pin as an input, you can configure these resistors so that one or either or neither of the resistors is enabled, using the optional pull_up_down parameter to GPIO.setup. If this parameter is omitted, then neither resistor will be enabled. This leaves the input floating, which means that its value cannot be relied upon and it will drift between high and low depending on what it picks up in the way of electrical noise.
68 |
69 |
If it is set to GPIO.PUD_UP, the pull-up resistor is enabled; if it is set to GPIO.PUD_DOWN, the pull-down resistor is enabled.
70 |
71 |
You might expect the push switch to have just two connections, which are either open or closed. While some of these tactile push switches do have just two connections, most have four. shows how these connections are arranged.
You want to know how to connect an LED to the Raspberry Pi.
Solution
Connect an LED (see “Opto-Electronics”) to one of the GPIO pins using a 470Ω or 1kΩ series resistor (see “Resistors and Capacitors”) to limit the current. To make this recipe, you will need:
shows how you can wire this using solderless breadboard and male-to-female jumper leads.
Connecting an LED to a Raspberry Pi
Having connected the LED, we need to be able to turn it on and off using commands from Python. To do this, follow “Installing RPi.GPIO” to install the RPi.GPIO Python library.
Start a Python console (“Using the Python Console”) from the Terminal with superuser access and enter these commands:
LEDs are a very useful, cheap, and efficient way of producing light, but you do have to be careful how you use them. If they are connected directly to a voltage source (such as a GPIO output) that is greater than about 1.7 volts, they will draw a very large current. This can often be enough to either destroy the LED or whatever is providing the current—which is not good if your Raspberry Pi is providing the current.
You should always use a series resistor with an LED because the series resistor is placed between the LED and the voltage source, which limits the amount of current flowing through the LED to a level that is safe for both the LED and the GPIO pin driving it.
Raspberry Pi GPIO pins can only provide about 3 mA of current. LEDs will generally illuminate with any current greater than 1 mA, but will be brighter with more current. Use as a guide to selecting a series resistor based on the type of LED; the table also indicates the approximate current that will be drawn from the GPIO pin.
Selecting series resistors for LEDs and a 3.3V GPIO pin
Red
470Ω
3.5
Red
1kΩ
1.5
Orange, yellow, green
470Ω
2
Orange, yellow, green
1kΩ
1
Blue, white
100Ω
3
Blue, white
270Ω
1
As you can see, in all cases, it is safe to use a 470Ω resistor. If you are using a blue or white LED, you can reduce the value of the series resistor considerably. If you want to play it safe, use 1kΩ.
If you wanted to extend the experiments that you made in the Python console into a program that makes the LED blink on and off repeatedly, you could paste the following code into the IDLE (“Editing Python Programs with IDLE”) or nano (“Editing a File”) editors. Save the file as led_blink.py. You can also download the program from the Raspberry Pi Cookbook website. Follow the link to this book and then the Downloads section.
You want to use a Raspberry Pi to control the position of a servo motor.
Solution
Use PWM to control the width of pulses to a servo motor to change its angle. Although this will work, the PWM generated is not completely stable, so there will be a little bit of jitter with the servo.
You should also power the servo from a separate 5V power supply because peaks in the load current are likely to crash or overload the Raspberry Pi.
12 | 5V 1A power supply or 4.8V battery pack (see “Miscellaneous”)
13 |
The breadboard layout for this is shown in .
Controlling a servo motor
The 1kΩ resistor is not essential, but it does protect the GPIO pin from unexpectedly high currents in the control signal, which could occur if a fault developed on the servo.
The leads of the servo may not be the same as the colors indicated in . It is common for the 5V wire to be red, the ground brown, and the control lead orange.
You can, if you prefer, power the servo from a battery pack rather than a power supply. Using a four-cell AA battery holder with rechargeable batteries will provide around 4.8V and work well with a servo. Using four alkali AA cells to provide 6V will be fine for many servos, but check the datasheet of your servo to make sure it is OK with 6V.
The user interface for setting the angle of the servo is based on the gui_slider.py program intended for controlling the brightness of an LED (“Controlling the Brightness of an LED”). However, you can modify it so that the slider sets the angle, between 0 and 180 degrees ().
User interface for controlling a servo motor
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called servo.py.
Note that this program uses a graphical user interface, so you cannot run it from SSH.
You must run it from the windowing environment on the Pi itself or via remote control using VNC (“Controlling the Pi Remotely with VNC”). You also need to run it as superuser, so run it with the command sudo python servo.py:
Servo motors are used in remote control vehicles and robotics. Most servo motors are not continuous; that is, they cannot rotate all the way around but rather just over an angle of about 180 degrees.
The position of the servo motor is set by the length of a pulse. The servo expects to receive a pulse at least every 20 milliseconds. If that pulse is high for 1 millisecond, the servo angle will be zero; if it is 1.5 milliseconds, it will be at its center position; and if it is 2 milliseconds, it will be at 180 degrees ().
Servo motors
The example program sets the PWM frequency to 100 Hz, which will send a pulse to the servo every 10 milliseconds. The angle is converted into a duty cycle between 0 and 100. This actually produces pulses shorter than the 1 millisecond expected minimum value and longer than 2 milliseconds maximum.
See Also
If you have a lot of servos to control, or require greater stability and precision, then you can use a dedicated servo controller module, as described in “Controlling a Large Number of Servo Motors”.
You need to connect electronics to the GPIO connector, but you need to know more about what all the pins do.
Solution
shows the GPIO pinout for both revisions 1 and 2 of the Raspberry Pi Model B. The quick way to tell the boards apart is that if you have an older revision 1 board, it has a black audio socket. The revision 2 boards have a blue audio socket.
The GPIO pinout
There were three changes to the GPIO connector between revision 1 and revision 2. These are highlighted in bold in . First, the I2C port was swapped. The two pins SDA and SCL are still SDA and SCL but use a different internal I2C interface. This means that if you’re using the pins as GPIO rather than I2C, then you will refer to them as 2 and 3 on a revision 2 board. Also, GPIO 21 was replaced by GPIO 27 on revision 2.
At the top of the connector, there are 3.3V and 5V power supplies. The GPIO uses 3.3V for all inputs and outputs. Any pin with a number next to it can act as a GPIO pin. Those that have another name after them also have some other special purpose, so 14 TXD and 15 RXD are the transmit and receive pins of the serial interface. SDA and SCL form the I2C interface, and MOSI, MISO, and SCKL from the SPI interface.
Discussion
A GPIO pin can be used as either a digital input or a digital output, and both operate at 3.3V. Unlike the Arduino, the Raspberry Pi does not have any analog inputs. For that you must use an external analog-to-digital converter (ADC) or connect the Pi to an interface board (like the Gertboard) or to an Arduino or an aLaMode board, as discussed in Chapter 14.
At the time of writing, this installs version 1.0.1, which is not the latest version but will suit the Arduino Uno; it will not, however, work for newer boards like the Leonardo and Due. They can still be used with the Raspberry Pi, but you will need some other computer to program them before connecting them to the Raspberry Pi.
After installation, you will find an Electronics group in your Programs menu ().
The Arduino IDE running on Raspberry Pi
The Arduino IDE connects to the Raspberry Pi through its USB cable to program it. This connection also requires that the serial console be disabled. You can follow “Freeing the Serial Port” to do this, but a second option is to run a script created by Kevin Osborn that both disables the serial console and configures the serial ports and Arduino profiles necessary to get things running. This has the advantage that it also sets up the aLaMode board to be ready for use (“Getting Started with an aLaMode Board and a Raspberry Pi”).
To download and run this script, follow these steps:
If you have not previously disabled your serial console and are relying on the preceding script to do it, then you will need to reboot for this change to take effect.
$ sudo reboot
You can now connect your Arduino to your Raspberry Pi. From the Tools menu, select Board and set the board type to Arduino Uno. Then, from the Serial Port option, select /dev/ttyACM0. To upload a test program that will make the LED on the Arduino blink, select the File menu and then click "Examples, Basic," and finally click Blink. Click on the right-arrow on the toolbar to begin the compile and upload process. If all is well, you should see a "Done Uploading" message in the status area at the bottom of the IDE window.
If you find that the device ttyACM0 is not listed even though your Arduino is plugged in, try restarting the Arduino IDE. If that doesn’t work, then you may have to reboot your Raspberry Pi. Leave the Arduino connected while you reboot and restart the Arduino IDE.
Discussion
To get the most out of using Arduino with Raspberry Pi, you need to learn a little Arduino programming. You may find the book Programming Arduino: Getting Started with Sketches (McGraw-Hill/Tab Books), by yours truly, helpful.
You want to convert your Raspberry Pi into a high-powered FM transmitter that will send a radio signal to a normal FM radio receiver ().
Solution
The clever folks at Imperial College London have created some C code and a Python wrapper that allow you to do just this. The download even includes the theme from Star Wars to play as a sample.
All you need is a short length of wire attached to GPIO pin 4. A female-to-male header lead will work just fine for this. In fact, it should work with the radio right next to your Pi without any kind of antenna—such is the strength of the transmission.
Raspberry Pi as an FM transmitter
The first step is to install the pifm library using the following commands:
$ mkdir pifm
6 | $ cd pifm
7 | $ wget http://www.icrobotics.co.uk/wiki/images/c/c3/Pifm.tar.gz
8 | $ tar -xzf Pifm.tar.gz
Next, find yourself an FM radio receiver and tune it to 103.0 MHz. If this frequency is already occupied by some other transmission, pick another frequency and make note of it.
Now run the following command (changing the final parameter from 103.0 to a different frequency if you had to change frequency):
sudo ./pifm sound.wav 103.0
If all is well, you should hear the stirring tones of the Star Wars theme.
Discussion
You need to know that this project may not be legal in your country. The power output is higher than that of FM transmitters used with MP3 players.
You can play other .wav files, but they must be 16-bit 44.1kHz mono.
The code also includes a Python library that you can use within your own Python programs. So, you could write yourself a user interface to allow the selection and playing of tunes.
The following fragment of code illustrates the use of the Python interface:
pi@raspberrypi ~/pifm $ sudo python
9 | Python 2.7.3 (default, Jan 13 2013, 11:20:46)
10 | [GCC 4.6.3] on linux2
11 | Type "help", "copyright", "credits" or "license" for more information.
12 | >>> import PiFm
13 | >>> PiFm.play_sound("sound.wav")
Were you to put a Raspberry Pi in your vehicle, this would be a great way of outputting sound through the vehicle’s audio system.
You want to connect a variable resistor to a Raspberry Pi and measure the position of its rotation.
Solution
You can measure resistance on a Raspberry Pi using nothing more than a capacitor, a couple of resistors, and two GPIO pins. In this case, you will be able to read the position of the knob on a small variable resistor (trimpot).
shows the arrangement of components on the breadboard.
Measuring resistance on a Raspberry Pi
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called pot_step.py.
The reading will vary between about 10 and about 170 as you rotate the knob of the trimpot.
Discussion
To explain how this program works, I first need to explain how the step response technique can be used to measure the resistance of the variable resistor.
shows the schematic diagram for the recipe.
Measuring resistance using step response
This way of doing things is called step response because it works by seeing how the circuit responds from the step change when an output is switched from low to high.
You can think of a capacitor as a tank of electricity, and as it fills with charge, the voltage across it increases. You can’t measure that voltage directly, because the Raspberry Pi doesn’t have an ADC converter. However, you can time how long it takes for the capacitor to fill with charge to the extent that it gets above the 1.65V or so that constitutes a high digital input. The speed at which the capacitor fills with charge depends on the value of the variable resistor (Rt). The lower the resistance, the faster the capacitor fills with charge and the voltage rises.
To be able to get a good reading, you must also be able to empty the capacitor each time before you take a reading. In , connection A is used to charge the capacitor through Rc and Rt, and connection B is used to discharge (empty) the capacitor through Rd. The resistors Rc and Rd are used to make sure that there is no way too much current can flow as the capacitor is charged and discharged.
The steps involved in taking a reading are first to discharge the capacitor through Rd and then to let it charge through Rc and Rt.
To discharge it, connection A (GPIO 18) is set to be an input, effectively disconnecting Rc and Rt from the circuit. Connection B (GPIO 23) is then set to be an output and low. This is held there for 5 milliseconds to empty the capacitor.
Now that the capacitor is empty, you can start to allow charge to flow into it by setting connection B to be an input (effectively disconnecting it) and then enabling connection A to be a high output at 3.3V. Capacitor C will now begin to charge through Rc and Rt. The while loop will then simply count as fast as possible until the voltage at connection B switches from being low to high at about 1.65V.
At that point, the counting stops and the count value is returned.
shows how a resistor and capacitor in this kind of arrangement charge and discharge as the voltage is toggled between high and low.
Charging and discharging a capacitor
You can see that the voltage at the capacitor increases rapidly at first but then tails off as the capacitor becomes full. Fortunately, you are interested in the area of the curve up until the capacitor reaches about 1.65V, which is a fairly straight line, meaning that the time taken for the voltage across the capacitor to rise to this point is roughly proportional to the resistance of Rt and hence the position of the knob.
This approach is not hugely accurate, but it is very low cost and easy to use.
See Also
Using a step response works well with all kinds of resistive sensors for light (“Measuring Light”) and even gas detection (“Detecting Methane”).
For more accurate measurements of the trimpot position, see “Measuring a Voltage”, where the pot is used with an ADC converter.
8 | Adafruit 4 × 7-segment LED with I2C backpack (see “Modules”)
9 |
shows the arrangement of components on the breadboard.
The breadboard layout for an LED display with Raspberry Pi
For this recipe to work, you will also need to set up your Raspberry Pi for I2C, so follow “Setting up I2C” first.
The display has an accompanying Python library written by Adafruit. It isn’t installed as a proper library, so to use it, you first need to download the folder structure. If you do not have Git installed, install it now with the following command (see “Fetching Source Code with git”).
$ sudo apt-get install git
Now, you can download the folder structure from GitHub:
$ cd Adafruit-Raspberry-Pi-Python-Code
10 | $ cd Adafruit_LEDBackpack
In this folder, you will find a test program that will display the time. Run it using the command:
$ sudo python ex_7segment_clock.py
Discussion
If you open the example file ex_7segment_clock.py in nano, you’ll see that the key commands are:
from Adafruit_7Segment import SevenSegment
which import the library code into your program. You then need to create a instance of SevenSegment using the next line of code. The address supplied as an argument is the I2C address (see “Setting up I2C”).
Every I2C slave device has an address number. The LED board has three pairs of solder pads on the back that can be bridged with solder if you want to change the address. This is essential if you need to operate more than one of the displays from a single Raspberry Pi.
segment = SevenSegment(address=0x70)
To actually set the contents of a particular digit, use a line like this one:
segment.writeDigit(0, int(hour / 10))
The first argument (0) is the digit position. Note that these positions are 0, 1, 3, and 4. Position 2 is reserved for the two dots in the center of the display.
The RaspiRobot board uses the power supply directly from its DC socket as the supply to the motor and regulates that same supply down to 5V to drive the Raspberry Pi. So in this case, the 12V power will be supplying both the 12V stepper motor and the Raspberry Pi.
The Raspberry Pi should not be powered through its USB connection when the RaspiRobot board is also powered, or slight differences in the 5V from the Raspberry Pi USB and the 5V regulated supply from the RaspiRobot board could cause large currents to flow and damage either the board or the Raspberry Pi. Power one board or the other, but not both.
Connect the stepper motor and power supply to the RaspiRobot board as shown in . The wire colors for the Adafruit 12V stepper motor are in order, from nearest the DC socket: yellow, red, grey, and green.
Using a RaspiRobot board to control a bipolar stepper motor
With a little modification to the pin allocations and step sequence, we can use the program from “Using a Bipolar Stepper Motor” with a RaspiRobot board.
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called stepper_rrb.py. This program uses the command line, so you can run it from SSH.
If you’re using Python 3, change the command raw_input to just input:
The RaspiRobot board uses the L293D in a different arrangement from how you used it in “Controlling the Direction of a DC Motor”, as it uses a pin to enable each channel (pins 17 and 10), and a second pair of pins that controls the direction of each motor (pins 4 and 25). This means that as well as changing the pin allocations, you also need to modify the step sequence to:
forward_seq = ['1011', '1111', '1110', '1010']
The first and third bit of each part of the sequence are always 1, enabling both motors. It is now only the second and fourth bits that control the polarity of each of the two stepper windings.
See Also
You can find out more about the RaspiRobot board and other projects that use it at the RaspiRobot website.
You want to control lots of LEDs using as few GPIO pins as possible.
Solution
The way to do this is to use a technique called Charlieplexing. The name comes from the inventor, Charlie Allen of the company Maxim, and the technique takes advantage of the feature of GPIO pins that allows them to be changed from outputs to inputs while a program is running. When a pin is changed to be an input, not enough current will flow through it to light an LED or influence other pins connected to the LED that are set as outputs.
shows the arrangement for controlling six LEDs with three pins.
Charlieplexing
shows the breadboard layout for the LEDs and resistors.
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called charlieplexing.py.
This example code prompts you to enter a number between 0 and 5 and then lights one of the six LEDs:
To understand how Charlieplexing works, imagine that you want to light LED A in . An LED will only light when its positive lead is high, and its negative lead is low. If the voltage is the other way around, it will not light. To light LED A, you need its lead connected to GPIO 18 (via a resistor) to be high and the other lead to LED A, connected to GPIO 23 by a resistor, to be low. However, you must also make sure that GPIO 24 is set to be an input; otherwise, LED C or D will also light depending on whether GPIO 24 is high or low.
The array pin_led_states holds the settings for each GPIO for each of the six LEDs. If the value is 0, the pin is low; 1 means high and -1 means set to be an input.
The number of LEDs that can be controlled per GPIO pin is given by the formula:
LEDs = n2 - n
Using 4 pins, we can have 16, 4, or 12 LEDs, whereas 10 pins would give you a massive 90 LEDs.
In this example, you’re lighting only one LED at a time. To light more than one at a time, you need to run a refresh loop that keeps the desired state of the LEDs in an array and refreshes the display, turning on the LEDs that need to be on before moving on to the next. It must do this sufficiently fast so that it appears that more than one of the LEDs is on at the same time.
The more LEDs you use when it comes to making it appear that more than one LED is on at a time, the less time the LED will actually be lit, and the dimmer the LEDs will become.
See Also
For more information about Charlieplexing, see Wikipedia. If you are interested in using only a single LED, see “Connecting an LED”.