Programming M.A.R.S. Rover on Raspberry Pi Zero (inc v2)

Programming the M.A.R.S. Rover with Python

Preparing your Raspberry Pi Zero

Before you can install the Rover software, you will need to ensure that your Raspberry Pi Zero 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 VNC 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.

Installing the M.A.R.S. Rover Python Software

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 M.A.R.S. Rover with

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

bash rover.sh

This installs the following, which should be run for a command line (not in Idle etc.)

  • Creates a folder home/pi/marsrover for all the example files and library module rover.py (the main library module)
  • calibrateServos.py should be the first program you run. This ensures that the wheels are all pointing in the correct direction. You must use the terminal to run this and you will require sudo because it uses the LEDs as indicators. Run with sudo python calibrateServos.py. Then select each servo in turn using ‘0’ to ‘4’ keys and adjust the servo using the left and right arrow keys until it is straight. Press ‘s’ to save the calibration and exit the program.
  • 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
  • servoTest.py to demonstrate controlling the servos. Must be run in a terminal, not from an IDE like Idle or Thonny. Use LXTerminal for this
  • ledTest.py flashes all LEDs through Red, Green, Blue and White. This must be run using sudo. ie: sudo python ledTest.py
  • sonarTest.py shows the distance in cm for an obstacle using the ultrasonic distance sensor mounted on the mast head
  • keypad.py shows the numeric value of each key pressed on th eoptional keypad
  • driveRover.py is a basic driving program using the arrow keys to steer and move

Remote Control of Raspberry Pi

Check out the various interface methods for your Raspberry Pi. We prefer to use Real VNC desktop client on our PC with the built-in VNC server on the Pi Zero. See the Raspberry Pi Remote Access blog and scroll down to the VNC section.

Using the rover.py Library Module

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

import rover

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 two optional parameters.

1. 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:

rover.init (100)

2. Using the PiBit to convert a Microbit Rover to Pi Zero. This parameter is only needed if using a PiBit and causes the pins used to drive the motors to be swapped. For a PiBit, use:

rover.init(PiBit = True), or rover.init(100, PiBit=True)

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:

rover.cleanup ( )

Motor Functions

  • stop ( ): Stops all motors – coast slowly to a halt
  • brake ( ): Stops all motors – brakes quickly
  • forward (speed): Sets all motors to move forward at speed. 0 <= speed <= 100
  • reverse (speed): Sets all motors to reverse at speed. 0 <= speed <= 100
  • spinLeft (speed): Sets left and right motors to turn opposite directions at speed. 0 <= speed <= 100
  • spinRight (speed): Sets left and right motors to turn opposite directions at speed. 0 <= speed <= 100

Fireled 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

UltraSonic Function

  • getDistance ( ). Returns the distance in cm to the nearest reflecting object. 0 == no object.

    Keypad Functions

  • getKey ( ). Waits for a keypress on the optional touch keypad and returns the value of the keypad pressed. The relevant bit is set for any keys pressed (16 keys, so a 16-bit value is returned)

EEROM Functions

The onboard EEROM can store 1024 bytes of information. However, the first 16 bytes are used to stroe the servo calibration offsets, so “only” 1008 bytes are available to the user. The servo offset data is hidden, so the user data is addressed from 0 to 1007. Values return are signed bytes with values from -128 to +127 inclusive. This could be used for example to store a sequence of commands from the Keypad, creating a set of remote instructions, etc.

  • readEEROM (Address). Returns the data byte stored at user address Address
  • writeEEROM (Address, Data). Saves the data byte Data at the user address Address

Valenta Off Roader

Valenta Off Road Vehicle

For BBC Microbit

The Valenta range of motor driver boards has been specifically engineered to be used as the main control unit for a range of injection moulded vehicles.

The Valenta Zero is the same size as the DriveBit and ServoBit products from 4tronix (and also the same size as a Raspberry Pi Zero). It contains a small motor controller (DRV8833) as well as connections for general I/O and servos (can be selected to operate at 3.3V or 5V using a jumper or switch).

A Makecode extension is available to drive both the Valenta Zero and the Valenta Plus. In the Advanced | Extensions search box, enter this URL to find and load the extension: https://github.com/4tronix/Valenta

Assembly

Please follow the steps shown in this video and outlined in the included User Guide

Programming in Makecode

A Makecode extension is available to drive both the Valenta Zero and the Valenta Plus. In the Advanced | Extensions search box, enter this URL to find and load the extension: https://github.com/4tronix/Valenta

