Pi2Go Mk2 Programming

Programming the Pi2Go Mk 2

Preparing your Raspberry Pi

Before you can install the Pi2Go Mk 2 software, you will need to ensure that your Raspberry Pi is up and running and connected to the internet. You will need to be able to see the desktop or console (either using direct connections, or SSH or VNS over the network).

NOTE: Please use Raspberry Pi OS (Legacy, 32-bit) – i.e. Bullseye version

Setting up a Raspberry Pi is not covered here. It is best to get the information from the source at Raspberry Pi

You will also need to enable SPI and I2C. Do this from raspi-config

sudo raspi-config

Select interfaces and enable both SPI and I2C. Then reboot.

ScratchGPIO is not supported in recent RPi OS builds

Simplesi (Simon Walters) has generously included Pi2Go Mk2 in the list of directly supported devices in ScratchGPIO.

Visit this blog post for installation and coding tips

Installing the Pi2Go Mk2 Python2 Software

NB. Note that this software is still in Python 2. If you are using Python3, then note that Python 3 will not work in some of the scripts due to Print statements. You can easily change the code by following the porting guide here

First you will need to prepare your Pi for the Fireleds (fully compatible with neopixels). Install the rpi_ws281x package (this works with Raspberry Pi OS Legacy, 32-bit – i.e. Bullseye version):

sudo pip install rpi_ws281x

Download the Python library module and example software for Pi2Go Mk2 with

wget https://4tronix.co.uk/pi2go2.sh -O pi2go2.sh

bash pi2go2.sh

This installs the following, which should be run in Python 2 for now (unless otherwise stated)

  • ipd.desktop in home/pi/.config/autostart which will start the IP Display on boot. This will silently fail if the optional IP Display is not plugged into either port.
  • Creates a folder home/pi/pi2go2 for all the example files and library module pi2go2.py (the main library module)
  • motorTest.py to demonstrate driving the motors. Must be run in a terminal, not from an IDE like Idle or Thonny. Use LXTerminal for this
  • stepTest.py to demonstrate running motors controlled by the wheel sensors. Must be run in a terminal, not from an IDE like Idle or Thonny. Use LXTerminal for this
  • adc.py shows the light sensor values and raw battery voltage
  • ledTest.py flashes all LEDs through Red, Green, Blue and White. This must be run using sudo. ie: sudo python3 ledTest.py
  • rainbow.py sets the LEDs to rainbow colours (static, but flashes every 10 seconds). This must be run using sudo in Python 3. ie: sudo python3 rainbow.py
  • lineTest.py shows the value of the line sensors
  • lineFollower.py is very basic line follower program
  • sonarTest.py shows the distance in cm for an obstacle using the optional ultrasonic breakout in either or both expansion slots
  • ipd03.py this is the program run on boot up to display the IP address of the Pi to make it easy to connect to using VNC or SSH

Using the Pi2go2.py Library Module

To use this module, you must first import it into your program using

import pi2go2

Then, before using any other functions you should call the init ( ) function to initialise all the variables used by the library. The init ( ) function has an optional parameter which is the default brightness of the LEDs. If omitted, this defaults to 40. So the following call will initialise the library and set the default brightness to 100:

pi2go2.init (100)

Hot Tip:
As a special case, if you set the brightness to zero, then the LEDs are not initialised. As this would require use of the sudo command, it can be beneficial to call init (0) so that your program can be run without using sudo.

When your program has finished, it is good practice to close down everything tidily by calling:

pi2go2.cleanup ( )

Motor Functions

  • stop ( ): Stops both motors – coast slowly to a halt
  • brake ( ): Stops both motors – brakes quickly
  • forward (speed): Sets both motors to move forward at speed. 0 <= speed <= 100
  • reverse (speed): Sets both motors to reverse at speed. 0 <= speed <= 100
  • spinLeft (speed): Sets motors to turn opposite directions at speed. 0 <= speed <= 100
  • spinRight (speed): Sets motors to turn opposite directions at speed. 0 <= speed <= 100
  • turnForward (leftSpeed, rightSpeed): Moves forwards in an arc by setting different speeds. 0 <= leftSpeed,rightSpeed <= 100
  • turnreverse (leftSpeed, rightSpeed): Moves backwards in an arc by setting different speeds. 0 <= leftSpeed,rightSpeed <= 100

