Skip to content

Commit 66e8d70

Browse files
committed
Some work on Inventor documentation
1 parent 34fe695 commit 66e8d70

File tree

2 files changed

+421
-0
lines changed

2 files changed

+421
-0
lines changed

micropython/modules_py/inventor.md

+360
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
# Pimoroni Inventor 2040/2350 W - Library Reference <!-- omit in toc -->
2+
3+
This is the library reference for the [Pimoroni Inventor 2040/2350 W](https://shop.pimoroni.com/products/inventor-2350-w), an all-in-one board for making battery powered contraptions that can move, (optionally) make noise, and talk to the internet!
4+
5+
## Table of Content <!-- omit in toc -->
6+
- [Getting Started](#getting-started)
7+
- [Different Gear Ratio](#different-gear-ratio)
8+
- [What Gets Initialised](#what-gets-initialised)
9+
- [Reading the User Button](#reading-the-user-button)
10+
- [Connecting Qw/ST Devices](#connecting-qwst-devices)
11+
- [Controlling Motors](#controlling-motors)
12+
- [Controlling Servos](#controlling-servos)
13+
- [Setting the RGB LEDs](#setting-the-rgb-leds)
14+
- [Audio](#audio)
15+
- [Wireless](#wireless)
16+
- [Program Lifecycle](#program-lifecycle)
17+
- [`inventor` Module Reference](#inventor-module-reference)
18+
- [Constants](#constants)
19+
- [IO Pin](#io-pin)
20+
- [Index](#index)
21+
- [Count](#count)
22+
- [`Inventor` Class Reference](#inventor-class-reference)
23+
- [Constants](#constants-1)
24+
- [Variables](#variables)
25+
- [Functions](#functions)
26+
27+
28+
## Getting Started
29+
30+
To start coding your Inventor board, you will need to add the following lines to the start of your code file.
31+
32+
```python
33+
from inventor import Inventor
34+
35+
board = Inventor()
36+
```
37+
38+
This will create an `Inventor` class called `board` that initialises all the features of Inventor and will be used in the rest of the examples going forward.
39+
40+
41+
### Different Gear Ratio
42+
43+
By default the Inventor class initialises the motors and encoders with a 50:1 gear ratio, matching the pre-assembled [Micro Metal Motor Encoders](https://shop.pimoroni.com/products/micro-metal-gearmotor-with-micro-metal-motor-encoder) that we sell.
44+
45+
If you are soldering up your own motors with encoders that have a different gear ratio, then add the `motor_gear_ratio` parameter during class creation, like so:
46+
47+
```python
48+
board = Inventor(motor_gear_ratio=<new ratio here>)
49+
```
50+
51+
:information_source: The Inventor class assumes the connected motor's encoders have the same 12 counts per revolution as our MMME's. If yours are different you will need adjust your ratio to account for this.
52+
53+
54+
### What Gets Initialised
55+
56+
To make the starting experience of Inventor easier, the class initialises all of the board features. For some advanced uses though this may not be wanted. To give this flexibility, several steps of the initialisation can be turned off during class creation:
57+
58+
```python
59+
board = Inventor(init_motors=True, init_servos=True, init_encoders=True, init_i2c=True)
60+
```
61+
62+
Example uses:
63+
* `init_motors=False` - Lets you drive different kinds of magnetic loads, such as solenoids or stepper motors (with the appropriate code), via the new 1x4 header of Inventor 2350 W.
64+
* `init_servos=False` - Lets you use the 6 servo headers as additional digital GPIO. Note these pins are not 5V tolerant so be careful when using the neighbouring 5V pins for powering devices.
65+
* `init_encoders=False` - Lets you use the 4 encoder pins as additional digital GPIO. These are handily broken out to pads on the new Inventor 2350 W.
66+
* `init_i2c=False` - Lets you use the 2 Qw/ST pins as additional digital GPIO for UART or similar.
67+
68+
69+
## Reading the User Button
70+
71+
Inventor has one user button, labelled **User**. This can be read using the `switch_pressed()` function:
72+
73+
```python
74+
state = board.switch_pressed()
75+
```
76+
77+
A common use for this would be to control your program's main loop, so that a press of the button causes it to exit:
78+
79+
```python
80+
while not board.switch_pressed():
81+
# Do some stuff here
82+
83+
# Shut the program down cleanly
84+
```
85+
86+
## Connecting Qw/ST Devices
87+
88+
Inventor 2040/2350 W features two Qw/ST connectors for attaching I2C-based sensors and devices. These connectors are automatically initialised during class creation (unless `init_i2c=False` was supplied), removing the worry of specifying the wrong pins. The I2C bus can then be accessed by calling `board.i2c`.
89+
90+
Here is an example of setting up our [BME280 breakout](https://shop.pimoroni.com/products/bme280-breakout) on Inventor.
91+
92+
```python
93+
from inventor import Inventor
94+
from breakout_bme280 import BreakoutBME280
95+
96+
# Constants
97+
ADDRESS = 0x76 # Or 0x77 if the trace on rear of the breakout has been cut
98+
99+
# Variables
100+
board = Inventor()
101+
bme = BreakoutBME280(board.i2c, ADDRESS)
102+
```
103+
104+
## Controlling Motors
105+
106+
Inventor features a DRV8833 dual-channel motor driver that it suitable for driving small motors. These motor channels are set up as `Motor` objects during class creation (unless `init_motors=False` was supplied). #
107+
108+
:information_source: **For details of what `Motor` objects can do, refer to the [Motor Library](/micropython/modules/motor/README.md#motor)**
109+
110+
The created `Motor` objects can be accessed in two ways, either through the `motor_a` and `motor_b` properties, or by the `motors` list.
111+
112+
```python
113+
# Access the first motor by property
114+
motor = board.motor_a
115+
116+
# Access the first motor by list
117+
motor = board.motors[0]
118+
119+
# Access the first motor by list and constant
120+
from inventor import MOTOR_A
121+
motor = board.motors[MOTOR_A]
122+
```
123+
124+
Accessing by property is convenient when you know the specific motor you wish to perform a motion, whereas accessing by list can be useful if you need to perform the same operation across both motors within a loop.
125+
126+
Here are examples of how the list may be looped through:
127+
128+
```python
129+
# Loop through all motors
130+
for motor in board.motors:
131+
# Do something with motor here
132+
133+
# Loop through all motors via an index
134+
from inventor import NUM_MOTORS
135+
for i in range(NUM_MOTORS):
136+
motor = board.motors[i]
137+
# Do something with motor here
138+
```
139+
140+
141+
## Controlling Servos
142+
143+
144+
145+
## Setting the RGB LEDs
146+
147+
Inventor 2040/2350 W has twelve addressable RGB LEDs, positioned alongside its servo and GPIO/ADC pins. These make use of our `Plasma` library.
148+
149+
```python
150+
board.leds.set_rgb(0, 255, 255, 255)
151+
```
152+
153+
## Audio
154+
155+
## Wireless
156+
157+
## Program Lifecycle
158+
159+
When writing a program for Inventor 2040/2350 W, there are a number of steps that should be included to make best use of the board's capabilities.
160+
161+
162+
```python
163+
# Perform system level imports here
164+
# e.g. import math
165+
166+
from inventor import Inventor
167+
168+
"""
169+
This is a boilerplate example for Inventor 2040/2350 W. Use it as a base for your own programs.
170+
171+
Press "User" to exit the program.
172+
"""
173+
174+
# Constants
175+
# e.g. SLEEP_TIME = 0.1
176+
177+
# Variables
178+
board = Inventor() # Create a new Inventor object. These optional keyword parameters are supported:
179+
# `init_motors`, `init_servos`, `init_encoders`, and `init_i2c`. All are True by default
180+
181+
# Pull out any variables for easy access. E.g
182+
motor = board.motor_a # or board.motors[MOTOR_A]
183+
encoder = board.encoder_a # or board.encoders[ENCODER_A]
184+
servo = board.servo1 # or board.servos[SERVO_1]
185+
186+
187+
# Wrap the code in a try block, to catch any exceptions (including KeyboardInterrupt)
188+
try:
189+
# Set up your motors, servos, LEDs, and audio here
190+
191+
# Loop until the "User" button is pressed
192+
while not board.switch_pressed():
193+
#######################
194+
# Put your program here
195+
#######################
196+
pass
197+
198+
finally:
199+
# Stop your motors, servos, LEDs, and audio here
200+
```
201+
202+
## `inventor` Module Reference
203+
204+
### Constants
205+
206+
These are accessible by `from inventor import *`, where star is one or more of the below values, separated by commas.
207+
208+
#### IO Pin
209+
210+
```python
211+
GP0 = 0
212+
GP1 = 1
213+
GP2 = 2
214+
215+
A0 = 26
216+
A1 = 27
217+
A2 = 28
218+
219+
GPIOS = (GP0, GP1, GP2, A0, A1, A2)
220+
ADCS = (A0, A1, A2)
221+
```
222+
223+
#### Index
224+
225+
```python
226+
MOTOR_A = 0
227+
MOTOR_B = 1
228+
229+
SERVO_1 = 0
230+
SERVO_2 = 1
231+
SERVO_3 = 2
232+
SERVO_4 = 3
233+
SERVO_5 = 4
234+
SERVO_6 = 5
235+
236+
LED_GP0 = 0
237+
LED_GP1 = 1
238+
LED_GP2 = 2
239+
LED_A0 = 3
240+
LED_A1 = 4
241+
LED_A2 = 5
242+
LED_SERVO_1 = 6
243+
LED_SERVO_2 = 7
244+
LED_SERVO_3 = 8
245+
LED_SERVO_4 = 9
246+
LED_SERVO_5 = 10
247+
LED_SERVO_6 = 11
248+
```
249+
250+
#### Count
251+
252+
```python
253+
NUM_GPIOS = 6
254+
NUM_ADCS = 3
255+
NUM_MOTORS = 2
256+
NUM_ENCODERS = 2
257+
NUM_SERVOS = 6
258+
NUM_LEDS = 12
259+
```
260+
261+
262+
## `Inventor` Class Reference
263+
264+
### Constants
265+
266+
These are accessible after having imported `Inventor` class from the `inventor` module. E.g. `Inventor.SERVO_1_PIN`.
267+
268+
```python
269+
AMP_EN_PIN = 3
270+
I2C_SDA_PIN = 4
271+
I2C_SCL_PIN = 5
272+
MOTOR_A_PINS = (6, 7)
273+
MOTOR_B_PINS = (8, 9)
274+
ENCODER_A_PINS = (19, 18)
275+
ENCODER_B_PINS = (17, 16)
276+
277+
SERVO_1_PIN = 10
278+
SERVO_2_PIN = 11
279+
SERVO_3_PIN = 12
280+
SERVO_4_PIN = 13
281+
SERVO_5_PIN = 14
282+
SERVO_6_PIN = 15
283+
284+
LED_DATA_PIN = 20
285+
PWM_AUDIO_PIN = 21
286+
USER_SW_PIN = 22
287+
288+
AMP_CORRECTION = 4
289+
DEFAULT_VOLUME = 0.2
290+
```
291+
292+
293+
### Variables
294+
```python
295+
# If init_motors was True
296+
motors: list[Motor]
297+
298+
# If init_encoders was True
299+
encoders: list[Encoder]
300+
301+
# If init_servos was True
302+
servos: list[Servo]
303+
304+
# If init_i2c was True
305+
i2c: PimoroniI2C
306+
307+
audio_pwm: PWM
308+
309+
leds: WS2812
310+
```
311+
312+
313+
### Functions
314+
315+
```python
316+
# Initialisation
317+
Inventor(motor_gear_ratio: int|float=50,
318+
init_motors: bool=True,
319+
init_servos: bool=True,
320+
init_encoders: bool=True,
321+
init_i2c: bool=True)
322+
323+
# Interaction
324+
switch_pressed() -> bool
325+
326+
# Motor Access (only usable if init_motors was True)
327+
@property
328+
motor_a -> Motor
329+
@property
330+
motor_b -> Motor
331+
332+
# Encoder Access (only usable if init_encoders was True)
333+
@property
334+
encoder_a -> Encoder
335+
@property
336+
encoder_b -> Encoder
337+
338+
# Servo Access (only usable if init_servos was True)
339+
@property
340+
servo1 -> Servo
341+
@property
342+
servo2 -> Servo
343+
@property
344+
servo3 -> Servo
345+
@property
346+
servo4 -> Servo
347+
@property
348+
servo5 -> Servo
349+
@property
350+
servo6 -> Servo
351+
352+
# Audio
353+
play_tone(frequency: float):
354+
play_silence() -> None
355+
stop_playing() -> None
356+
volume() -> float
357+
volume(volume: float) -> None
358+
mute_audio() -> None
359+
unmute_audio() -> None
360+
```

0 commit comments

Comments
 (0)