This provides generalised commands to drive motors, servos and Fireleds (where available). To drive this Off-Roader vehicle, note that:

  • Motor 1 is the left motor
  • Motor 2 is the right motor
  • Servo 8 is the steering servo connected to Pin 8 of the Microbit
  • (There are no headlights or Fireleds on this prototype)

Sample Programs

Please visit the Hummingworks website for samples at this time

RUB: Really Useless Box

Really Useless Box

The concept of a “Really Useless Box”, where the human moves a switch and then the box closes it again, has been around for years. This is the 4tronix take on it, adding Microbit control of the servo (position and speed of movement) as well as Fireleds to give it more ambience.

There is an accompanying Makecode extension to make it even easier to code. This extension could easily be used for your own version of a Really Useless Box: simply connect your switch to Pin 0 and your servo to Pin 1 and you can use it. If you also have some Fireleds (or neopixels) then you can connect these to Pin 2.

Purchase

You can purchase the 4tronix Really Useless Box here, or feel free to build your own and use the Makecode extension.

Assembly

Click on any image to enlarge

Step 1: Check you have the Correct Parts

You should have:

  • 7 PCBs (6 black, 1 white)
    • Main PCB with all components (base)
    • Left side
    • Right side
    • End
    • Top
    • Lid
    • Actuator (White)
  • Bag with servo and fixings
  • Bag with pre-wired Switch
  • Bag with aluminium brackets and 8 fixing screws (M3, 8mm)
  • Bag with an assortment of screws and rubber feet
    • 2 x M2, 4mm screws (to fit switch)
    • 2 x M2.5, 6mm screws (to fit servo and pillars)
    • 2 x M2.5, 18mm female-female brass pillars (to mount servo)
    • 4 x Black self-tapping screws (to mount servo arm to the actuator PCB)
    • 8 x M3, 6mm screws (to fit PCBs to aluminium brackets)
    • 4 x rubber feet
  • Screw driver (reversible – unplug blade from handle and turn round for flat blade)

Step 2: Fit the Aluminium Brackets

There are 4 brackets to fit. One on each Side and 2 on the Top.

Ensure that the two threaded holes in the top of each bracket are at the edge of the PCB. Failure to do this will prevent you fitting the Sides/Top

When complete it should look like the above photo.

Step 3: Fit the Servo to Left Side

Screw the 2 brass pillars to the Left Side using 2 of the four M2.5, 6mm screws, ensuring that the pillars are on the same side as the aluminium bracket.

Finally, screw the servo on to the top of the pillars using the remaining 2 of the M2.5, 6mm screws. Ensure the cable from the servo is towards the centre of the PCB as shown below.

Step 4: Fit the Servo Arm to the Actuator PCB

Take the cross shaped Servo Arm from the Servo bag and push it through the hole in the Actuator PCB. It may be a tight fit.

Make sure you push it in from the side shown above, which has the markings for the arm on the Actuator.

Then use the 4 black screws to fix the Servo Arm from the opposite side.

Finally, use a pair of side-cutters or nail-clippers to trim the Servo Arm to size

Step 5: Fit the Actuator to the Servo

THIS IS CRUCIAL – DO NOT SKIP THIS

We need to set the servo into the correct place and then position the actuator so that the tip is just below the flat top of the side – as shown above.

To do this we need to connect the servo to the main PCB, plug in a Microbit and power, and write a very small program.

  1. Plug the servo into the Main PCB 3-pin connector. Ensure that the Brown wire is closest to the centre of the board, as shown above.
  2. Plug your Microbit into the socket, ensuring that the LEDs on the Microbit face away from the main PCB
  3. Connect your Microbit to your computer with a USB cable
  4. Load the Servo setup program from here onto your computer. It should have a single line in the “on start” block
  5. Click on “Edit”, then click on “Download” to install it on your
  6. Move the USB cable from the Microbit to the RUB Main PCB and switch ON. The Servo should now move to the “Closed” position
  7. Now push on the Actuator so that the tip of it is just below the top edge of the Side PCB as shown below:

Unplug the Microbit and USB cable.

Finally use the very small screw in the Servo bag of fixings to fix the Actuator in position.

Step 6: Screw The Box Loosely Together

First the Left Side PCB. Use 2 of the eight M3, 6mm screws fitted from underneath the main PCB and into the 2 screw holes in the aluminium bracket on the Left Side. Leave the screws loose so the side can move a little.

Repeat for the Right Side PCB

Now use the remaining 4 M3, 6mm screws to fit the top piece to the side pieces. Again, leave the screws loose at this stage.

Take the switch and pass the wires through the square hole in the Top PCB.

