micro:bit

Here are a couple of projects for the BBC micro:bit to download and try out for yourself!


Brake/Tail Light

This is a novelty brake/tail light for your bike, scooter, skateboard, or R/C car!

Using the accelerometer it will make a bright brake light come on when you brake, and if you brake really hard the light will flash just like on some cars with LED taillights! There is also a dimmer tail light that optionally stays on all the time. You can also choose between a round and a square pattern for both the tail light and the brake light.

NOTE: Always use proper bicycle lights when riding at night! This is just a novelty for use in your garden or in the park, not on the road!

Here's the source code as a JSZ file, BrakeTailLight.jsz, which can be imported into the editor (and run on a real micro:bit after compiling yourself), OR you can use this hex file: BrakeTailLight.hex which can be both imported into the editor and run directly on a real micro:bit.


Cube/Stack Timer

Here’s a micro:bit program which simulates official Rubik’s Cube and cup stack competition timers.

Like the official timers, you have to hold both buttons to start the clock, and it only stops when you’ve pressed both buttons again. This is to ensure that you’ve put down the cube / not still touching any cups. The time (accurate to 1 millisecond) scrolls across the screen digitally at the end in an easy to read mm:ss.sss format (and repeats in case you missed it).



There’s a simulated BBC micro:bit right on the website so you don’t even have to have one yet to have fun with it:


Cut and paste the code below straight into the CodeKingdom’s JavaScript editor (in full code mode - that’s the fourth button along at the bottom of the window) which can be found here: https://www.microbit.co.uk/

Alternatively, here is the source code as a JSZ file, CubeStackTimer.jsz, which can be imported into the editor (and run on a real micro:bit after compiling yourself), OR you can use this hex file: CubeStackTimer.hex which can be both imported into the editor and run directly on a real micro:bit.

Note: This is v1.1 as I had to modify the code to fix a couple of bugs that were apparent on a real micro:bit that didn’t show up in the simulator.


// Rubik's Cube / Cup Stack Timer

// 

// by James Shaughnessy - See www.demonstudios.com/microbit.html for more micro:bit apps!

// 

// v1.1 (fixed to work properly on actual hardware)

// 

// You must press A and B to both start and stop the timer, just like official competition timers

// Accurate to 1 millisecond (0.001 of a second), and displays the time in mm:ss.sss format

// (or just ss.sss if under one minute)

// While running a nifty animated analogue split-second hand spins around

// Feel free to change the code, reuse, remove these credits and pass on as desired!

// Why not see how you could improve/optimise the code, or perhaps add new features like another clock hand.

// This could even be modified to read the pins on the micro:bit so that instead of using the fiddly

// on-board buttons, e.g. start and stop the timer by touching two bananas!

// 

// globals.state values:

// 0 - waiting for start (show animated arrows)

// 1 - ready to start    (A and B are held, show solid square)

// 2 - running           (show animated clock hand)

// 3 - showing result    (show the time repeatedly)

// 

/* When the BBC micro:bit runs                                                                              */

