BitBot Programming in Python

BitBot and BitBot XL Programming in Python

Programming in Python

For text-based programming there is micro-python, and I prefer to use this offline using the Mu editor.  It provides a very neat and easy way of interfacing to the micro:bit without all the fuss of dragging and dropping.

Note on examples: We want to show people how the various features can be used. We don’t want to do the coding for you – that is the learning experience you should be taking away from using it. In the following examples, we will give you the tools to use all the features of Bit:Bot but it is up to you to combine them together in your code to make it do something useful. We do give a complete example of line-following – but it is a very basic algorithm and will get confused at T-junctions  and crossings; and it doesn’t use the FireLeds.

Download Python examples at the bottom of this page.

Some great tutorials/examples by Mark Atkinson here

Motors

Each motor has two pins connected to it. If the first pin is High and the second is Low, then the motor will drive Forward. Conversely, if the first is Low and the Second is High then it will drive in Reverse.

For BitBot Classic: Left pins are P0, P8 and Right pins are P1, P12

For BitBot XL: Left pins are P16, P8 and Right pins are P14, P12

The simplest way to make the motors move Forward is to set the First pin to HIGH and the Second pin to LOW. eg for BitBot XL:

Move left motor Forwards:

pin16.write_digital(1)
pin8.write_digital(0)

Move left motor Reverse:

pin16.write_digital(0)
pin8.write_digital(1)

If we want to change the speed of a motor, so that it is not going at full speed all the time, we need to use PWM (Pulse Width Modulation). This is a means of changing the amount of power given to the motor by switching it on and off very fast. The percentage value of PWM determines the amount of each cycle that the output is ON. So a percentage of 100% is the same as being on all the time and thus the same as the examples above. A percentage of 50% would mean that the motor is only energised half the time, so it will go much slower. Note that the actual speed of the motor is not the same as the percentage of PWM – the motor won’t turn at all if the PWM value is too low and you will also get some stuttering at certain values. Nevertheless, being able to change the speed makes for a much better robot. For example, you can make a line follower that smoothly follows the line, rather than the normal shaking left and right.

To change the PWM value of a pin, we must use the analog_write commands. These can be set to a value between 0 (always off = 0%) to 1023 (always on = 100%), so 50% would be 511. Here are the commands to change the speed of the Right motor to approx 75% (value is 770) for the BitBot XL

Move right motor forwards at 75%

pin14.write_analog(770)
pin12.write_analog(0)

To move it in reverse, we simply apply the PWM value to the other pin instead and set the first pin to 0

Move right motor Reverse at 75%

pin14.write_analog(0)
pin12.write_analog(770)

 

FireLeds

The FireLeds smart RGB pixels are able to display any of 16 million colours by selecting a value of 0 to 255 for each of the Red, Green and Blue LEDs on each chip. The whole thing is controlled by a single pin on the BBC micro:bit (pin 13 for all models of Bit:Bot). It is simple to use the included neopixel libraries to control each FireLed individually.

The pixels are labelled on the Bit:Bot. From 0 to 5 on the left arm and from 6 to 11 on the right arm.

Set FireLed 2 to purple (red and blue)

from microbit import *
import neopixel
fireleds = neopixel.NeoPixel(pin13, 12)
fireleds[2] = (40, 0, 40)
fireleds.show( )

The first line is the standard import all from Microbit library.

The second line imports the neopixel library. We only need to do this once, at the very top of your Python program.

The third line creates a Python list with an element for each pixel. As shown, it specifies 12 pixels connected to pin 13.

The fourth line sets the pixel we have selected (number 2 in this case) to the colour which is set by three values in the brackets, each value can be from 0 to 255 and covers Red, Green and Blue. In our example we have set Red and Blue to 40.

The fifth line tells the neopixel library to copy all the data to the neopixels, from the Python list that we have been working with. It is only at this point that the LEDs change. In general, you would make all the changes you want and only at the end would you use a np.show( )

Line Follower Sensors

The pins used for line following are quite different for the BitBot Classic and the BitBot XL. BitBot Classic uses Pin11 (Left sensor) and Pin5 (Right sensor), which are the same pins as used for the Microbit’s two buttons. This can cause all sorts of issues.

