Skip to content

Commit a8a7206

Browse files
authored
Merge pull request #141 from RaspberryPiFoundation/dev
Dev
2 parents c4e50b5 + 545a8cf commit a8a7206

File tree

15 files changed

+1004
-120
lines changed

15 files changed

+1004
-120
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2023 Raspberry Pi Foundation
1+
Copyright 2025 Raspberry Pi Foundation
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
44

docs/api.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ Servo
6363
:inherited-members:
6464
:members:
6565

66+
Stepper
67+
-------
68+
69+
.. autoclass:: Stepper
70+
:show-inheritance:
71+
:inherited-members:
72+
:members:
73+
6674
Motor
6775
-----
6876

@@ -109,6 +117,14 @@ MotionSensor
109117
:inherited-members:
110118
:members:
111119

120+
TouchSensor
121+
-----------
122+
123+
.. autoclass:: TouchSensor
124+
:show-inheritance:
125+
:inherited-members:
126+
:members:
127+
112128
Switch
113129
------
114130

docs/changelog.rst

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,24 @@ Change log
33

44
.. currentmodule:: picozero
55

6+
0.6.0 - 2025-11-26
7+
-----------
8+
9+
+ Introduced ``Stepper`` class for stepper motors
10+
+ Introduced ``TouchSensor`` class for capacitive touch sensors
11+
+ Updated tests and documentation
12+
+ Other minor bug fixes
13+
14+
15+
0.5.2 - 2025-11-26
16+
-----------
17+
18+
+ Fixed 404 in manual install instructions
19+
620
0.5.1 - 2025-11-24
21+
-----------
722

8-
+ Fix to incorrect example in documentation.
23+
+ Fix to incorrect example in documentation
924

1025
0.5.0 - 2025-10-31
1126
-----------

docs/conf.py

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,62 +12,75 @@
1212
#
1313
import os
1414
import sys
15+
1516
# sys.path.insert(0, os.path.abspath('.'))
16-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
17-
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
17+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
18+
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
19+
1820

1921
# Mock out certain modules while building documentation
2022
class Mock:
2123
__all__ = []
22-
def __init__(self, *args, **kw): pass
23-
def __call__(self, *args, **kw): return Mock()
24-
def __mul__(self, other): return Mock()
25-
def __and__(self, other): return Mock()
26-
def __bool__(self): return False
27-
def __nonzero__(self): return False
24+
25+
def __init__(self, *args, **kw):
26+
pass
27+
28+
def __call__(self, *args, **kw):
29+
return Mock()
30+
31+
def __mul__(self, other):
32+
return Mock()
33+
34+
def __and__(self, other):
35+
return Mock()
36+
37+
def __bool__(self):
38+
return False
39+
40+
def __nonzero__(self):
41+
return False
42+
2843
@classmethod
2944
def __getattr__(cls, name):
30-
if name in ('__file__', '__path__'):
31-
return '/dev/null'
45+
if name in ("__file__", "__path__"):
46+
return "/dev/null"
3247
else:
3348
return Mock()
3449

35-
sys.modules['machine'] = Mock()
36-
sys.modules['micropython'] = Mock()
50+
51+
sys.modules["machine"] = Mock()
52+
sys.modules["micropython"] = Mock()
3753

3854
# add the ticks_ms function to time (as it is in micropython)
3955
import time
40-
setattr(time, 'ticks_ms', lambda x: None)
41-
setattr(time, 'ticks_us', lambda x: None)
56+
57+
setattr(time, "ticks_ms", lambda x: None)
58+
setattr(time, "ticks_us", lambda x: None)
4259

4360
# -- Project information -----------------------------------------------------
4461

45-
project = 'picozero'
46-
copyright = '2025, Raspberry Pi Foundation'
47-
author = 'Raspberry Pi Foundation'
62+
project = "picozero"
63+
copyright = "2025, Raspberry Pi Foundation"
64+
author = "Raspberry Pi Foundation"
4865

4966
# The full version, including alpha/beta/rc tags
50-
release = '0.5.0'
67+
release = "0.6.0"
5168

5269