NB. Ensure that the Red wire is nearest the centre of the box, as shown below

Use the 2 M2, 4mm screws to fit the switch tightly into the top

NOTE: If you fix the switch the wrong way round it will interfere with the servo, so make sure you have it fixed correctly

Finally, plug the end of the switch cable into the white JST socket on the mainboard

Step 7: Finish Assembly

Now, clip the End PCB into the slots on the back edge of the Sides, then push the small lugs on the sides of the Lid into the holes at the top of the Sides.

Then you can tighten all the screws to hold it all together firmly

Move the lid up and down a few times to loosen it and remove any burrs. It should drop under its own weight, but can be a bit stiff until used a couple of times.

Finally, peel the 4 rubber feet off the backing and stick them in the corners of the base so it sits on a desk without sliding around and scratching the desk.

Programming the Really Useless Box

In some ways, the RUB is very simple to program – after all, it is only a switch, a servo and some LEDs. However, you can make it come alive and show its own personality. You can make it slight open the boix to have a look round, then go back in to hide. Or maybe it can come straight out in a rush as soon as you flick the switch. The best Really Useless Boxes exhibit a variety of behaviours at random so you never know what will happen when you flick the switch. Have fun designing your behaviours!

NOTE: The servo will not have sufficient power to move the switch unless you power the RUB from the USB connector on the side. Don’t forget to do this.

To start with you can run this simple test program from this link. This will set the LEDs to Red, then change to Green when the switch is activated and will switch itself off (and back to Red)

To program it yourself, first load up Microsoft Makecode from this link and select “New Project”.

Then go to Advanced, then Extensions. Insert the following URL into the search box and press Enter: https://github.com/4tronix/RUB

After selecting the extension you will see a Rub category in the Makecode toolbox. Clicking on that will show subcategories for Switch, Servo, Fireleds and more.

Switch subCategory

This subcategory has 2 blocks. The most useful one is the “On Switch On/Off” block which enables you to run code only when the switch is moved to a new position.

The other block allows you to check what state the switch is in (On or Off) at any time, using the standard Logic blocks.

Servo subCategory

This subcategory has a number of blocks that enable you to move the servo directly to any position, or to make it move at a selected speed from “Very Slow” to “Very Fast”. In fact, “Very Fast” is the same as moving the servo directly – the Servo moves at its fastest pace.

As well as moving to a specified angle, there are 3 preset positons of the Servo labelled Closed. Open and Switched. You can use the “set closed open switched” block to set the positions of these presets in degrees. If you have built the RUB as described above then you should find the default positions are okay.

NOTE: The servo is limited in software to only travel between the Closed and the Switched positions. So setting these presets, also sets the servo maximum travel

You will find that, if the Servo is moving very slowly then it may need to go an extra distance to get enough power to open the switch. In this case, either move to a higher number of degree or set the switched position to be higher.

You can use the block “wait for servo” to hold up running the program until the servo has reached the position you set. This is important otherwise your program might start moving the servo again before it has had a chance to get where you told it to.

NB. The very first servo command in the program will ALWAYS go at full speed irrespective of what speed was set. This is because the software needs to know where the servo is before it can start controlling it slowly. The first time it is used, the software doesn’t know where it is so it moves directly to a known position.

Fireled and more subCategories

This is the standard set of commands for driving Fireleds. You can set all the Fireleds at once, or set them individually. The default is automatic updates, so the Fireleds are updated automatically after every change (with only 4 Fireleds, it is probably not worth changing this)

 

Orbit – FireLed Globe

Orbit – Fireled Globe

<Click any image to enlarge>

Purchase Orbit Here

Orbit is a FireLed Globe with 256 RGB LEDs and an integrated base.

It is constructed of 16 segments, each of 16 LEDs. The segments are plugged directly into the base.

There are 2 bases available: One supports Microbit and the other supports Raspberry Pi.

Power is provided via a USB connector on the base. You should use the highest current USB power supply that you have available. If all the LEDs are on maximum brightness and showing White (ie. all 3 internal LEDs are on) then it will consume more current than can be supplied. So please keep the brightness low (default is 40, maximum is 255). With brightness of 40, we find that a 3A USB supply is adequate for Microbit.

Assembling the Orbit

The kit comprises:

  • Base unit (either Microbit or Raspberry Pi)
  • 16 segments
  • O-Ring

Take each segment in turn and carefully plug it into the base unit.

When you have most of the segments plugged in you will have to be very careful not to dislodge any of the LEDs, so be careful plugging in and ensure that the LEDs do not catch.