Wheel Sensor Functions

  • stepForward (speed, steps): Moves forwards specified number of steps, then stops
  • stepReverse (speed, steps): Reverses specified number of steps, then stops
  • stepSpinL (speed, steps): Spins left specified number of steps, then stops
  • stepSpinR (speed, steps): Spins right specified number of steps, then stops

RGB LED Functions

  • setColor (color): Sets all LEDs to color – requires show()
  • setPixel (ID, color): Sets pixel ID to color – requires show()
  • show ( ): Updates the LEDs with state of LED array
  • clear ( ): Clears all LEDs to off – requires show()
  • rainbow ( ): Sets the LEDs to rainbow colors – requires show()
  • fromRGB (red, green, blue): Creates a color value from R, G and B values
  • toRGB (color): Converts a color value to separate R, G and B
  • wheel (pos): Generates rainbow colors across 0-255 positions

IR Sensor Functions

  • irLeft ( ): Returns state of Left IR Obstacle sensor
  • irRight ( ): Returns state of Right IR Obstacle sensor
  • irAll ( ): Returns true if either of the Obstacle sensors are triggered
  • irLeftLine ( ): Returns state of Left IR Line sensor
  • irRightLine ( ): Returns state of Right IR Line sensor

UltraSonic Function

  • getDistance (sonar = 0). Returns the distance in cm to the nearest reflecting object. 0 == no object. Sonar 0 is the front connector, Sonar=1 is the side connector. If you don’t include the parameter it defaults to 0 (front)

    Analog and Light Sensor Functions

  • getLight (Sensor). Returns the value 0..1023 for the selected sensor, 0 <= Sensor <= 3
  • getLightFL ( ). Returns the value 0..1023 for Front-Left light sensor
  • getLightFR ( ). Returns the value 0..1023 for Front-Right light sensor
  • getLightBL ( ). Returns the value 0..1023 for Back-Left light sensor
  • getLightBR ( ). Returns the value 0..1023 for Back-Right light sensor
  • getBattery ( ). Returns the voltage of the battery pack (>7.2V is good, less is bad)

    Switch Function

  • getSwitch ( ). Returns the value of the tact switch: True == pressed

Pi2Go Mk 2 Home Page

Links

Overview

The Pi2Go Mk2 is the evolution of the very popular original Pi2Go, first shipped in April 2015. The major changes are:

  • Improved assembly method, particularly the motor mounts
  • No wires for attaching the battery packs
  • Better quality wheels with high grip tyres
  • Wheel sensors built into both wheels
  • Programmatic access to the raw battery voltage
  • Improved analog light sensors – one in each corner
  • 10 individually addressable Smart RGB LEDs
  • 2 edge connectors compatible with Pimoroni’s Breakout Garden with full access to I2C signals and individual GPIO signals
  • Improved motor controller allowing higher speeds and optional braking on stop
  • Now with 4WD option

 

Specification

  • Requires 6 x AA rechargeable battery cells (not included)
  • Supports all versions of 40-pin Raspberry Pi
    (NB. the Raspberry Pi 4 consumes a lot of power and it is recommended to use one of the optional 7 x AA, or 2 x 18650 battery boards)
  • Motor controller: DRV8833
  • Analog input (light sensors and battery) MCP3008
  • Switching 5V power supply using TPS5430
  • 10 x SK6812-3535 Smart RGB LEDs (compatible with neopixels) – on battery board
  • On/Off switch with Blue indicator LED – on battery board
  • 2 x TCRT5000 infra-red obstacle sensors (front corners)
  • 4 x SFH3710 light sensors (all 4 corners)
  • 2 x TCRT5000 infra-red line follower sensors
  • 6mm tact switch for programmatic use
  • 4 x servo connections – direct from GPIO pins, with 5V and Gnd signals
  • 2 x optical wheel sensors with 20 slot encoder wheels (ie. 20 pulses per revolution)
  • 2 slots for breakout boards, including ultrasonic distance sensor and IP Display. These slots are compatible with Pimoroni’s Breakout Garden range.
  • Overall size with wheels attached: 148 x 118 x 98mm (length x width x height)
  • Weight (excluding Raspberry Pi & batteries): 282g

 

GPIO Connections