The BitBot XL uses an I2C chip for these pins, with bit 0 of the resulting value being the Left sensor and bit 1 being the Right sensor.

The following two programs perform the same operation. They read the state of each line sensor and set the corresponding FireLed on the end of the stalks to either Red or Green.  The BitBot Classic first

from microbit import *
import neopixel
fireleds = neopixel.NeoPixel(pin13, 12)
while True:
    if(pin11.read_digital() == 0):
        fireleds[5]=(40,0,0)
    else:
        fireleds[5]=(0,40,0)
    if(pin5.read_digital() == 0):
        fireleds[11]=(40,0,0)
    else:
        fireleds[11]=(0,40,0)
    fireleds.show()
    sleep(200)

And now the equivalent program for the BitBot XL. You can see that we’ve defined a new function getLine( ) that reads the I2C device and returns the state of bit 0 (Left sensor) or bit 1 (Right sensor)

from microbit import *
import neopixel
I2CADDR = 0x1c # address of PCA9557
fireleds = neopixel.NeoPixel(pin13, 12)

def getLine(bit):
    mask = 1 << bit
    value = 0
    try:
        value = i2c.read(I2CADDR, 1)[0]
    except OSError:
        pass
    if (value & mask) > 0:
        return 1
    else:
        return 0

while True:
    if(getLine(0) == 0):
        fireleds[5]=(40,0,0)
    else:
        fireleds[5]=(0,40,0)
    if(getLine(1) == 0):
        fireleds[11]=(40,0,0)
    else:
        fireleds[11]=(0,40,0)
    fireleds.show()
    sleep(200)

The above programs are complete, with all the imports and defines required. This simple line following algorithm for the BitBot XL uses the getLine( ) function defined above as well as some simple motor functions which aren’t defined here

while True:
    lline = getLine(0)
    rline = getLine(1)
    if (lline == 1):
        spinLeft( )
    elif (rline == 1):
        spinRight( )
    else:
        forward(speed)

Light Sensors

These are analog sensors and will give a value of 0 to 1023, where 0 is fully dark and 1023 is maximum brightness. As there are only 3 analog pins available on the micro:bit (without affecting the LED displays) and we are using 2 of them to control the motors, we only have one left (Pin 2) to read the analog values from 2 line sensors. How can we do this? Well, the Bit:Bot has an analog switch that uses a digital output signal (pin 16) to determine whether the analog input we are reading is for the left sensor or the right sensor.

Therefore, to read the light sensors we need to set the selection output pin first, then read the analog data.

In Python, we can do it like this to read the values into 2 variables called leftVal and rightVal:

Pin16.write_digital(0) # select left sensor
leftVal = Pin2.read_analog()
Pin16.write_digital(1) # select right sensor
rightVal = Pin2.read_analog()

 

Buzzer

The buzzer is a very simply device that outputs a 2.4kHz sound when it is set to ON. It is NOT controlled by the tone signal that can be output by the micro:bit on Pin 0 so you don’t need to install any libraries to operate it.

It is connected to Pin14. Setting this to ON (1) will activate the buzzer and setting to OFF (0) will deactivate it.

In Python, a very simple and annoying beep, beep, beep sound can be made as follows:

while True:
pin14.write_digital(1)
sleep(400)
pin14.write_digital(0)
sleep(400)

Ultrasonic Distance Sensor

This optional HC-SR04 ultrasonic distance sensor addon can be used most easily in Microsoft PXT. In MicroPython we can use the utime module to measure time at microsecond level. Below we have a function called sonar() which returns the number of cm to the nearest object. Then we have a while loop that prints the distance every second:

from microbit import *
from utime import ticks_us, sleep_us

def sonar( ):
SONAR.write_digital(1) # Send 10us Ping pulse
sleep_us(10)
SONAR.write_digital(0)
SONAR.set_pull(SONAR, NO_PULL)
while SONAR.read_digital() == 0: # ensure Ping pulse has cleared
pass
start = ticks_us() # define starting time
while SONAR.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)

Programming BitBot XL

BitBot and BitBot XL Programming in Makecode