When all the segments are plugged in, carefully move the tops around so that they form a rough circle of about 12mm diameter (slightly too small for my little finger to poke in)

Now the tricky bit. Take the O-Ring and push it into the slot on one of the segments. It will snap into place after a mm or two. Then use your finger nail (you have got finger nails, right?) to push the O-Ring into the next segment around the ring.

When it is complete, you should have a neat and tidy circle at the top of the Globe. It is now ready to program.

Programming in MakeCode

There is a Makecode extension available, although it hasn’t been formally released at the time of writing (March 2020). In Makecode, select Advanced | Extensions and then enter this URL in the search bar: https://github.com/4tronix/Orbit

You are then presented with a box to click and install the extension.

Clicking on the Orbit category in the Toolbox gives 3 options: Generic, SingleString and Latitude/Longitude. These provide 3 different ways to address the LEDs in the Orbit.

While assembling an Orbit, we like to have the following simple programming running in the Microbit. This displays Red, Green, Blue, White in sequence on all LEDs, so is a good test that every FireLed in each segment is working properly. It uses blocks from the Generic category

Another simple but very attractive program uses blocks from the Latitude/Longitude category. This creates a waterfall of rainbow colours.

You will note that nothing special is being done to ensure that the LEDs are updated whenever things change. This is because the default mode for this is “Automatic Update”. In the Generic category, you can change to “Manual Update” which will require you to use the “Show LED Changes” block after making changes to the LED colours

Using the Manual Update mode is recommended when making a lot of changes, because it speeds up the processing a lot if the Microbit doesn’t have to update all 125 FireLeds every time. So consider using this mode for more complex patterns

 

ZBot80 – Robot for RC2014 Mini

ZBot80 – Robot for RC2014 Mini

For Christmas 2019 I received the gift of a RC2014 Mini kit and I/O Board. This is a Z80 board that runs micro BASIC (other languages and operating systems are available). This was a great gift, because the first computer I ever designed used a Z80 CPU, so it took me back to my youth. See the RC2014 website for details and to purchase some of their excellent products.

Obviously, 4tronix is now known for developing small robots for various micro-controllers (Microbit, Raspberry Pi, Arduino, etc) so I clearly had to design a robot for this exciting new (old) computer.

The easiest way for me to do this would be to put an ATMega328P and a motor controller on a board and write a little firmware to handle commands from the Z80. But that goes against the spirit of the whole RC2014 ethos, so of course I had to design it using mainly 74 series logic gates. This post describes the specification and the design.

Specification

  • 4 x N20 Micro Metal Gear Motors. 6V, 240 rpm
  • Motor Driver chip: L293D
  • 2 channels of bi-directional PWM output. One channel for both left-side motors and the other channel for both right-side motors
  • Each PWM channel can take values from 0 to 127
    • Value 0 is motor off completely (0 %)
    • Value 127 is actually motor on for 127/128 of the time (99.22 %)
  • Z80 data writes are 8 bits. The bottom 7 bits define the PWM value (0 to 127). The top bit decides whether the motor turns forwards or backwards.
  • There are two 8-bit storage registers to hold the PWM and Direction bits for each channel.
  • The 2 registers then feed into the PWM generators (one for each channel)
  • The outputs of the PWM generators drive the L293D motor controller.
  • In addition to the logic there is a battery holder for 2 x 18650 batteries and a (linear) 5V regulator to power the robot and the RC2014 Mini

Operation Description

Download the complete schematic from here

Input Registers

<Click any image to enlarge>

There are two ‘273 registers which are each 8-bit, one for each channel (Only one register shown above). We use the reset signal on the Z80 bus to reset them to zero when the Z80 is reset. This stops the motors turning randomly on startup. Pressing the reset button on the RC2014 will guarantee stopping the motors

The rest of the logic is to correctly assign addresses 4 and 5 to these 2 registers. The ‘138 takes addresses A0, A2 and A3 as inputs, together with the Z80’s I/O request (IORQ) and Write Request (WR) signals. If everything is valid then the data on the Z80 data bus is written to the selected register. In Micro Basic, use OUT 4,nn or OUT 5,nn to write the selected PWM values.

There is another enable signal fed into the ‘138, which isn’t shown here, called SEL. This is generated by 4 diodes connected to address lines A4, A5, A6 and A7 with a pull down resistor. This is simply further address decoding, allowing the higher value address to be used for something else in the future.

How Does PWM Work?

PWM stands for Pulse Width Modulation. DC Motors tend to work best at, or close to, their rated voltage. Simply turning the voltage down will reduce their speed but it will also considerably reduce the torque and it won’t be long before the motor stops altogether.

