From 00bd1eb5349c4bc2ce321cebfa4398d2647376b5 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 16 Mar 2023 16:25:04 +0000 Subject: [PATCH] Started readme for Inventor 2040 W --- micropython/modules_py/inventor.md | 128 +++++++++++++++++++++++++++++ micropython/modules_py/inventor.py | 15 ++-- 2 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 micropython/modules_py/inventor.md diff --git a/micropython/modules_py/inventor.md b/micropython/modules_py/inventor.md new file mode 100644 index 00000000..0b457632 --- /dev/null +++ b/micropython/modules_py/inventor.md @@ -0,0 +1,128 @@ +# Inventor 2040 W (MicroPython) + +This library offers convenient functions and variables for interacting with [Inventor 2040 W](https://shop.pimoroni.com/products/inventor-2040-w). + +## Table of Content +- [Inventor 2040 W](#interstate75-class) + - [Reading the User Button](#reading-the-user-button) + - [Board Variables](#board-variables) + - [Skip Initialisation](#skip-initialisation) + - [Constants](#constants) + - [Pin Constants](#pin-constants) + - [Index Constants](#index-constants) + - [Count Constants](#index-constants) + + +### Board Variables + +To make getting started with Inventor 2040 W easier, the necessary objects for interacting with motors, encoders, servos, leds, and i2c are automatically initialised when creating a new `Inventor2040W` object. These can be accessed as variables, like so: + +```python +board = Inventor2040W() + +# Access a motor and its encoder +motor = board.motors[MOTOR_A] +encoder = board.encoders[MOTOR_A] + +# Access a servo +servo = board.servos[SERVO_1] + +# Access the Neopixel LEDs +leds = board.leds + +# Access the I2C bus used for the Qwst connectors and Breakout Garden socket +i2c = board.i2c +``` + +For details of what can be done with these objects, check out there respective documentation pages: +* `board.motors`: [`Motor` object](../modules/motor/README.md#motor) +* `board.encoders`: [`Encoder` object](../modules/encoder/README.md#encoder) +* `board.servos` [`Servo` object](../modules/servo/README.md#servo) +* `board.leds` [`WS2812` object](../modules/plasma/README.md#ws2812) +* `board.i2c` [`I2C` object](https://docs.micropython.org/en/latest/library/machine.I2C.html) + + +#### Skipping Initialisation + +For some projects the automatic initialisation of servos, motors and the I2C bus may not be wanted. For example if you wanted to use the servo outputs to drive another kind of PWM device. + +To allow for this, the parameters `init_motors=False`, `init_servos=False`, and `init_i2c=False` can be added when creating the `Inventor2040W` object. + +```python +board = Inventor2040W(init_motors=False, init_servos=False, init_i2c=False) +``` + +This leaves `board.motors`, `board.encoders`, `board.servos` and `board.i2c` set to `None`, letting you to use those board pins for any other purpose. + +The pins available after this are: + +* `board.I2C_SDA_PIN` = `4` +* `board.I2C_SCL_PIN` = `5` +* `board.MOTOR_A_PINS` = `(6, 7)` +* `board.MOTOR_B_PINS` = `(8, 9)` +* `board.ENCODER_A_PINS` = `(19, 18)` +* `board.ENCODER_B_PINS` = `(17, 16)` +* `board.SERVO_1_PIN` = `10` +* `board.SERVO_2_PIN` = `11` +* `board.SERVO_3_PIN` = `12` +* `board.SERVO_4_PIN` = `13` +* `board.SERVO_5_PIN` = `14` +* `board.SERVO_6_PIN` = `15` + + +### Constants + +#### Pin Constants + +The `inventor` module contains constants for the IO pins: + +* `GP0` = `0` +* `GP1` = `1` +* `GP2` = `2` +* `A0` = `26` +* `A1` = `27` +* `A2` = `28` + +There are also tuple constants with various pins grouped together: + +* `GPIOS` = `(GP0, GP1, GP2, A0, A1, A2)` +* `ADCS` = `(A0, A1, A2)` + + +#### Index Constants + +The `inventor` module contains index constants for the motors, servos and LEDs: + +* `MOTOR_A` = `0` +* `MOTOR_B` = `1` + +* `SERVO_1` = `0` +* `SERVO_2` = `1` +* `SERVO_3` = `2` +* `SERVO_4` = `3` +* `SERVO_5` = `4` +* `SERVO_6` = `5` + +* `LED_GP0` = `0` +* `LED_GP1` = `1` +* `LED_GP2` = `2` +* `LED_A0` = `3` +* `LED_A1` = `4` +* `LED_A2` = `5` +* `LED_SERVO_1` = `6` +* `LED_SERVO_2` = `7` +* `LED_SERVO_3` = `8` +* `LED_SERVO_4` = `9` +* `LED_SERVO_5` = `10` +* `LED_SERVO_6` = `11` + + +#### Count Constants + +The `inventor` module also contains count constants for helping with iterating over multiple features: + +* `NUM_GPIOS` = `6` +* `NUM_ADCS` = `3` +* `NUM_MOTORS` = `2` +* `NUM_SERVOS` = `6` +* `NUM_LEDS` = `12` \ No newline at end of file diff --git a/micropython/modules_py/inventor.py b/micropython/modules_py/inventor.py index 23dc53cf..f7ba9ab9 100644 --- a/micropython/modules_py/inventor.py +++ b/micropython/modules_py/inventor.py @@ -1,6 +1,5 @@ import gc -from machine import Pin, PWM -from pimoroni_i2c import PimoroniI2C +from machine import Pin, PWM, I2C from plasma import WS2812 from motor import Motor from servo import Servo @@ -54,6 +53,7 @@ NUM_LEDS = 12 class Inventor2040W(): AMP_EN_PIN = 3 + I2C_ID = 0 I2C_SDA_PIN = 4 I2C_SCL_PIN = 5 MOTOR_A_PINS = (6, 7) @@ -75,12 +75,13 @@ class Inventor2040W(): AMP_CORRECTION = 4 DEFAULT_VOLUME = 0.2 - def __init__(self, motor_gear_ratio=50, init_motors=True, init_servos=True): + def __init__(self, motor_gear_ratio=50, init_motors=True, init_servos=True, init_i2c=True, i2c_baudrate=100000): # Free up hardware resources gc.collect() # Set up the motors and encoders, if the user wants them self.motors = None + self.encoders = None if init_motors: cpr = MMME_CPR * motor_gear_ratio self.motors = [Motor(self.MOTOR_A_PINS), Motor(self.MOTOR_B_PINS)] @@ -94,7 +95,9 @@ class Inventor2040W(): self.servos = [Servo(i) for i in range(self.SERVO_1_PIN, self.SERVO_6_PIN + 1)] # Set up the i2c for Qw/st and Breakout Garden - self.i2c = PimoroniI2C(self.I2C_SDA_PIN, self.I2C_SCL_PIN, 100000) + self.i2c = None + if init_i2c: + self.i2c = I2C(self.I2C_ID, self.I2C_SDA_PIN, self.I2C_SCL_PIN, i2c_baudrate) # Set up the amp enable self.__amp_en = Pin(self.AMP_EN_PIN, Pin.OUT) @@ -120,14 +123,14 @@ class Inventor2040W(): self.play_silence() raise ValueError("frequency of range. Expected greater than 0") - corrected_volume = (self.__volume ** 4) # Correct for RC Filter curve + corrected_volume = (self.__volume ** self.AMP_CORRECTION) # Correct for RC Filter curve self.audio_pwm.duty_u16(int(32768 * corrected_volume)) self.unmute_audio() def play_silence(self): self.audio_pwm.freq(44100) - corrected_volume = (self.__volume ** 4) # Correct for RC Filter curve + corrected_volume = (self.__volume ** self.AMP_CORRECTION) # Correct for RC Filter curve self.audio_pwm.duty_u16(int(32768 * corrected_volume)) self.unmute_audio()