4. MiniBit module

Pins for the motors are below.

Pin

Purpose

pin12

Left Motor

pin8

Left Motor Backwards

pin14

Right Motor

pin16

Right Motor Backwards

pin15

Ultrasonic

Write a module for the MiniBit that uses classes.
  • a class for motors using pin12, pin8, pin14, pin16

  • a class for ultrasonic sensor using pin15

The module will be named MiniBit.py.
Code using the module will typically begin with:
from microbit import *
import MiniBit
Each class will be named systematically, using MiniBit in their names.
Objects for each class will be created when setting up the MiniBit.
from microbit import *
import MiniBit

buggy = MiniBit.MiniBitMotors()
distance_sensor = MiniBit.MiniBitDistanceSensor()

4.1. Install module

The MiniBit module is required to control the MiniBit buggy.
Download the python file MiniBit.py module.
Place it in the mu_code folder: C:\Users\username\mu_code
The file needs to be copied onto the microbit.
In Mu editor, with the microbit attached by USB, click the Files icon.
Files on the microbit are shown on the left.
Files in the mu_code folder are listed on the right.
Click and drag the maqueen.py file from the right window to the left window to copy it to the microbit.
The images below are for the maqueen, but illustrate the idea.
Before copying:
../../_images/Mu_files2.png

After copying:

../../_images/Mu_files_copied2.png

4.2. Module code

The module is shown below.
  1# MiniBit module for motors, and distance sensing
  2# requires microbit v2
  3# GMC-code; 2022-4
  4# The MIT License (MIT)
  5
  6# A microbit v2 micropython module
  7# speed from -10 to 10
  8
  9
 10from microbit import *
 11import utime
 12
 13# constants
 14LMF = pin12
 15LMB = pin8
 16RMF = pin16
 17RMB = pin14
 18DSP = pin15
 19                   
 20class MiniBitMotors:
 21
 22    def __init__(self):
 23        # no need to do anything
 24        pass
 25
 26    def stop(self):
 27        LMF.write_digital(0)
 28        LMB.write_digital(0)
 29        RMF.write_digital(0)
 30        RMB.write_digital(0)
 31
 32    @staticmethod
 33    def scale(from_value, from_min, from_max, to_min, to_max):
 34        return int(((from_value - from_min) / (from_max - from_min)) * (to_max - to_min) + to_min)
 35
 36    @staticmethod
 37    def speed_scaled(speed):
 38        return __class__.scale(speed, 0, 10, 0, 1023)
 39        
 40    def forwards(self, speed=2, duration=None):
 41        analog_speed = self.speed_scaled(speed)
 42        LMF.write_analog(analog_speed)
 43        LMB.write_digital(0)
 44        RMF.write_analog(analog_speed)
 45        RMB.write_digital(0)
 46        if duration is not None:
 47            utime.sleep_ms(duration)
 48            self.stop()
 49
 50    def backwards(self, speed=2, duration=None):
 51        analog_speed = self.speed_scaled(speed)
 52        LMF.write_digital(0)
 53        LMB.write_analog(analog_speed)
 54        RMF.write_digital(0)
 55        RMB.write_analog(analog_speed)
 56        if duration is not None:
 57            utime.sleep_ms(duration)
 58            self.stop()
 59
 60    @staticmethod
 61    def inner_turn_speed(speed, tightness=2):
 62        if tightness == 0:
 63            return 0
 64        else:
 65            return int(speed / tightness)
 66
 67
 68    def left(self, speed=2, tightness=2, duration=None):
 69        outer_speed = speed_scaled(speed)
 70        inner_speed = inner_turn_speed(outer_speed, tightness)
 71        if speed > 0:
 72            LMF.write_analog(inner_speed)
 73            LMB.write_digital(0)
 74            RMF.write_analog(outer_speed)
 75            RMB.write_digital(0)
 76        else:
 77            LMF.write_digital(0)
 78            LMB.write_analog(-inner_speed)
 79            RMF.write_digital(0)
 80            RMB.write_analog(-outer_speed)
 81        if duration is not None:
 82            utime.sleep_ms(duration)
 83            stop()
 84
 85
 86    def right(self, speed=2, tightness=2, duration=None):
 87        outer_speed = self.speed_scaled(speed)
 88        inner_speed = self.inner_turn_speed(outer_speed, tightness)
 89        if speed > 0:
 90            LMF.write_analog(outer_speed)
 91            LMB.write_digital(0)
 92            RMF.write_analog(inner_speed)
 93            RMB.write_digital(0)
 94        else:
 95            LMF.write_digital(0)
 96            LMB.write_analog(-outer_speed)
 97            RMF.write_digital(0)
 98            RMB.write_analog(-inner_speed)
 99        if duration is not None:
100            utime.sleep_ms(duration)
101            self.stop()
102
103    def spin_left(self, speed=2, duration=None):
104        analog_speed = self.speed_scaled(speed)
105        LMF.write_digital(0)
106        LMB.write_analog(analog_speed)
107        RMF.write_analog(analog_speed)
108        RMB.write_digital(0)
109        if duration is not None:
110            utime.sleep_ms(duration)
111            self.stop()
112
113    def spin_right(self, speed=2, duration=None):
114        analog_speed = self.speed_scaled(speed)
115        LMF.write_analog(analog_speed)
116        LMB.write_digital(0)
117        RMF.write_digital(0)
118        RMB.write_analog(analog_speed)
119        if duration is not None:
120            utime.sleep_ms(duration)
121            self.stop()
122
123
124class MiniBitDistanceSensor():
125
126    def distance(self):
127        DSP.write_digital(1)
128        utime.sleep_us(10)
129        DSP.write_digital(0)
130
131        while DSP.read_digital() == 0:
132            pulse_start = utime.ticks_us()
133        while DSP.read_digital() == 1:
134            pulse_end = utime.ticks_us()
135
136        try:
137            pulse_duration = pulse_end - pulse_start
138        except ValueError:
139            pulse_duration = 0
140        else:
141            pulse_duration = 0
142
143        distance = int(0.01715 * pulse_duration)
144        return distance
145