(Broadcom numbering)

  • Left Motor: 26, 19
  • Right Motor: 21, 16
  • Smart RGB LEDs: 18
  • Left Obstacle Sensor: 22
  • Right Obstacle Sensor: 17
  • Left Line Sensor: 23
  • Right Line Sensor: 27
  • Front ultrasonic (or general I/O): 20
  • Side ultrasonic (or general I/O): 4
  • Tact switch: 15
  • Left wheel sensor: 5
  • Right wheel sensor: 6
  • Servos: 12, 13, 24, 25

 

MiniBit

MiniBit Entry-Level Robot for Microbit

Purchase here

Overview

MiniBit is a ready-assembled simple and inexpensive robot for the BBC micro:bit.

It has the following features:

  • Ready-assembled. Just push on the wheels
  • Edge connector to easily insert the Microbit
  • Micro metal gear motors with fully-enclosed gearbox (no grit or fluff can enter)
  • Wire-free battery holder for 3 x AA batteries
  • 4 x Smart RGB LEDs (neopixel compatible)
  • Integrated Pen holder for 10mm diameter pens (eg. Sharpie felt tips)
  • Robust On/Off switch with Blue indicator LED
  • Wide chunky wheels with lots of grip
  • Metal ball front caster
  • Connector for optional ultrasonic sensor or I2C breakouts (fully compatible with Pimoroni’s Breakout Garden range)
  • The Microbit pins 0, 1, 2, Gnd and 3V are available for use with croc clips etc.
  • Lots of mounting holes to create your own “body” for the robot or additional sensors etc.
  • Makecode extension and micropython examples available

Batteries

Please use Alkaline batteries. Rechargeable batteries do not provide sufficient voltage once they have started to deplete. This primarily affects the ultrasonic sensor, so you may be okay to use with the other functions even when the batteries get low

Coding Your MiniBit

Calibrating the Motors (v1.3 or later Only)

For version 1.3 of Minibit we have added code and hardware to help calibrate the motors on either side so that they match speeds better. Once the motors are calibrated, the calibration values are permanently remembered on the Minibit, so even using different Microbits and different programs, you will still get the matched motors. For this to work you must use the latest Minibit Makecode extension.

The calibration Makecode program can be downloaded from >here<. Load it into your Makecode editor and download to the Microbit on the Minibit v1.3 or later.

Process: The calibration program starts at speed 30 (displaying 3 on the Microbit LEDs). You then set the left or right speeds until it is driving straight. Then give the Minibit a good shake and it will change to speed 60 (displaying 6). Set this speed, shake again to change to speed 90 (displaying 9). Once this speed is set correctly, shake again and it will return to speed 30. You can then switch off and all the values are stored. If you run the program again, you will start from the un-calibrated values and must follow all the steps again.

  • Load the program into the Microbit and plug it into the Minibit
  • Switch on the Minibit. It will display 13 (indicating a v1.3 Minibit), then change to show 3 (meaning speed 30)
  • Press A or B buttons to affect the turning left or right, then press both A+B simultaneously and the Microbit will display the current calibration value, then move forward for 2 seconds at speed 30.
  • If it is still not moving straight, press the appropriate button one or more times to straighten it up, then press A+B again to test it
  • When you’re happy that it is moving straight, give the Minibit a shake and it will store the values for speed 30 and move onto Speed 60.
  • Repeat for speed 60 and speed 90

Microsoft MakeCode

Click any image to enlarge.

To load the extension, select Advanced, then Extensions. Then enter “Minibit” into the search box and press Enter. If that doesn’t find it (there are sometimes earch glitches) you can enter the full URL into the search box: “https://github.com/4tronix/MiniBit”

NB. This post is being updated to relate to the new functions added (Feb 2020). Images may not match the text.

Once loaded, you will have a MiniBit menu item with 4 sub-folders: Motors, FireLeds, Sensors, Addons

Motor Blocks

The “New style block” section contains command for basic movements eg. “Go Forwards/Reverse at speed 60” or “Rotate Left/Right at speed 40 for 700 ms”. All the commands in this section use speeds from 0 to 100 inclusive.

Both the “Go” and the “Rotate” blocks have a paired block that will do the command for a selected amount of time and then stop