5370
# -- General configuration ---------------------------------------------------
5471

5572
# Add any Sphinx extension module names here, as strings. They can be
5673
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
5774
# ones.
58-
extensions = [
59-
'sphinx.ext.autodoc',
60-
'sphinx.ext.viewcode',
61-
'sphinx.ext.intersphinx'
62-
]
75+
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx"]
6376

6477
# Add any paths that contain templates here, relative to this directory.
65-
templates_path = ['_templates']
78+
templates_path = ["_templates"]
6679

6780
# List of patterns, relative to source directory, that match files and
6881
# directories to ignore when looking for source files.
6982
# This pattern also affects html_static_path and html_extra_path.
70-
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
83+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
7184

7285

7386
# -- Options for HTML output -------------------------------------------------
@@ -79,26 +92,26 @@ def __getattr__(cls, name):
7992
# a list of builtin themes.
8093
#
8194
if on_rtd:
82-
html_theme = 'sphinx_rtd_theme'
83-
#html_theme_options = {}
95+
html_theme = "sphinx_rtd_theme"
96+
# html_theme_options = {}
8497
html_sidebars = {
85-
'**': [
86-
'globaltoc.html',
87-
'relations.html',
88-
'searchbox.html',
98+
"**": [
99+
"globaltoc.html",
100+
"relations.html",
101+
"searchbox.html",
89102
],
90103
}
91104
else:
92-
html_theme = 'alabaster'
93-
#html_theme_options = {}
94-
#html_sidebars = {}
105+
html_theme = "alabaster"
106+
# html_theme_options = {}
107+
# html_sidebars = {}
95108

96109
# Add any paths that contain custom static files (such as style sheets) here,
97110
# relative to this directory. They are copied after the builtin static files,
98111
# so a file named "default.css" will overwrite the builtin "default.css".
99-
html_static_path = ['_static']
112+
html_static_path = ["_static"]
100113

101114
# -- Autodoc configuration ------------------------------------------------
102115

103-
autodoc_member_order = 'groupwise'
104-
autodoc_default_flags = ['members']
116+
autodoc_member_order = "groupwise"
117+
autodoc_default_flags = ["members"]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from picozero import Stepper
2+
3+
# Second Hand Clock - Continuous 60s Rotation
4+
# One full revolution every 60 seconds.
5+
6+
STEP_DELAY = 60.0 / 2048 # ≈ 0.029296875 seconds per step (full-step)
7+
8+
stepper = Stepper((1, 2, 3, 4), step_delay=STEP_DELAY)
9+
10+
stepper.run_continuous(direction="cw")
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from picozero import Stepper
2+
from time import localtime, sleep
3+
4+
stepper = Stepper((1, 2, 3, 4), step_sequence="half")
5+
6+
OPEN_TIME = (7, 0) # Open at 7:00 AM (hour, minute)
7+
CLOSE_TIME = (20, 0) # Close at 8:00 PM
8+
ROTATIONS = 5 # Number of full rotations needed to fully open/close blinds
9+
10+
# Track state
11+
is_open = False
12+
13+
14+
def open_blinds():
15+
global is_open
16+
if not is_open:
17+
for _ in range(ROTATIONS):
18+
stepper.rotate(1, "cw")
19+
is_open = True
20+
21+
22+
def close_blinds():
23+
global is_open
24+
if is_open:
25+
for _ in range(ROTATIONS):
26+
stepper.rotate(1, "ccw")
27+
is_open = False
28+
29+
30+
def check_schedule():
31+
now = localtime()
32+
current_time = (now.tm_hour, now.tm_min)
33+
34+
# Check if it's time to open
35+
if current_time == OPEN_TIME and not is_open:
36+
open_blinds()
37+
38+
# Check if it's time to close
39+
elif current_time == CLOSE_TIME and is_open:
40+
close_blinds()
41+
42+
43+
# Set starting position (closed)
44+
stepper.reset_position()
45+
is_open = False
46+
47+
# Check every 30 seconds
48+
while True:
49+
check_schedule()
50+
sleep(30)

docs/examples/touch_sensor.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from picozero import TouchSensor, pico_led
2+
from time import sleep
3+
4+
# Capacitive touch sensor output connected to pin 2
5+
touch = TouchSensor(2)
6+
7+
while True:
8+
if touch.is_touched:
9+
pico_led.on()
10+
else:
11+
pico_led.off()
12+
sleep(0.1)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from picozero import TouchSensor, pico_led
2+
from time import sleep
3+
4+
touch = TouchSensor(2)
5+
6+
touch.when_touch_starts = pico_led.on
7+
touch.when_touch_ends = pico_led.off

docs/gettingstarted.rst

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ picozero can be installed by copying the ``picozero.py`` code to your Raspberry
5858
Either clone the picozero `GitHub repository`_ or copy the code from the `picozero.py`_ file and save it on your main computer.
5959

6060
.. _GitHub repository: https://github.com/RaspberryPiFoundation/picozero
61-
.. _picozero.py: https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py?token=GHSAT0AAAAAABRLTKWZDBSYBE54NJ7AIZ6MYSENI2A
61+
.. _picozero.py: https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py
6262

6363
Create a new file called picozero.py, copy code into the file and save it on your Raspberry Pi Pico.
6464

@@ -72,10 +72,25 @@ In the **View** menu, ensure that the **Files** option has a tick. This will let
7272
.. image:: images/thonny-view-files.jpg
7373
:alt: The Files option selected from the View menu
7474

75-
Either clone the picozero `GitHub repository`_ or copy the code from the `picozero.py`_ file and save it on your main computer.
75+
Either clone the picozero `GitHub repository`_ or download the `picozero.py`_ file and save it on your main computer.
76+
77+
.. only:: html
78+
79+
.. raw:: html
80+
81+
<p>
82+
<a href="https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py" download>
83+
⬇️ Download picozero.py
84+
</a>
85+
</p>
86+
87+
.. only:: not html
88+
89+
Download ``picozero.py``:
90+
https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py
7691

7792
.. _GitHub repository: https://github.com/RaspberryPiFoundation/picozero
78-
.. _picozero.py: https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py?token=GHSAT0AAAAAABRLTKWZDBSYBE54NJ7AIZ6MYSENI2A
93+
.. _picozero.py: https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py
7994

8095
In Thonny, navigate to the cloned directory or location you saved the file in and find the ``picozero.py`` file.
8196

docs/recipes.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ Turn the :obj:`pico_led` on when a :class:`Button` is pressed and off when it is
145145

146146
.. literalinclude:: examples/button_led.py
147147

148+
Touch sensor
149+
------------
150+
151+
Detect touch using a capacitive touch sensor:
152+
153+
.. literalinclude:: examples/touch_sensor.py
154+
155+
Use callbacks to respond to touch events:
156+
157+
.. literalinclude:: examples/touch_sensor_callbacks.py
158+
148159
Motion sensor
149160
-------------
150161

@@ -276,13 +287,37 @@ Move the rover (roughly) in a square:
276287

277288
.. literalinclude:: examples/robot_rover_square.py
278289

290+
291+
Stepper motor
292+
-------------
293+
294+
Control a stepper motor connected via a driver board (e.g. ULN2003) to create:
295+
296+
Analog clock (continuous second hand):
297+
.. literalinclude:: examples/stepper_analog_clock.py
298+
299+
Automatic blinds (multi-rotation, time-based):
300+
.. literalinclude:: examples/stepper_automatic_blinds.py
301+
302+
279303
Internal temperature sensor
280304
---------------------------
281305

282306
Check the internal temperature of the Raspberry Pi Pico in degrees Celcius:
283307

284308
.. literalinclude:: examples/pico_temperature.py
285309

310+
Motion sensor
311+
-------------
312+
313+
Detect motion using a PIR (Passive Infrared) sensor:
314+
315+
.. literalinclude:: examples/motion_sensor.py
316+
317+
Use callbacks to respond to motion events:
318+
319+
.. literalinclude:: examples/motion_sensor_callbacks.py
320+
286321
Ultrasonic distance sensor
287322
--------------------------
288323

0 commit comments

Comments
 (0)