Skip to content

Commit 729c98c

Browse files
committed
Merge branch 'master' into motors
2 parents 0c26812 + b823e1c commit 729c98c

File tree

11 files changed

+487
-35
lines changed

11 files changed

+487
-35
lines changed

analogue.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Analogue Inputs
2+
3+
The Raspberry Pi's GPIO pins are digital pins, so you can only set outputs to high or low, or read inputs as high or low. However, using an ADC chip (Analogue-to-Digital converter), you can read the value of analogue input devices such as potentiometers.
4+
5+
## SPI
6+
7+
The analogue values are communicated to the Pi using the SPI protocol. While this will work in GPIO Zero out of the box, you may get better results if you enable full SPI support.
8+
9+
1. Open a terminal window and install the `spidev` package:
10+
11+
```bash
12+
sudo apt-get install python3-spidev python-spidev
13+
```
14+
15+
1. Open the **Raspberry Pi Configuration** dialogue from the main menu and enable **SPI** in the **Interfaces** tab:
16+
17+
![Enable SPI](images/rcgui.png)
18+
19+
1. Click **OK** and reboot the Pi.
20+
21+
## Wiring the ADC (MCP3008)
22+
23+
The MCP3008 is an ADC providing eight input channels. The eight connectors on one side are connected to the Pi's GPIO pins, and the other eight are available to connect analogue input devices to read their values.
24+
25+
Place the MCP3008 chip on a breadboard and carefully wire it up as shown in the following diagram:
26+
27+
![MCP3008 wiring](images/mcp3008.png)
28+
29+
Alternatively, you could use the [Analog Zero](http://rasp.io/analogzero/) board, which provides the MCP3008 chip on a handy add-on board to save you from the complicated wiring.
30+
31+
## Add a potentiometer
32+
33+
Now that the ADC is connected to the Pi, you can wire devices up to the input channels. A potentiometer is a good example of an analogue input device: it's simply a variable resistor, and the Pi reads the voltage (from 0V to 3.3V).
34+
35+
![Potentiometer](images/potentiometer.jpg)
36+
37+
A potentiometer's pins are ground, data, and 3V3. This means you connect it to ground and a supply of 3V3, and read the actual voltage from the middle pin.
38+
39+
1. Place a potentiometer on the breadboard and wire one side to the ground rail, the other to the 3V3 rail, and the middle pin to the first input channel as shown:
40+
41+
![Add a potentiometer](images/mcp3008-pot.png)
42+
43+
## Code
44+
45+
Now your potentiometer is connected and its value can be read from Python!
46+
47+
1. Open **Python 3** from the main menu.
48+
49+
1. In the shell, start by importing the `MCP3008` class from the GPIO Zero library:
50+
51+
```python
52+
from gpiozero import MCP3008
53+
```
54+
55+
1. Create an object representing your analogue device:
56+
57+
```python
58+
pot = MCP3008(0)
59+
```
60+
61+
Note the `0` represents the ADC's channel 0. There are 8 channels (0 to 7), and you're using the first one.
62+
63+
1. Try to read its value:
64+
65+
```python
66+
print(pot.value)
67+
```
68+
69+
You should see a number between 0 and 1. This represents how far the dial is turned.
70+
71+
1. Now read the value in a loop:
72+
73+
```python
74+
while True:
75+
print(pot.value)
76+
```
77+
78+
Try twisting the dial around to see the value change.
79+
80+
## PWMLED
81+
82+
Now you've tested you can read values from the potentiometer, you should connect it to another GPIO device.
83+
84+
1. Add an LED to your breadboard and wire it to the Pi, connecting it to GPIO pin 21:
85+
86+
![Add LED](images/mcp3008-pot-led.png)
87+
88+
1. In your Python code, start by importing the `PWMLED` class:
89+
90+
```python
91+
from gpiozero import PWMLED
92+
```
93+
94+
The `PWMLED` class lets you control the brightness of an LED using PWM, or pulse-width modulation.
95+
96+
1. Create a `PWMLED` object on pin 21:
97+
98+
```python
99+
led = PWMLED(21)
100+
```
101+
102+
1. Test you can control the LED manually:
103+
104+
```python
105+
led.on() # the led should be lit
106+
led.off() # the led should go off
107+
led.value = 0.5 # the led should be lit at half brightness
108+
```
109+
110+
1. Now connect the LED to the potentiometer:
111+
112+
```python
113+
led.source = pot.values
114+
```
115+
116+
1. Turn the dial to change the LED brightness!
117+
118+
### Source and values
119+
120+
GPIO Zero has a powerful feature: **source and values**. Every device has a `value` property (the current value) and a `values` property (a stream of the device's values at all times). Every output device has a `source` property which can be used to set what the device's value should be.
121+
122+
- `pot.value` gives the potentiometer's current value (it's read only, as it's an input device)
123+
- `led.value` is the LED's current value (it's read/write: you can see what it is, and you can change it)
124+
- `pot.values` is a generator constantly yielding the potentiometer's current value
125+
- `led.source` is a way of setting where the LED gets its values from
126+
127+
Rather than continuously setting the value of the LED to the value of the potentiometer in a loop, you can just pair the two devices. Therefore the line `led.source = pot.values` is equivalent to the following loop:
128+
129+
```python
130+
while True:
131+
led.value = pot.value
132+
```
133+
134+
## Multiple potentiometers
135+
136+
1. Add a second potentiometer to your breadboard and connect it to the ADC's channel 1:
137+
138+
![Second potentiometer](images/mcp3008-2pots-led.png)
139+
140+
1. Now create a second `MCP3008` object on channel 1:
141+
142+
```python
143+
pot2 = MCP3008(1)
144+
```
145+
146+
1. Make the LED blink:
147+
148+
```python
149+
led.blink()
150+
```
151+
152+
The LED will blink continuously, one second on and one second off.
153+
154+
1. Change the `on_time` and `off_time` parameters to make it blink faster or slower:
155+
156+
```python
157+
led.blink(on_time=2, off_time=2)
158+
led.blink(on_time=0.5, off_time=0.1)
159+
```
160+
161+
1. Now use a loop to change the blink times according to the potentiometer values:
162+
163+
```python
164+
while True:
165+
print(pot.value, pot2.value)
166+
led.blink(on_time=pot.value, off_time=pot2.value, n=1, background=False)
167+
```
168+
169+
Note you have to make it blink once in the foreground, so that each iteration gets time to finish before it updates the blink times.
170+
171+
1. Rotate the dials to make it blink at different speeds!
172+
173+
1. Also try changing `blink` to `pulse` and change `on_time` and `off_time` to `fade_in_time` and `fade_out_time` so that it fades in and out at different speeds, rather than just blinking on and off:
174+
175+
```python
176+
while True:
177+
print(pot.value, pot2.value)
178+
led.pulse(fade_in_time=pot.value, fade_out_time=pot2.value, n=1, background=False)
179+
```
180+
181+
1. Rotate the dials to change the effect.
182+
183+
## What next?
184+
185+
- Use potentiometers to control other GPIO Zero output devices
186+
- Use potentiometers to control the speed of motors
187+
- Use potentiometers to control the visual settings of a Camera Module in real time
188+
- Find more analogue sensors that will work with the ADC
189+
- Use potentiometers to control a player in a [PyGame Zero](http://pygame-zero.readthedocs.io) game, or in [Minecraft](https://www.raspberrypi.org/learning/getting-started-with-minecraft-pi/)

code/example.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

distance.md

Lines changed: 105 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,126 @@
11
# Ultrasonic distance sensor
22

3-
In air, sound travels at a speed of 343ms<sup>-1</sup>. An ultrasonic distance sensor sends out pulses of ultrasound, which is inaudible to humans, and detects the echo that is sent back when the sound bounces off a nearby object.
3+
In air, sound travels at a speed of 343 metres per second. An ultrasonic distance sensor sends out pulses of ultrasound which are inaudible to humans, and detects the echo that is sent back when the sound bounces off a nearby object. It then uses the speed of sound to calculate the distance from the object.
44

5-
![usd](images/ultrasonic-distance-sensor.png)
5+
![Ultrasonic distance sensor](images/ultrasonic-distance-sensor.png)
66

7-
By knowing the speed of sound and the time taken for the ultrasound to be detected, an ultrasonic distance sensor can be used to detect how far away an object is.
7+
## Wiring
88

9-
## Wiring an ultrasonic distance sensor
10-
11-
To wire up an ultrasonic distance sensor, you'll need to use a pair of resistors as a potential divider. Use the diagram below as a guide.
9+
The circuit connects to two GPIO pins (one for echo, one for trigger), the ground pin, and a 5V pin. You'll need to use a pair of resistors (330Ω and 470Ω) as a potential divider:
1210

1311
![wiring](images/wiring-uds.png)
1412

15-
## Detecting distance
13+
## Code
14+
15+
To use the ultrasonic distance sensor in Python, you need to know which GPIO pins the echo and trigger are connected to.
16+
17+
1. Open Python 3.
18+
19+
1. In the shell, enter the following line to import `DistanceSensor` from the GPIO Zero library:
20+
21+
```python
22+
from gpiozero import DistanceSensor
23+
```
24+
25+
After each line, press **Enter** and the command will be executed immediately.
26+
27+
1. Create an instance of `DistanceSensor` using your echo and trigger pins:
28+
29+
```python
30+
ultrasonic = DistanceSensor(echo=17, trigger=4)
31+
```
32+
33+
1. See what distance it shows:
34+
35+
```python
36+
ultrasonic.distance
37+
```
38+
39+
You should see a number: this is the distance to the nearest object, in metres.
40+
41+
1. Try using a loop to print the distance continuously, while waving your hand in front of the sensor to alter the distance reading:
42+
43+
```python
44+
while True:
45+
print(ultrasonic.distance)
46+
```
47+
48+
The value should get smaller the closer your hand is to the sensor. Press **Ctrl + C** to exit the loop.
49+
50+
## Ranges
51+
52+
As well as being able to see the distance value, you can also get the sensor to do things when the object is in or out of a certain range.
53+
54+
1. Use a loop to print different messages when the sensor is in range or out of range:
55+
56+
```python
57+
while True:
58+
ultrasonic.wait_for_in_range()
59+
print("In range")
60+
ultrasonic.wait_for_out_of_range()
61+
print("Out of range")
62+
```
63+
64+
Now wave your hand in front of the sensor; it should switch between showing the message "In range" and "Out of range" as your hand gets closer and further away from the sensor. See if you can work out the point at which it changes.
65+
66+
1. The default range threshold is 0.3m. This can be configured when the sensor is initiated:
67+
68+
```python
69+
ultrasonic = DistanceSensor(echo=17, trigger=4, threshold_distance=0.5)
70+
```
71+
72+
Alternatively, this can be changed after the sensor is created, by setting the `threshold_distance` property:
73+
74+
```python
75+
ultrasonic.threshold_distance = 0.5
76+
```
77+
78+
1. Try the previous loop again and observe the new range threshold.
79+
80+
1. The `wait_for` functions are **blocking**, which means they halt the program until they are triggered. Another way of doing something when the sensor goes in and out of range is to use `when` properties, which can be used to trigger actions in the background while other things are happening in the code.
81+
82+
First, you need to create a function for what you want to happen when the sensor is in range:
83+
84+
```python
85+
def hello():
86+
print("Hello")
87+
```
88+
89+
Then set `ultrasonic.when_in_range` to the name of this function:
1690

17-
The ultrasonic distance sensor has not yet been included in the GPIO Zero library, but it will be soon. Until then, you can use a generic input and output device to detect the distance of an object.
91+
```python
92+
ultrasonic.when_in_range = hello
93+
```
1894

95+
1. Add another function for when the sensor goes out of range:
1996

20-
```python
21-
from gpiozero import InputDevice, OutputDevice
22-
from time import sleep, time
97+
```python
98+
def bye():
99+
print("Bye")
23100

24-
trig = OutputDevice(4)
25-
echo = InputDevice(17)
101+
ultrasonic.when_out_of_range = bye
102+
```
26103

27-
sleep(2)
104+
Now these triggers are set up, you'll see "hello" printed when your hand is in range, and "bye" when it's out of range.
28105

29-
def get_pulse_time():
30-
trig.on()
31-
sleep(0.00001)
32-
trig.off()
106+
1. You may have noticed that the sensor distance stopped at 1 metre. This is the default maximum and can also be configured on setup:
33107

34-
while echo.is_active == False:
35-
pulse_start = time()
108+
```python
109+
ultrasonic = DistanceSensor(echo=17, trigger=4, max_distance=2)
110+
```
36111

37-
while echo.is_active == True:
38-
pulse_end = time()
112+
Or after setup:
39113

40-
sleep(0.06)
114+
```python
115+
ultrasonic.max_distance = 2
116+
```
41117

42-
return pulse_end - pulse_start
118+
1. Try different values of `max_distance` and `threshold_distance`.
43119

44-
def calculate_distance(duration):
45-
speed = 343
46-
distance = speed * duration / 2
47-
return distance
120+
## What next?
48121

49-
while True:
50-
duration = get_pulse_time()
51-
distance = calculate_distance(duration)
52-
print(distance)
53-
```
122+
Now you've learned to use an ultrasonic distance sensor, you could:
54123

124+
- Build a proximity sensor alert using a buzzer or a sound file
125+
- Build a Pi camera photo booth which is activated when a person is close enough to the camera
126+
- Build a robot with a distance sensor to stop it bumping into other objects

images/mcp3008-2pots-led.png

233 KB
Loading

images/mcp3008-pot-led.png

215 KB
Loading

images/mcp3008-pot.png

196 KB
Loading

images/mcp3008.png

181 KB
Loading

images/potentiometer.jpg

42 KB
Loading

images/rcgui.png

34.9 KB
Loading

0 commit comments

Comments
 (0)