There are two ways of stopping. Coasting to a stop or braking. If you set the speed to 0 or use the “stop with no brake” command, then it will stop gently over the coourse of a second or so depending on initial speed). If you use the “stop with brake” block (or the go/rotate for a time block) then it will stop almost immediately.

You can also drive each motor individually using the “Move Left/Right/Both motors…” block. For instance if you set the left motor to drive at 600 and the right motor to drive at 1000, then it will perform an arc towards the left

We have introduced a new command to bias the driving in one direction or the other. This is to counteract any mismatch between the motors. So if your robot drifts over the left when you want it to go straight, then add a bias to the Right. At a speed of 60, a bias of 10% is roughly equal to 10 cms or so.

FireLed Blocks

You can use these blocks to set and clear one or all the FireLeds.

Using the “Enable Bluetooth” block at the top level you can disable the Fireleds. The Bluetooth software for Microbit is not compatible with Fireleds (like neopixels and all such LEDs) so you should switch off the Fireleds using this block if you want to use the Microbit Bluetooth functionality.

Note that the MiniBit defaults to automatically updating the FireLeds whenever any change is made, but you can change this behaviour by setting the update mode to manual. Then you would have to run the “Show LED changes” block after making any changes to the LED settings.

The LEDs on the MiniBit are labelled from 0 to 3. Use these numbers in the Makecode blocks to change the colour. eg setting LED 1 to Purple could be done like this:

The default brightness level is 40. This is plenty bright enough for most uses, saves damaging eyes, and reduces battery consumption. If required you can change the brightness from 0 up to 255

In the Advanced section of FireLeds :

Set update mode is used to switch between automatic LED updates or manual LED updates. The default is for automatic updates: every change to the LEDs results in all the LEDs being written to with the updated values. This is easy to understand, but it does mean that when making a lot of changes it can slow things down considerably. If doing that, it is best to use Manual update mode, make all the changes required, then use the show LED changes block to make all the updates in one go.

Rotate LEDs block will move the colour in LED 0 to LED 1, LED1 to LED2, LED2 to LED3 and LED3 to LED0. If done repeatedly, with a delay between each one, it will show the LED colours rotating around all the 4 LEDs.

Shift LEDs block will move LED0 to LED1, LED1 to LED2 and LED2 to LED3. It will blank LED0. So all the colours will disappear one at a time from 0 to 3

You can also create your own colours and replace the fixed list of colours in any command using the convert from red, green, blue block. For example, to set LED0 to a blue-green colour:

Sensor Blocks

Ultrasonic distance sensor: You can get the values to the nearest object in cm, inches or microseconds. This block returns a number that you can put into a variable or use it directly in a calculation or test

Line sensors: This optional accessory has 3 sensors: left, centre and right. These are connected directly to Pin 0, 1 and 2 of the Microbit. There are two ways of using the sensors: a) read the current value and check it’s state before deciding what to do, or b) use a block that only gets run when the requested event occurs. eg: when the left sensor finds a (black) line

More Blocks

These are the advanced usage blocks. Most students will not need to use them.

  • Set update mode is used to switch between automatic LED updates or manual LED updates. The default is for automatic updates: every change to the LEDs results in all the LEDs being written to with the updated values. This is easy to understand, but it does mean that when making a lot of changes it can slow things down considerably. If doing that, it is best to use Manual update mode, make all the changes required, then use the show LED changes block to make all the updates in one go.
  • Rotate LEDs block will move the colour in LED 0 to LED 1, LED1 to LED2, LED2 to LED3 and LED3 to LED0. If done repeatedly, with a delay between each one, it will show the lED colours rotating around all the 4 LEDs.
  • Shift LEDs block will move LED0 to LED1, LED1 to LED2 and LED2 to LED3. It will blank LED0. So all the colours will disappear one at a time from 0 to 3
  • You can also create your own colours and replace the fixed list of colours in any command using the convert from red, green, blue block. For example, to set LED0 to a blue-green colour:

Programming in microPython

Driving Motors

The motors use 2 pins each to determine the speed and direction. In microPython we use write_analog ( ) to set the first pin to a value between 0 and 1023 and the second pin to 0 in order to go forward. To reverse, we swap the pins so that the first pin is set to 0 and the second pin is set to the value.

On the MiniBit the left motor uses pins 12 and 8, and the right motor uses pins 16 and 14.