BitBot XL is the latest incarnation of the popular BitBot robot. It has the following features:

  • 2 micro-metal gear motors. Both fully controllable in software, for both speed (0 to 100%) and direction (forward or reverse)
  • Wheels with rubber tyres for maximum grip
  • Front ball caster
  • 12 FireLeds in 2 sets of 6 along the arms either side. Select any colour for any pixel, produce stunning lighting effects as your Bit:Bot XL moves around
  • 2 digital line following sensors with indicator LEDs. Code your own line-following robots and race them to see whose code produces the fastest lap time!
  • 2 analog light sensors (front left and front right) so your Bit:Bot XL can be programmed to follow a light source such as a torch, or you could code it to go and hide in the darkest place it can find
  • Buzzer, so you can make beeping sounds or music whenever you want
  • Powered from integrated 3xAA battery holder with on/off switch and blue indicator LED
  • Easily plug your BBC micro:bit in and out using the vertical edge connector
  • Expansion connections at the front for accessories. Currently available accessories: Ultrasonic, 5×5 FireLed matrix, BitFace and OLED
  • Two GVS connectors with 5V for servos (shared with light sensors)

Programming in Makecode

Python Programming can be found here

Tip: Click on any image to enlarge

Load Makecode for the Microbit from makecode.microbit.org and create a New Project. Then select the Advanced tab and click on Extensions. You should see BitBot on the extensions home page. If not, enter bitbot in the search box and select the extension when it shows up.

Setting the BitBot Model

The BitBot Makecode extension is fully compatible with all models of BitBot, including BitBot XL. The extension will automatically select the correct  version to use when it runs (as long as the BitBot is switched on when the program starts)

There are blocks available, in the “BitBot Model” category, to force a specific model (Classic or XL) as well as giving the ability to check which version the software is running on. This allows you to write programs that will run unchanged on all models of BitBot.

Controlling the Motors

In the motors category, you can select blocks to go forward or reverse, or spin on the spot. Both types of block can optionally be run for a fixed time, then the robot will stop.

In addition you can stop BitBot with the stop block. This can be a fast stop with an electronic brake, or the robot can more slowly come to rest.

You can also drive each motor individually. This allows you, for example, to turn the left wheel slowly and the right wheel fast so that the BitBot curves smoothly to the left.

Small DC Motors as used in the BitBot and other small robots are never fully matched. To take account of this you can bias the motors to move in the opposite direction to their natural curve. For example, if the robot curves to the left when it should be travelling straight, add some right bias. Vice versa, if it curves to the right, then add some left bias.

Controlling the FireLeds

There are 12 FireLeds on the BitBot. Each of which can be individually controlled with 16 million different colours (not that you can distinguish that many).

By default, the FireLeds are updated as soon as you make any change to them. If you are doing more complicated changes, you may want to change to manual updating so that you make all the changes required, then update the FireLeds once at the end. This is more efficient and gives a tidier appearance to animations, but isn’t necessary for the majority of uses.

You can set all of the FireLeds in one go to the same colour, using the “set all LEDs” block. If you click on the Red blob on the end of the block it will allow you to select one of 25 different colours (you can select your own colours as well, see the advanced blocks)

You can also set individual FireLeds (numbered 0 to 11 on the BitBot’s arms) to specific colours and clear all the FireLeds (switch them off). Setting the FireLeds to Rainbow, sets them all to different colours starting at Red and ending at Purple.

Blocks are also available to shift all the FireLeds along one place (with the FireLed 0 being turned off) and to rotate them all by one place (with FireLed 0 becoming the same colour that FireLed 11 was previously)

Advanced FireLed Control

In the advanced block we can set the brightness of all the FireLeds. The default setting is 40, but it can go as high as 255 for maximum brightness. Do not look directly at the FireLeds if they are set to very bright, especially if they are set to White, as it can hurt the eyes.

If you set the update mode to Manual (instead of Automatic) then you must run the “show FireLed changes” block after you make a change, otherwise nothing will change on the FireLeds themselves.

The final 2 blocks return a number representing a colour that you can select from the colour chooser or by setting specific Red, Green and Blue values. This colour number can be put into a variable for testing against other values, or you can use it directly to set the colour of FireLeds

Sensors – Buzzer, Light Sensors, Line Sensors, Talon, Servos

