8000 docs: Add programming guide with digital I/O tutorial. · boneskull/circuitpython@a528b3d · GitHub
[go: up one dir, main page]

Skip to content

Commit a528b3d

Browse files
committed
docs: Add programming guide with digital I/O tutorial.
1 parent 16ef611 commit a528b3d

8 files changed

+310
-0
lines changed

docs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
Digital Inputs & Outputs
2+
========================
3+
4+
Digital inputs and outputs (or I/O) are some of the simplest and most powerful
5+
ways to interact with hardware. Using digital I/O you can talk to devices with
6+
simple on and off signals, like turning a LED on/off or reading if a button is
7+
pressed. In CircuitPython using digital I/O is easy with a few modules that
8+
this guide will explore.
9+
10+
Digital Signals
11+
---------------
12+
13+
Before diving in to how to digital I/O works you'll want to understand what is a
14+
digial signal. In the simplest sense a digital signal is a simple on or off
15+
signal--i.e. there are only two possible states for the signal to be in. Think
16+
of this almost like a binary digit that's either 0 or 1. With a digital signal
17+
it can only ever be 0/off or 1/on, there is no in-between!
18+
19+
At a physical level digital signals are represented with high and low voltage
20+
levels. A digital signal that's on will be at a 'high' voltage level, typically
21+
3.3 volts or more (depending on the specifications of your microprocessor or
22+
development board), and a signal that's off will be at a 'low' voltage level of
23+
zero volts (also called ground). You can actually see this voltage with a
24+
multimeter set to measure DC voltage--try connecting a multimeter to a button or
25+
LED and watch the voltage as digital signal changes from on to off and
26+
vice-versa.
27+
28+
Examples of Digital Signals
29+
---------------------------
30+
31+
What can you do with a digital signal? It turns out quite a few interesting components are controlled with simple on/off digital I/O!
32+
33+
Digital inputs:
34+
35+
- `Buttons and switches <https://www.adafruit.com/category/155>`_
36+
- `Magnetic or hall-effect sensors <https://www.adafruit.com/product/158>`_
37+
- `PIR motion sensors <https://www.adafruit.com/product/189>`_
38+
- `Simple vibration sensors <https://www.adafruit.com/product/1766>`_
39+
- `Beam-break sensors <https://www.adafruit.com/product/2167>`_
40+
- `Liquid level sensors <https://www.adafruit.com/product/3397>`_
41+
- `Tilt switches <https://www.adafruit.com/product/173>`_
42+
- `Simple wireless remote controls <https://www.adafruit.com/product/1096>`_
43+
44+
Digital outputs:
45+
46+
- `Single color LEDs <https://www.adafruit.com/category/90>`_
47+
- `Relays to control high-power devices <https://www.adafruit.com/product/2935>`_
48+
- `Solenoids that push or pull objects <https://www.adafruit.com/product/2776>`_
49+
- `Vibration motors <https://www.adafruit.com/product/1201>`_
50+
- `Buzzers (not piezo buzzers that require an analog signal though!) <https://www.adafruit.com/product/1536>`_
51+
52+
In addition to devices like the above you can also use digital signals for
53+
simple communication between two devices. A digital output of one device, like
54+
your development board, can be connected to another device's digital input, like
55+
an `audio FX board <https://www.adafruit.com/product/2217>`_ that plays music
56+
and sound effects. There are even fast protocols like I2C or SPI for sending
57+
large amounts of data over a digital signal, but we'll cover those in a later
58+
guide.
59+
60+
Board Pins
61+
----------
62+
63+
To use digital I/O you need to learn how to access the pins on your board.
64+
These are the physical points where you connect wires to access the digital
65+
signals. On some boards, like Arduino Zero and Metro M0, the digital I/O pins
66+
are exposed with female headers that work well with breadboard-friendly hookup
67+
wires. On other boards like Circuit Playground Express and Gemma M0 the digital
68+
I/O pins are large copper pads with holes that are easy to connect to alligator
69+
clips or conductive thread. Check your board's documentation to see where all
70+
of the digital I/O pins are located.
71+
72+
In CircuitPython you use the board module to reference digital I/O pins. The
73+
:py:mod:`board` module contains an object for each pin on the board and they're
74+
typically named after labels on the board. You can list all of the pins in the
75+
board module with `Python's dir function
76+
<https://docs.python.org/3.4/library/functions.html#dir>`_, for example from a
77+
board's REPL run:
78+
79+
>>> import board
80+
>>> dir(board)
81+
['A0', 'SPEAKER', 'A1', 'A2', 'A3', 'A4', 'SCL', 'A5', 'SDA', 'A6', 'RX',
82+
'A7', 'TX', 'LIGHT', 'A8', 'TEMPERATURE', 'A9', 'BUTTON_A', 'D4', 'BUTTON_B',
83+
'D5', 'SLIDE_SWITCH', 'D7', 'NEOPIXEL', 'D8', 'D13', 'REMOTEIN', 'IR_RX',
84+
'REMOTEOUT', 'IR_TX', 'IR_PROXIMITY', 'MICROPHONE_SCK', 'MICROPHONE_DO',
85+
'ACCELEROMETER_INTERRUPT', 'ACCELEROMETER_SDA', 'ACCELEROMETER_SCL',
86+
'SPEAKER_ENABLE', 'SCK', 'MOSI', 'MISO', 'FLASH_CS']
87+
88+
Each of the objects returned by the dir command represents a named pin on the
89+
board. Above you see the output on a Circuit Playground Express board which has
90+
pins like A0, A1, D4, D5, etc. that represent pins that run around the diameter
91+
of the board. There are even named pins like BUTTON_A, BUTTON_B, and
92+
SLIDE_SWITCH that represent pins connected to components built-in to the board.
93+
94+
Digital Outputs
95+
---------------
96+
97+
Controlling a digital output with CircuitPython is easy to do with a few lines
98+
of code. In fact you can connect to a board's REPL and directly turn digital
99+
outputs on and off with a few simple commands.
100+
101+
An easy way to demonstrate digital outputs is with a simple single-color LED.
102+
You can connect a LED to a digital output of your board and turn it on or off by
103+
setting the output to a high or low voltage level. Remember digital outputs are
104+
only on or off and never in-between so you can't control the brightness of the
105+
LED! To wire a LED to your board you'll need these components:
106+
107+
- `A single color LED. <https://www.adafruit.com/product/777>`_ You want a simple single color LED and not a fancier multi-color LED or NeoPixel. Look for a LED that has two legs, a short one and long one. Check out `the Adafruit LED guide <https://learn.adafruit.com/all-about-leds/overview>`_ for more details on LEDs.
108+
- `A resistor in the range of 300-1,000 ohms. <https://www.adafruit.com/product/2781>`_ You *must* use a resistor when wiring up a LED to your board or else you might damage the digital output on the board. The resistor limits the amount of current to the LED and prevents damage to the board or LED. The exact value of the resistor isn't super important for this demonstration--pick any resistor in the 300-1,000 ohm range.
109+
- A breadboard and wires to connect the components and board together.
110+
111+
Connect the components to your board as follows:
112+
113+
.. image:: images/01_digital_io_figure_1.png
114+
115+
- The short leg (cathode) of the LED connects to one end of the resistor.
116+
- The other end of the resistor connects to the ground or GND pin of the board.
117+
- The long leg (anode) of the LED connects to a digital output on your board.
118+
119+
Now connect to your board's REPL and you can use the :py:mod:`digitalio` module
120+
to control the digital output connected to the LED. Run the following code to
121+
first import the necessary modules and create a
122+
:py:class:`digitalio.DigitalInOut` object for the pin (pin A1 in this example
123+
but you can use any digital output from your board):
124+
125+
>>> import board
126+
>>> import digitalio
127+
>>> led = digitalio.DigitalInOut(board.A1)
128+
129+
The :py:class:`digitalio.DigitalInOut` class is your gateway for controlling
130+
both digital inputs and outputs. By default when you create an instance of one
131+
it starts as a digital input, however you can call the
132+
:py:func:`digitalio.DigitalInOut.switch_to_output` function to turn it into a
133+
digital output:
134+
135+
>>> led.switch_to_output()
136+
137+
Once a digital output is created and initialized you simply change the value of
138+
its :py:attr:`digitalio.DigitalInOut.value` property to turn the output on or
139+
off. For example to turn the LED on set value to true:
140+
141+
>>> led.value = True
142+
143+
And to turn the LED off set value to false:
144+
145+
>>> led.value = False
146+
147+
Remember with digital signals you can only set them to on or off states, i.e.
148+
true or false values. There is no in-between or half on and half off!
149+
150+
Finally you can blink the LED by simply changing the value in a loop with a
151+
small delay:
152+
153+
>>> import time
154+
>>> while True:
155+
... led.value = True
156+
... time.sleep(0.5)
157+
... led.value = False
158+
... time.sleep(0.5)
159+
>>>
160+
161+
Remember in the REPL you need to press delete to de-indent the while loop and then press enter for it to see you're done typing code in the loop! Alternatively press enter three times an CircuitPython will automatically close the loop and run it. You can press Ctrl-C to stop the loop from running with a keyboard interrupt exception.
162+
163+
Digital Inputs
164+
--------------
165+
166+
Just like digital outputs, digital inputs are easy to control with a few lines
167+
of CircuitPython code. A great example of using digital inputs is reading the
168+
state of a button or switch. To do this you'll need the following parts:
169+
170+
- A `slide switch <https://www.adafruit.com/product/805>`_ or toggle switch. These are switches that have three legs and physically connect one of the legs to another when the switch is flipped. You'll see two different ways to wire this switch to your board--one that uses all three legs and another that uses just two legs.
171+
- A breadboard and wires to connect the components and board together.
172+
173+
Wire up the switch to your board as follows:
174+
175+
.. image:: images/01_digital_io_figure_2.png
176+
177+
- The middle leg or output of the switch is connected to one of the digital inputs of the board.
178+
- Another leg of the switch is connected to the board's ground or GND pin. When the switch is flipped to this position it will read a low digital logic signal.
179+
- The opposite leg of the switch is connected to the board's 3.3V output. You want to connect this switch to a voltage output that matches your board's voltage for a high digital logic signal, typically 3.3V but sometimes 5V. When the switch is flipped to this position it will read a high digital logic signal.
180+
181+
Now connect to the board's REPL and create a digital input object just like you
182+
saw previously with digital outputs. For example using pin A1 of a board:
183+
184+
>>> import board
185+
>>> import digitalio
186+
>>> switch = digitalio.DigitalInOut(board.A1)
187+
188+
By default :py:class:`digitalio.DigitalInOut` objects are created as digital
189+
inputs so you don't need to do anything else to read the switch. However if you
190+
were doing other things with the pin you can use the
191+
:py:func:`digitalio.DigitalInOut.switch_to_input` function:
192+
193+
>>> switch.switch_to_input()
194+
195+
After a digital input object is created you simply read the
196+
:py:attr:`digitalio.DigitalInOut.value` property to check if the input is at a
197+
high or low logic level. If the value is a boolean true value it's at a high
198+
digital logic level and if it's false it's at a low digital logic level.
199+
200+
Try reading the switch state, for example you might see:
201+
202+
>>> switch.value
203+
False
204+
205+
Then flip the switch to its opposite position and read it again:
206+
207+
>>> switch.value
208+
True
209+
210+
Notice the value changed from false to true! This shows that the board first
211+
saw the digital input connected to ground or low digital logic level and then
212+
saw the input connected to 3.3V or high digital logic level. By flipping the
213+
switch you physicaly changed how the legs of the switch were connected to switch
214+
between high and low levels!
215+
216+
Remember you can use boolean values in conditional statements, like to print out a message if the switch is turned on:
217+
218+
>>> if switch.value:
219+
... print("Switch is on!")
220+
... else:
221+
... print("Switch is off!")
222+
Switch is on!
223+
224+
There's one other way to read the switch which only requires two of its legs to
225+
be connected to your board. This is useful to reduce the number of physical
226+
connections or to connect to momentary or push buttons that only have two legs.
227+
Change the wiring of the switch to look like:
228+
229+
.. image:: images/01_digital_io_figure_3.png
230+
231+
- The middle leg or output of the switch is still connected to one of the digital inputs of the board.
232+
- Another leg of the switch is connected to the board's ground or GND pin.
233+
234+
The opposite leg of the switch remains disconnected--only two wires are
235+
connected to the switch. When the switch is wired like this it means it will
236+
read a ground or low logic level in one position, but what happens when it's in
237+
the opposite position and not connected to anything on the board? This state is
238+
called 'floating' and the input will actually read random values--you might get
239+
a high or low logic level depending on the electrical noise around the pin!
240+
241+
Luckily there's an easy way to prevent an input from floating by using special
242+
built-in pull-up or pull-down resistors available on most development board
243+
digital I/O pins. You can turn on a pull-up resistor that will bring the
244+
digital input up to a high digital logic level if nothing is connected to it.
245+
This prevents the input from floating and will instead read a high digital logic
246+
level. Then when the switch is flipped and connected to ground / low logic it
247+
will 'overpower' the small pull-up resistor and read a low digital logic level.
248+
249+
To enable a digital input with a pull-up (or pull-down) resistor you do so with
250+
a parameter to the :py:func:`digitalio.DigitalInOut.switch_to_input` function:
251+
252+
>>> switch.switch_to_input(pull=digitalio.Pull.UP)
253+
254+
Now the digital input is configured with a pull-up resistor! Note that you can
255+
instead specify a pull-down resistor (connected to ground / low digital logic
256+
level) by setting the pull parameter to the :py:attr:`digitalio.Pull.DOWN`
257+
value.
258+
259+
Once the input is configured with a pull-up resistor use the
260+
:py:attr:`digitalio.DigitalInOut.value` attribute to read its value:
261+
262+
>>> switch.value
263+
False
264+
265+
Then flip the switch and read its value again:
266+
267+
>>> switch.value
268+
True
269+
270+
Notice the switch value changes depending on how the switch is flipped. When
271+
the switch connects to ground you'll read a false or low digital logic level,
272+
and when the switch connects to nothing (i.e. is floating) you'll read a true or
273+
high logic level because of the pull-up resistor connected internally to 3.3V.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Analog Inputs & Outputs
2+
=======================
3+
4+
This is a test of restructured text!
5+
6+
Analog Signals
7+
--------------
8+
9+
Lorem ipsum.
10+
11+
Analog to Digital Converter (Inputs)
12+
------------------------------------
13+
14+
Foo bar.
15+
16+
Digital to Analog Converter (Outputs)
17+
--------------------------------------
18+
19+
Blah blah blah.
20+
21+
Pulse-width Modulation (Outputs)
22+
--------------------------------
23+
24+
Foo bar 2.
Loading
Loading
Loading

docs/programming_guide/index.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Programming Guide
2+
=================
3+
4+
This series of tutorials will progress through the basics of using CircuitPython with hardware. You'll learn how to connect to components like LEDs, buttons, sensors, etc. and control them with CircuitPython code.
5+
6+
.. toctree::
7+
:maxdepth: 1
8+
:numbered:
9+
10+
01_digital_io.rst

index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ docs are low-level API docs and may link out to separate getting started guides.
4242
:maxdepth: 3
4343

4444
shared-bindings/index.rst
45+
docs/programming_guide/index.rst
4546
docs/drivers.rst
4647
docs/common_hal
4748
docs/design_guide

0 commit comments

Comments
 (0)
0