So to move the left motor forwards at speed 600:

pin12.write_analog(600)
pin8.write_digital(0)

And to move the right motor in reverse at speed 450:

pin16.write_digital(0)
pin14.write_analog(450)

To stop with no brake, use write_digital ( ) to set both pins to 0. To stop with brake, set both pins to 1.
eg. stop left motor with coasting and right motor with brake:

pin12.write_digital(0)
pin8.write_digital(0)

pin16.write_digital(1)
pin14.write_digital(1)

So a complete, but fairly useless, program to drive the motors for 2 seconds and then stop quickly, would look like this:

from microbit import *
pin12.write_analog(600)
pin8.write_digital(0)
pin16.write_analog(600)
pin14.write_digital(0)
sleep(2000)
pin12.write_analog(0) # temporary fix for python bug
pin12.write_digital(1)

pin8.write_digital(1)
pin16.write_analog(0) # temporary fix for python bug
pin16.write_digital(1)

pin14.write_digital(1)

Note the 2 lines that write_analog(0) before swapping a pin from analog to digital. These are required until a fix is obtained for the python PWM driver continually updating the pin type to analog

Lighting the LEDs

This uses the standard neopixel code, with the LEDs connected to Pin 13.

At the top of your program add import neopixel then:

leds = neopixel.NeoPixel(13, 4)

leds is then an array of all 4 LEDs. leds[0] refers to the LED 0 and leds[3] refers to LED3. Each element of the array is a set of 3 numbers representing the Red, Green and Blue values (each 0..255) for that LED. So to set LED2 to Blue:

leds[2] = (0, 0, 255)

All this does is update the array. To show the new value of the array, we need to call the show ( ) function as follows:

leds.show ( )

Reading the Ultrasonic Distance Sensor

The ultrasonic sensor breakout is on pin15.

The concept is simple: send an ultrasonic pulse out, then time how long it takes to return. Using the speed of sound and some maths, we can then work out the distance. The following complete program has 2 parts to it: a function sonar ( ) which returns the distance to the object, and the main code in a loop which continually prints the distance. We also need to import the utime library:

from microbit import *
from utime import ticks_us, sleep_us

def sonar():
    pin15.write_digital(1) # Send 10us Ping pulse
    sleep_us(10)
    pin15.write_digital(0)
    while pin15.read_digital() == 0: # ensure Ping pulse has cleared
        pass
    start = ticks_us() # define starting time
    while pin15.read_digital() == 1: # wait for Echo pulse to return
        pass
    end = ticks_us() # define ending time
    echo = end-start
    distance = int(0.01715 * echo) # Calculate cm distance
    return distance

while True:
    display.scroll(sonar())
    sleep(1000)

Scooter for Raspberry Pi Zero

Scooter Robot for Raspberry Pi Zero

Purchase Scooter

Assembly

Step 1 – Check you have all the parts

  • Main board with attached battery holder
  • 2 x wheels
  • 2 x 16mm pillars
  • 4 x screws
  • Female header

Step 2 – Remove the Battery Holder

Unscrew the battery holder, taking careful note of which way it is fitted

 

Step 3 – Fit the Raspberry Pi Zero

NB. You need to have a Pi Zero with the headers fitted. Model Zero WH is recommended

Screw the 16mm pillars onto the main board

Push the included female header into the low-profile header on the main board

Fit the Pi Zero to the header, with the Pi Zero sitting over the motors as shown below

Screw the Pi Zero onto the headers so it doesn’t fall off in use

 

Step 4 – Complete the Assembly

Refit the battery holder

Push on the wheels

Add batteries

Start coding…

Coding for the Scooter

Install the software

First you will need to prepare your Pi for the Smart RGB LEDs (fully compatible with neopixels). The best way we’ve found to do this is run Pimoroni’s curl script.
With your Pi connected to the internet, run (you don’t need to install the resources and examples):

curl -sS https://get.pimoroni.com/unicornhat | bash

Then install the Scooter software:

wget https://4tronix.co.uk/scooter.sh -O scooter.sh

bash scooter.sh