The Buzzer can be On (continuous beep) or Off (silent). On the BitBot XL, this can also be used to play music (badly) as it is connected to Pin 0. Use the standard Music blocks in Makecode to do this – it isn’t supported directly in the BitBot extension.

The optional ultrasonic sensor is used to measure the distance to the nearest sound reflecting object. This may be anything in the area as the focus of the sound beam is not very tight, so it may pick up other objects than the one you want. This block returns a number that can be the number of cm, number of inches, or a raw microseconds figure.

Similarly the light sensors return a number from 0 (totally dark) to 1023 (maximum brightness).

The line follower sensors are slightly different. They return a value of either 0 (no black line) or 1 (black line).

The Servos (BitBot XL only) and the Talon (optional on all models) operate in the same way – as the Talon is just a servo really.

For the Talon you can select the angle of the servo from 0 to 80 (closed to open). On the servos (BitBot XL only) you can select an angle from 0 (fully clockwise) to 180 (fully anti-clockwise)

If you want to release the pin from being a servo (as the servo pins on the BitBot XL are shared with the light sensors), then you can disable the servos.

 

 

Starting with ScratchGPIO on Pi2Go Mk2

Pi2Go Mark 2 with ScratchGPIO

Simon Walters (Cymplecy) has worked on ScratchGPIO for many years and continues to add new products to the supported list. Pi2Go Mk2 is now also supported – here’s a brief introduction on how to get started.

Step 1: Install ScratchGPIO

Visit the ScratchGPIO install page here.

From a command line, first run the wget to download the installer

wget https://git.io/vMS6T -O isgh8.sh

Then run the installer:

sudo bash isgh8.sh

Step 2: Run ScratchGPIO8Plus

Make sure you choose the correct program to run here. Do NOT run ScratchGPIO8, nor Scratch2GPIO…

Step 3: Create an Addon Variable

You need to create a variable and set it to “Pi2Go2” (without the quotes)

Select the Variables tab (top left) and press “Make a variable”

Name the variable “AddOn”

Move the block “set AddOn…” to the programming area and enter Pi2Go2 as the variable name.

While you’re at it, grab a green flag block from the Control tab and lock the 2 blocks together

Click on the green flag and the AddOn variable in the stage will show up as Pi2Go2 as in the image above.

Step 4: Check the Sensors are available

Now, when you look into the Sensing tab, next to the bottom is a block showing “slider sensor value”. If you click on the slider you can see all the other sensors available, including those for the Pi2Go Mk2: battery, frontleftlight, frontrightright, etc. You can now use all these sensors in your program.

Step 5: Drive the Motors

Now you can create two more variables for the motors. MotorL and MotorR for the Left and Right motors respectively.

Setting these to values between 0 and 100 will drive the motors. Note that speeds below 30 or so may not be able to power the motors – it depends what batteries and what voltage is available.

The program below drives the left motor for 1 second at speed 60, then stops

Step 6: Further Programming

Now visit the ScratchGPIO page dedicated to Pi2Go Mk2 for further tips and information.

Servo:Bit Affordable Multi-Servo Driver for Microbit

Servo:Bit Multi-Servo Driver

Purchase Servo:Bit here

Servo:Bit is a little board, exactly the same size as a Raspberry Pi Zero and the 4tronix Drive:Bit, which provides control for up to 16 servos. Access to the useful pins of the Microbit is provided as is a single Smart RGB LED

Power for the servos is provided by one of three options:

  • USB connector
  • 2-pin male header
  • 2-way screw connector

Providing power (5V – 6V) to one of these connectors also provides power for the Microbit.

Connections

NB: Fit the Microbit into the connector with the LEDs on the Microbit facing the switch and indicator LED.

Voltage

Most hobby servos operate within 5V to 6V range. Ensure that the voltage you provide does not exceed the voltage supported by your servo. Unless you have a specialist servo, you should be safe with the 5V USB input

Current Draw

Running 16 servos will consume a fair amount of current. Check the specification of your servos to see how much current they may take and ensure your power supply can provide sufficient. For instance, 16 servos taking 100mA each may require up to 1.6A this may not be available from your USB power supply.

