SparkFun moto: bit I2C operation and use from MicroPython

Trigger

I got SparkFun moto: bit which is a kind of motor driver for micro: bit.

IMG_4065.JPG

It may be cheaper than Kitronik's motor driver board, but when you look at the base, GPIO is directly connected to the motor driver IC. It doesn't look like it. If you refer to the Circuit diagram, the PSoC processes the instructions sent by I2C and the motor driver It seems that it has become an intelligent thing to control.

It's nice to be able to control the motor without consuming other I / O pins, but the interface available is only provided by Microsoft's Makecode. I wanted to use it from MicroPython, so I examined the implementation of the block for Makecode and how it is controlled by I2C.

The source of the moto: bit block (TypeScript) can be found below.

https://github.com/sparkfun/pxt-moto-bit/blob/master/motobit.ts

Survey results

I2C address

The I2C address is 0x59 (89)

Format of control information sent by I2C

All are 2-byte configurations. The first byte is the control type, and the second byte is the parameter.

Specifying speed

When specifying the speed of the left motor (LEFT MOTOR), the first byte is 0x21, and when specifying the speed of the right motor (RIGHT MOTOR), the first byte is 0x20.

In the second byte, specify the direction of travel and speed.

Inversion designation of the direction of travel

There is a specification to reverse the forward / backward movement of the motor.

When the left motor (LEFT MOTOR) is specified to be inverted, the first byte is 0x13, and when the right motor (RIGHT MOTOR) is specified to be inverted, the first byte is 0x12.   The second byte is the specification of whether to invert or not. If it is 1, it is inverted, and if it is 0, the inversion is stopped (restored).

Specifying whether to enable / disable the motor

When enabling / disabling the motor, the first byte is 0x70.

The second byte is the specification of enable / disable. If it is 1, it will be enabled, and if it is 0, it will be disabled.

That's why I created the MycroPython library

Source code

from microbit import i2c


class Motor:
    # command
    LEFT = 0x21
    RIGHT = 0x20
    LEFT_INVERT = 0x13
    RIGHT_INVERT = 0x12
    ENABLE = 0x70

    # direction
    FORWARD = 0x80
    REVERSE = 0x00

    # i2c
    _I2C_ADDR = 0x59
    _I2C_SDA = 20
    _I2C_SCL = 19
    _i2c_buf = bytearray(2)

    def __init__(self, motor):
        self.motor = motor

    def set_speed(self, speed, direction=FORWARD):
        pwr = speed * 127 // 100
        Motor._i2c_buf[0] = self.motor
        Motor._i2c_buf[1] = (pwr | direction) \
                            if direction == Motor.FORWARD else (127 - pwr)
        i2c.write(Motor._I2C_ADDR, Motor._i2c_buf)

    def invert(self, invert):
        if self.motor == Motor.LEFT:
            Motor._i2c_buf[0] = Motor.LEFT_INVERT
        else:
            Motor._i2c_buf[0] = Motor.RIGHT_INVERT
        Motor._i2c_buf[1] = int(invert)
        i2c.write(Motor._I2C_ADDR, Motor._i2c_buf)

    @staticmethod
    def enable():
        Motor._i2c_buf[0] = Motor.ENABLE
        Motor._i2c_buf[1] = 1
        i2c.write(Motor._I2C_ADDR, Motor._i2c_buf)

    @staticmethod
    def disable():
        Motor._i2c_buf[0] = Motor.ENABLE
        Motor._i2c_buf[1] = 0
        i2c.write(Motor._I2C_ADDR, Motor._i2c_buf)


motor_left = Motor(Motor.LEFT)
motor_right = Motor(Motor.RIGHT)

I also put the source on github.

https://github.com/MinoruInachi/micropython-microbit-mylib/blob/master/motobit.py

How to use

Module import

import motobit

API

motobit.Motor.enable()

Activate the motor.

motobit.motor_left.set_speed(speed, direction=Motor.FORWARD)

Set the speed of the left motor. speed: Specify the motor speed as 0-100. 100 is the maximum speed direction: Move forward with Motor.FORWARD, move backward with Motor.REVERSE

motobit.motor_right.set_speed(speed, direction=Motor.FORWARD)

Set the speed of the right motor. speed: Specify the motor speed as 0-100. 100 is the maximum speed direction: Move forward with Motor.FORWARD, move backward with Motor.REVERSE

motobit.motor_left.invert(invert)

Set whether to reverse the direction of travel of the left motor. invert: True --Invert, False --Do not invert

motobit.motor_left.invert(invert)

Set whether to reverse the direction of travel of the right motor. invert: True --set to invert, False --not set to invert

motobit.Motor.disable()

Disable the motor.

Sample code

Do the same thing in MicroPython as "Experiment 1: Driving and Turning" on the SparkFun site This is the code I wrote.

from microbit import button_a, sleep
from microbot import *

while True:
    if button_a.is_pressed():
        Motor.enable()
        motor_left.set_speed(100)
        motor_right.set_speed(100)
        sleep(1000)
        motor_left.set_speed(100, Motor.REVERSE)
        motor_right.set_speed(100)
        sleep(200)
        motor_left.set_speed(100)
        motor_right.set_speed(100)
        sleep(1000)
        Motor.disable()

Digression

  1. micro: bot kit using this moto: bit goes in the BACK direction in Forward and in the FRONT direction in Reverse. I will. At first, I wondered if it was assembled incorrectly, but SparkFun's Experimental Video also works that way. It's terrible.

  2. When I used microbit.i2c.init () in the MicroPython documentation, I got an error if it wasn't defined. Well, the default (freq = 100000, sda = pin20, scl = pin19) is fine. According to the history of github, it was added on 2016/11/11, but it seems that it has not been reflected in the development environment yet.

  3. It's a pity that the MicroPython documentation wasn't translated into Japanese on the official site of ~~ micro: bit. Arbitrary translation is available. ~~ Japanese document was officially linked.

Recommended Posts

SparkFun moto: bit I2C operation and use from MicroPython
Read and use Python files from Python
Bit operation
Use dein.vim and ckw-mod with Windows7 32bit PowerShell