function onStart(  ) {

    globals.state = 0;

    globals.timeAtStart = 0;

    globals.timeAtEnd = 0;

    globals.runTime = 0;

    while (true) {

        // If 'waiting for start'

        if (globals.state == 0) {

            // If both A and B are pressed

            if (microbit.buttonAPressed && microbit.buttonBPressed) {

                // Go to 'ready to start'

                globals.state = 1;

            }

            else if (Math.mod(microbit.runningTime, 1000) < 500) {

                // We are under the half second, so draw the arrows together,

                // but not drawing an arrow if either A or B are held

                if (microbit.buttonAPressed) {

                    microbit.draw(Pattern("00000.00010.00011.00010.00000"));

                }

                else if (microbit.buttonBPressed) {

                    microbit.draw(Pattern("00000.01000.11000.01000.00000"));

                }

                else {

                    microbit.draw(Pattern("00000.01010.11011.01010.00000"));

                }

            }

            else {

                // We are over the half second, so draw the arrows apart,

                // but not drawing an arrow if either A or B are held

                if (microbit.buttonAPressed) {

                    microbit.draw(Pattern("00000.00100.00110.00100.00000"));

                }

                else if (microbit.buttonBPressed) {

                    microbit.draw(Pattern("00000.00100.01100.00100.00000"));

                }

                else {

                    microbit.draw(Pattern("00000.00100.01110.00100.00000"));

                }

            }

        }

        else if (globals.state == 1) {

            // Ready to start, so if either A or B are not pressed then we can start

            if (( ! microbit.buttonAPressed ) || ( ! microbit.buttonBPressed )) {

                // Record the running time at the start

                globals.timeAtStart = microbit.runningTime;

                // Go to 'running'

                globals.state = 2;

            }

            else {

                // Ready to start

                microbit.draw(Pattern("11111.11111.11111.11111.11111"));

            }

        }

        else if (globals.state == 2) {

            // Running, so if both A and B are pressed then stop the timer

            if (microbit.buttonAPressed && microbit.buttonBPressed) {

                // Record the actual timer run time, which is the difference

                // between the runningTime (stored earlier) at the start and

                // the runningTime at the end

                globals.timeAtEnd = microbit.runningTime;

                globals.runTime = globals.timeAtEnd - globals.timeAtStart;

                // Draw a chequered flag and wait one second 

                microbit.draw(Pattern("10101.01010.10101.01010.10101"));

                wait(1000);

                // Go to 'showing result'

                globals.state = 3;

            }

            else {

                // Show an animated clock hand where one rotation is one second

                // There are 16 positions for the hand (hence why the divisor is 16)

                globals.runTime = microbit.runningTime - globals.timeAtStart;

                var s = Math.mod(globals.runTime, 1000);

                // If under 1/16th of a second (1000ms / 16)

                if (s < ( 1000 / 16 )) {

                    microbit.draw(Pattern("00100.00100.00100.00000.00000"));

                }

                else if (s < ( 2000 / 16 )) {

                    microbit.draw(Pattern("00010.00010.00100.00000.00000"));

                }

                else if (s < ( 3000 / 16 )) {

                    microbit.draw(Pattern("00001.00010.00100.00000.00000"));

                }

                else if (s < ( 4000 / 16 )) {

                    microbit.draw(Pattern("00000.00001.00110.00000.00000"));

                }

                else if (s < ( 5000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00111.00000.00000"));

                }

                else if (s < ( 6000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00100.00011.00000"));

                }

                else if (s < ( 7000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00100.00010.00001"));

                }

                else if (s < ( 8000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00100.00100.00010"));

                }

                else if (s < ( 9000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00100.00100.00100"));

                }

                else if (s < ( 10000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00100.01000.01000"));

                }

                else if (s < ( 11000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.00100.01000.10000"));

                }

                else if (s < ( 12000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.01100.10000.00000"));

                }

                else if (s < ( 13000 / 16 )) {

                    microbit.draw(Pattern("00000.00000.11100.00000.00000"));

                }

                else if (s < ( 14000 / 16 )) {

                    microbit.draw(Pattern("00000.11000.00100.00000.00000"));

                }

                else if (s < ( 15000 / 16 )) {

                    microbit.draw(Pattern("10000.01000.00100.00000.00000"));

                }

                else {

                    // (s < ( 16000 / 16 )), which will always true if we got here

                    microbit.draw(Pattern("01000.00100.00100.00000.00000"));

                }

            }

        }

        else {

            // state == 3 (show result)

            // Shows the time repeatedly while in the end of game state

            microbit.clear();

            // Construct a string that converts total milliseconds into mm:ss.sss,

            // adding leading zeroes if needed to the seconds and milliseconds

            // If the time is under one minute the number of minutes is omitted

            var minutes = globals.runTime / 60000;

            var seconds = Math.mod(globals.runTime / 1000, 60);

            var milliseconds = Math.mod(globals.runTime, 1000);

            var timeString = "";

            // If over a minute 

            if (minutes > 0) {

                // Add the number of minutes onto the string

                timeString = ( timeString + minutes ) + ":";

                // If the number of seconds is under 10 add a leading zero

                if (seconds < 10) {

                    timeString = timeString + "0";

                }

            }

            // Add the number of seconds onto the string

            timeString = ( timeString + seconds ) + ".";

            // Add leading zeroes as needed

            if (milliseconds < 100) {

                timeString = timeString + "0";

                if (milliseconds < 10) {

                    timeString = timeString + "0";

                }

            }

            // Add the number of milliseconds onto the time

            timeString = timeString + milliseconds;

            // 'Say' the time string and wait a second before showing it again

            microbit.say(timeString, 100);

            wait(1000);

        }

    }

}


function onPressA(  ) {

    // If showing result

    if (globals.state == 3) {

        // Go to 'waiting for start'

        globals.state = 0;

    }

}


function onPressB(  ) {

    // If showing result

    if (globals.state == 3) {

        // Go to 'waiting for start'

        globals.state = 0;

    }

}


© 2017 DemonStudios Ltd