You can connect both USB power and one of 2-pin male header or 2-way screw terminal to power at the same time as there are blocking diodes to prevent back-current. Do NOT connect power to both the 2-pin male header and the 2-way screw terminal as there is no blocking diode between these two. Use one or the other, but not both.

Each servo output is provided with 3 connections using the GVS (Ground, Volts, Signal) layout common to servo cables. Ensure you plug them in the correct way round or your servo may be damaged. Brown or Black is the normal colour for the Ground lead and this should be connected nearest to the pins near the edge of the board labelled ‘G’. The signal wire is likely to be White, Yellow or Orange and this should be on the pins labelled ‘S’

The Microbit can power the Smart RGB LED and the blue LED on the board, but it cannot power and is not connected to the servos. Your servos will not operate unless you connect power into the USB, 2-pin header or 2-way screw terminal.

Programming the ServoBit in Microsoft Makecode

There is a Makecode extension available to control the servos and Smart RGB LED on the ServoBit. Go into the Advanced tab in Makecode (or click on the gear icon in top right) then select Extensions. Enter ServoBit in the search box and select it.

The 4tronix ServoBit uses a PCA9685 to control 16 independent servos.
Helper commands are available to centre all servos, or set individual servos to any angle from -90 to +90 degrees

It is also possible to set the speed at which each servo moves to its new position, which gives a smoother operation

In addition, the 4tronix ServoBit contains a single Smart RGB status LED which can be set to any colour and brightness and a flashing function is also available.

Setting the servos

Set all 16 servos to the centre position

ServoBit.centreServos()

Set a specified servo to an angle, between -90 and +90 degrees

eg. Set Servo 5 to +30 degrees
ServoBit.setServo(5, 30)

Controlling servo movements and speeds

You can control the number of degrees per second that the servo moves. A typical servo would have a maximum speed of around 500 degrees per second.
Reasonable values for slower movements are between 30 and 200 degrees per second, although a range of 1 to 1000 is supported.
Setting the servo position whilst it is still moving, will cancel the movement command.
Creating a new movement command for a servo with an existing movement will cancel the first and then start the second.
You can also check if the servo has reached its target position, or wait until it has completed.

Move specified servo to an angle at a specified speed (speed can be from 1 degree per second to 1000 degrees per second)

eg. Move servo 5 to 30 degrees at 40 degrees per second
ServoBit.moveServo(5, 30, 40)

Check current position of specified servo

eg. Check current actual position of servo 5
let variable = ServoBit.getServoActual (5)

Check target positon for servo

eg. Check target positon for servo 5
let variable = ServoBit.getServoTarget (5)

Wait for specified servo to complete its movement

eg. Wait for servo 5 to complete its movement
ServoBit.waitServo (5)

Smart RGB LED helpers

The 4tronix ServoBit has a single smart RGB LED (aka neopixel) fitted. There are various blocks available to make it easy to control the LED

Clear the LED (turn it Off)

ServoBit.ledClear()

Set LED to selected colour. You can use other blocks to generate your own RGB colours

eg. Set LED to Red
ServoBit.setLedColor(ServoBit.vColours(vColors.Red))

Set brightness of LED from 0 to 255. Default value is 40

ServoBit.ledBrightness(40)

Start Flashing the LED with selected colour and defined speed

eg. Start Flashing the LED with Green at 100ms
ServoBit.startFlash(ServoBit.vColours(vColors.Green), 100)

Stop flashing the LED

ServoBit.stopFlash()

 

McRoboFace Home Page

McRoboFace – Emoticon for Electronic Creations

mrf02b

(Click on any image to enlarge)

Purchase McRoboFace Here

Overview

The McRoboFace is a robotic face with 17 individually controllable RGB LEDs that you can use to bring your electronic creations to life.

Each LED can be set to any of 16 million different colours (256 for each of Red, Green and Blue).

All the LEDs as fully compatible with the “standard” WS2812, also known as “neopixels” – a name coined by Adafruit. As such, any of the many libraries and examples for most of the common controllers can be used to drive them. This includes:

  • Crumble
  • Arduino
  • micro:bit
  • ESP8266
  • Raspberry Pi
  • Codebug
  • BeagleBone

 

Tour of the ‘Face

