======== Overview ======== This project uses Python and MicroPython for control of up to four DFRobot 12V DC brushless motors (model number FIT0441). It is designed for use with a Raspberry Pi but could be adapted to any hardware with similar capabilities. The DFRobot brushless motors require a Pulse-Width Modified (PWM) signal to control their speed, in an inverted mode: when fed a 100% duty cycle the motor is stopped, a 50% duty cycle is half speed, a 0% duty cycle is full speed. Because the Raspberry Pi is a user-space OS rather than an RTOS, its software PWM is not particularly stable, as it is influenced by system load. The Pi has only two channels of hardware PWM available. Therefore, if you are trying to control more than two motors you'll need either an external PWM board or connect to a microcontroller over a UART. In this latter mode the project supports either an RP2040 or an STM32 (i.e., the STM32H562, though it could with some pin configuration changes be used with others). Installation ------------ The Python files for the project are located in the root directory, ``core``, ``hardware`` and ``uart`` directories. The ``upy`` directory contains the contents to be uploaded to the microcontroller. Also, depending on your implementation choices you will be able to trim unused files. ====== Pinout ====== Here are the pin configurations for connecting a Raspberry Pi to a STM32H562. UART Pins --------- This uses a custom build of MicroPython for the STM32H562, whose board definition can be found at `mp-weact-stm32h562 `__. The pins used for this implementation are defined in the board definition. The STM32H562 build defines UARTs 1-3. UART 1 is discouraged as it is used to print console communications over ``/dev/serial0`` when connected to the board (e.g., over rshell). UART 4's pins conflict with the SD card so support for it as not built into MicroPython for the STM32H562. Therefore, only UART 2 or UART 3 are suitable: UART 2 is configured as the default. +--------+-------+-------+ | UART | TX | RX | +========+=======+=======+ | UART1 | PA9 | PA10 | +--------+-------+-------+ | UART2 | PA2 | PA3 | +--------+-------+-------+ .. note:: You cannot specify tx/rx pins in MicroPython's ``UART()`` constructor; it will use the defined pins for each. The primary UART on the Raspberry Pi is GPIO 14 (TX) and GPIO 15 (RX). Using UART 2, GPIO 14 is therefore connected to PA3, GPIO 15 to PA2. If using a NeoPixel or NeoPixel strip, it is connected to PA1. This is currently hard-coded in the ``upy/pixel.py`` class. +----------+-------+ | Device | Pin | +==========+=======+ | NeoPixel | PA1 | +----------+-------+ Motor Pins ---------- Apart from power, there are three connections to each motor: a PWM pin used for speed control; a direction pin that sets the motor direction; and an encoder feedback pin whose ticks indicate motor rotation. Hardware Timers on the STM32 have four channels. We use all four channels of a Timer to supply our PWM signals. +----+------+--------+---------+---------+---------+--------+ | Id | Name | PWM Ch | PWM Pin | Dir Pin | Enc Pin | Enc Ch | +====+======+========+=========+=========+=========+========+ | 0 | M0 | 1 | PB6 | B12 | PC6 | | +----+------+--------+---------+---------+---------+--------+ | 1 | M1 | 2 | PB7 | B14 | PC7 | | +----+------+--------+---------+---------+---------+--------+ | 2 | M2 | 3 | PB8 | B3 | PB0 | | +----+------+--------+---------+---------+---------+--------+ | 3 | M3 | 4 | PB9 | B5 | PB1 | | +----+------+--------+---------+---------+---------+--------+ All four motors use the same PWM Timer (4). ======= Modules ======= This project documentation intermixes the CPython and MicroPython code indescriminately. To differentiate, check the ``upy`` directory, which contains all the MicroPython code. .. automodule:: core.component :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: core.config_loader :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: core.globals :members: :undoc-members: :show-inheritance: :exclude-members: has, get, put, init .. automodule:: core.logger :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: core.util :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.brushless_motor :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.controller_channel :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.digital_pot_async :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.payload :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.pwm_controller :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.pwm_controller_impl :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.rotary_encoder :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.slew_limiter :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.stm32_pwm_controller :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.tlc59711 :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.tlc59711_pwm_controller :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: hardware.value_provider :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: stop_motor :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: temp.source.conf :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: uart.async_uart_manager :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: uart.crc8_table :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: uart.payload :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: uart.sync_uart_manager :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: uart.uart_master :members: :undoc-members: :show-inheritance: :exclude-members: main, init .. automodule:: uart_driver :members: :undoc-members: :show-inheritance: :exclude-members: main, init