A far better way to control the speed is to switch the power to the motor from full power to zero power many times per second. If the motor power is on for half the time, then we say this is a PWM of 50%. If the motor power is on all the time then it is 100%. If it is never on then it is 0%.

[Note that this value does not give you the speed. A PWM value of 80% will not give you a speed of 80% of the full power speed. In fact it is likely to be much more than that.]

In this case, I am using 7 bits of each input register to determine the PWM value. So I also have a ‘393 binary counter that continually counts from 0 to 127. The ‘393 is actually two separate 4-bit counters so we link the C3 output from the first into the clock of the second, creating a ripple counter. C7 is not needed as we only need values from 0 to 127

We then use a pair of ’85 comparator chips (2 chips per channel) to see if the counter value is less than the value in the register. If it is, then the appropriate input signal to the motor driver chip is enabled. The top bit of each register determines whether we drive the “Forwards” or “Reverse” signals on the motor driver

The other thing we need to consider is the frequency of the PWM signal. For these motors I usually find that a frequency of 30Hz to 100Hz is appropriate. I am using a very simple oscillator circuit made from two inverters, a capacitor and a resistor.

I set the capacitor to 100nF (as I had some around!) and the resistor to 1K. This gave a clock frequency of 5kHz. As were are counting in units of 128, the output frequency as seen by the motors will be 5000/128 = 39Hz. A bit low, but quite usable. It would probably be better to use 10nF capacitor and 4K7 resistor.

Completed Board

To fit this to the RC2014 Mini, you need to have downward facing male pins on the Z80 bus on the RC2014 Mini. As I also fitted the RC2014 I/O board to allow me to control the robot, I also needed upward facing pins. The answer was to fit to the RC2014 Mini a header with long pins. First I moved the plastic that holds the pins together so that it was central (push the small end into a female header, then pin-by-pin push each pin into the female header as far as it will go).

This gave me male pins on both sides of the RC2014 Mini so I could then fit both the ZBot80 and the I/O Board onto it:

Programming

To move the ZBot80 forwards, set both channels to the same speed forwards. Eg. Forwards at speed 60:

OUT 4,60
OUT 5,60

To move backwards, set both channels to the same speed, remembering to add 128 to each value (ie. set the top bit). So Reverse at 60 is:

OUT 4,188
OUT 5,188

To spin the ZBot80, set opposite speeds to each side. eg:

OUT 4,60
OUT 5,188

The rest is “just software” as my old boss used to say…

 

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

BitBot XL: On the BitBot XL these sensors are connected to Pin1 (Right) and Pin2 (Left). To get the current values of each sensor into variables rightVal and leftVal:

rightVal = pin1.read_analog()
leftVal = pin2.read_analog()

BitBot Classic: 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

SONAR = pin15

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)

Calibrating the Motors (v1.2 or later Only)

For version 1.2 of BitBot XL 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 BitBot XL, so even using different Microbits and different programs, you will still get the matched motors. For this to work you must use the latest BitBot XL Makecode extension.

The calibration Makecode program can be downloaded from >here<. Load it into your Makecode editor and download to the Microbit on the BitBot XL v1.2 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 BitBot XL 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 BitBot XL
  • Switch on the BitBot XL. it will display 5 (indicating a v1.2 BitBot XL), 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 BitBot XL a shake and it will store the values for speed 30 and move onto Speed 60.
  • Repeat for speed 60 and speed 90

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()

 

Programming M.A.R.S. Rover in Microsoft Makecode

Makecode for 4tronix M.A.R.S. Rover

Installing the Extension

In the Makecode editor, select “Advanced” and then “Extensions”. Alternatively click on the gear icon and select “Extensions” from there

Then enter Rover or Mars Rover in the seach bar

Click on the extension and it will be loaded into your Makecode editor. You will now have a rocket ship icon, Rover, with several sub-sections

Calibrating the Servos

Before we start using the Rover we should calibrate the servos so that they run directly.

Load this project into your Makecode editor: https://makecode.microbit.org/_Mpt6xpCRF0EK by selecting “Import”, then “Import URL”

Alternatively, download it from https://4tronix.co.uk/rover/microbit-CalibrateServos.hex

This program goes round all the wheel servos and allows you to use the A and B buttons on the Microbit to set each servo to straight ahead position.

It indicates using the LEDs which servo is being calibrated.

When you are happy with each servo, press the A+B buttons together to store the setting and move onto the next servo. After setting all servos, simply switch off and start coding.