v02_Render03

The “mouth” is made up of 14 small (3.5mm) pixels numbered in small lettering from 0 to 13:

  • Lighting 0 to 5 gives a smile
  • Lighting 0, 5, 6, 7, 8, 9 gives a frown
  • Lighting 0, 5, 10, 11, 12, 13 gives a straight-line
  • Use other combinations for quizzical looks, open mouth, etc

The “nose” comprises a small (3.5mm) pixel numbered 14

The “eyes” comprise two standard (5mm) pixels numbered 15 & 16

 

v02_Render04

The rear shows the 3 mounting holes, each is 2.8mm diameter for use with M2.5 screws

There are 4 connections at the bottom:

  • Gnd – Ground pin. Connect to 0V from your controller
  • Vcc – Power pin. Connect to the power pin from your controller.Ideally this is 5V, but on the micro:bit for instance only 3.3V is available. This will work, although it is below the recommended minimum voltage
  • Din – Data input pin. Connect this to the control output from your controller
  • Dout – Data Output pin. Use this to connect additional smart pixels such as another McRoboFace, a CodeBug GlowStar/GlowBug, Crumble Sparkles or an Adafruit neopixel strip etc.

 

Connections to Example Controllers

For the following photos I have soldered on the 4-pin right angle header to make connections easier using jumper leads. Photos are of a prototype McRoboFace, without the numbers to identify each pixel

Crumble

Crumble01

The Crumble knows smart pixels as Sparkles and they must be connected to the D pin. Use the + and – pins to provide Power and Ground

The software is as simple as setting each pixel to the required colour. This is what the picture above is running:

Crumble02

 

Arduino

Arduino01

For the Arduino, any of the output pins will work. In this example we are using A0 as it is closest to the %V and Ground pins.

The code used relies on the well-known and well supported FastLED library. In the Arduino IDE, go to Sketch / Include library / Manage Libraries and then search for FastLED. Select it and install.

Then you can use this example code to show various facial expressions. The important parts are:

  • in setup ( ) – you need to define the number of LEDs, and the pin to be used to control them: FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
  • to change any pixel, set its RGB value in the led array, eg. leds [3] = CRGB (RedValue, GreenValue, BlueValue);  When you have set all the pixels you need, then call FastLED.show ( ); to transfer the changes to the pixels.

 

micro:bit

microbit01

In micro python on the micro:bit, you can use any output pin to control the McRoboFace’s pixels. In this example we’re using Pin 0

As with the Arduino, you first need to include the right library and then define which pin you’ll be using and how many pixels are required. micro:bit calls them “neopixels”

microbit02

 

Raspberry Pi

You can do this in two ways:

  1. Connect directly to GPIO pin and install some software. This software often changes as Raspberry Pi change things in the kernel and will need keeping up to date
  2. Use Picon Zero to provide a simple interface to all your devices including smart pixels

Directly to GPIO Pin

rpi01

You need to use GPIO 18, which is physical pin 12. You can use the 5V and Ground pins directly. No level changers are required as the pixel can be controlled using 3.3V quite happily as shown.

If you already have neopixels supported on your Pi then there is no need for the build and install steps below. You can visit McRoboFace githib repo for the information below

$ git clone https://github.com/4tronix/mcroboface
$ cd ~/mcroboface
$ sudo apt-get install python-pip python-dev
$ sudo python setup.py install

NB. For Raspbian Jessie release 10th May 2016 (and probably later versions also) you will need to add the following lines in ‘/boot/config.txt’ :

hdmi_force_hotplug=1
hdmi_force_edid_audio=1

This will create a folder on your Pi called mcroboface and provide a simple example, mcroboface.py. Run this as:

$ sudo python mcroboface.py

 

Using the 4tronix Picon Zero

rpi02

Picon Zero output 5 can be used to drive smart pixels in a very simple manner. You should first visit the main Picon Zero page to download the library

Download the simple test example from here

 

Singalong Kit for McRoboFace

sa02

The Kickstarter campaign for McRoboFace included an option for some electronics that allowed the mouth of McRoboFace to be controlled by an audio input signal.

This was developed by Robin Newman and the full blog can be seen here

Download the assembly instructions here