This installs the following files:

  • scooter.py the main library module
  • motorTest.py Use the arrow keys to control the motors. Use . and , to speed up and slow down after next arrow press. Press space bar to stop slowly and ‘b’ to brake quickly
  • ledTest.py Sets the Smart RGB LEDs to Red, Green, Blue, White in turn. Run with sudo python ledTest.py
  • lineTest.py shows the states of the line follower sensors
  • sonarTest.py gives the distance in cm to an obstacle using the optional HC-SR04P
  • avoider.py is a simple obstacle avoider. Run with sudo python avoider.py
  • lineFollower.py is a simple line follower. This runs the Scooter backwards and is best with lines printed from RobotSquare.

 

 

 

Pi2Go Mk2 Assembly

Assembly Instructions for Pi2Go Mk2

Click any image to enlarge

Step 1 – Check the Contents

Check you have:

  • Main Board
  • Battery Board
  • Caster Board
  • 2 Wheels
  • 2 Motors
  • 2 Motor Fixings Bags
  • Bag with mechanical parts (caster, encoder disks, headers)
  • Fixings Bag with screws and spacers

Fixings bag contains:

  • 4 x 5mm, M3, Male-Female pillars
  • 4 x 11mm, M2.5 Male-Female pillars
  • 4 x 19mm, M2.5 Female-Female pillars
  • 2 x 24mm, M3, Female-Female pillars
  • 4 x 4mm, M3 screws
  • 4 x 8mm, M3 screws
  • 8 x 6mm, M2.5 screws

 

Step 2 – Fit the Raspberry Pi Mountings

You will need 4 x 19mm, M2.5 pillars and 4 x 6mm, M2.5 screws.

Fit the 4 pillars to the main board as shown below

 

Step 3 – Prepare the Motor Mounts

Screw 2 of the 5mm, M3 pillars into the top of each motor mount. Ensure they are fitted tightly

 

Step 4 – Fit the Motor Mounts to the Motors

Pass one of the long screws from the outside of the motor (the side without the wires), through the motor and through the motor mount. Then loosely fit one of the nuts. It will sit at a strange angle as shown below

Then pivot the mount on the long nut, so that it pushes the wires out of the way and allows you to put the second long screw in. Then tighten up both nuts.

Repeat for the second motor, but fit the mount the other way up.

You should now have a left-hand and a right-hand motor assembly as shown above

Step 5 – Fit the Motor Assemblies to the Main Board

First, attach an encoder wheel to the inside shaft of each motor. Just push it on so that it is flush with the end of the shaft. It may take some pushing to get it on, and when it is on it will be a bit floppy. This is normal

Now use the 4mm, M3 screws, 2 for each motor, to screw through the main board into the pillars that you fitted into each motor mount in step 3

 

Step 6 – Assemble the Front Caster board

Use 2 of the 8mm, M3 screws to screw through the caster, through the caster PCB and into the 24mm, M3 pillars. Ensure the header pins are on the opposite side to the caster, and the same side as the pillars.

 

Step 7 – Fit the Caster Board to the Main Board

First push the extended 6-pin header into the header on the bottom of the main board, then plug the assembled caster board into the 6-pin header as shown below

Finally screw the 2 remaining 8mm, M3 screws through the main board and into the top of the pillars from the caster board. Tighten up well.

 

Step 8 – Fit the Raspberry Pi

You can use a Model A, A+, B or B+.

NB: To use a Raspberry Pi Zero, use the “Zero Spacer” PCB that is included with Pi2Go Mk2 since 1st September 2019. Kits shipped prior to that date do not include that spacer so you would have to use washers or similar to make up the extra 1.6mm height.

Push the 40-pin header onto the header on the main board

Then push the Raspberry Pi, upside down, into the 40-pin header, ensuring that all the pins line up and the mounting holes on the Raspberry Pi match the pillars

Screw the 11mm, M2.5 Male-Female pillars in well to hold the Pi firmly

 

Step 9 – Fit the Battery Board

Standard 6 x AA battery board shown. Fitting the other types is the same

Making sure that the LEDs marked 0 through 7 are at the front, use the 6mm, M2.5 screws to fix the battery board tightly to the 4 pillars.
Note that these pillars all carry power and/or signals, so it is important that they are all screwed in well. Failure to attach screws or pillars properly will result in failure of the Pi2Go.

 

Step 10 – Add the Wheels

Push on the wheels

And the build is complete!

Now go to the Programming Pi2Go Mk2 article to get it going