micro:Bit Robot Cart & micro:Bit Tilt Controller

After the success of the Move Mini Bulldozer using a second micro:Bit as a Tilt controller; I decided to apply it to a more powerful Cart.

The chassis is from the first Robot Cart I ever made. Arduino UNO & Motor Driver, Raspberry Pi Zero & Camera, Controlled via a web page. Pi Zero sent camera images to web page and commands from the webpage to the Arduino to drive the motors and servos. It worked very well but had a few limitations.

Outside taking pics of bike. Camera movable on servos.

An earlier version showing just Arduino UNO and Motor Shield.

In this Cart I learnt a lot about the micro:Bit. Most important was; some library functions are not time sensitive, they must have built in delays which are not ideal when other parts of the code need to execute immediately. ie checking for a command from the Radio function. The motor driver board can drive four motors, which is ideal in this case, and 8 servos. (link to board below)

Using the controller tilt function to drive the Cart is not ideal and lacks sensitivity. The Cart tends to drive too far or not enough. My 7 & 5 year old grandchildren loved it because of the much more powerful motors, it would drive over things and push stuff around. It would even pull a wheel stand in reverse. But it was hard to drive it where you wanted it accurately. I think I will abandon the idea of using the tilt function to move the Cart, probably buy a Kitronik Game controller board.

But other features of the micro:Bit will used. Maybe use the compass to align the Cart in the same direction as the controller. Add some sensors to detect objects in front of it, and a movement sensing and recording ability.

The 5 year old is very interested in big machinery. We discussed adding a bulldozer type attachment that could actually lift stuff. I am already developing a design in my head.

Anyway, the micro:Bit journey continues.

Regards
Jim


Motor Board

Future purchase, push button control better than tilt, more accurate.

1 Like

Controller Code - Javascript from Make Code App.
Thought Iā€™d post this here, may be of use to someone.

input.onButtonPressed(Button.A, function () {
    if (Cmd == 7) {
        Cmd = 0
    } else {
        Cmd = 7
    }
})
function LED_Level () {
    Lvl = input.lightLevel()
    if (Lvl < 10) {
        Lvl = 10
    }
    led.setBrightness(Lvl)
}
function CheckMove () {
    if (control.millis() > LastCheck + 200) {
        Roll = input.rotation(Rotation.Roll)
        Pitch = input.rotation(Rotation.Pitch)
        LastCheck = control.millis()
        if (Roll < -30 && Math.abs(Pitch) < 30) {
            Cmd = 1
        } else if (Roll > 30 && Math.abs(Pitch) < 30) {
            Cmd = 2
        } else if (Math.abs(Roll) < 20 && Pitch < -20) {
            Cmd = 3
        } else if (Math.abs(Roll) < 20 && Pitch > 20) {
            Cmd = 4
        } else if (Roll < -20 && Pitch < -20) {
            Cmd = 5
        } else if (Roll > 20 && Pitch < -20) {
            Cmd = 6
        } else {
            Cmd = 0
        }
    }
}
input.onButtonPressed(Button.AB, function () {
    Cmd = 0
})
function LED_Burst (num: number) {
    for (let index = 0; index < 2; index++) {
        basic.showLeds(`
            . . . . .
            . . . . .
            . . # . .
            . . . . .
            . . . . .
            `)
        basic.pause(20)
        basic.showLeds(`
            . . . . .
            . # # # .
            . # # # .
            . # # # .
            . . . . .
            `)
        basic.pause(20)
        basic.showLeds(`
            # # # # #
            # # # # #
            # # # # #
            # # # # #
            # # # # #
            `)
        basic.pause(num)
        basic.clearScreen()
        basic.pause(100)
    }
    basic.showLeds(`
        . . . . .
        . . # . .
        . # # # .
        . . # . .
        . . . . .
        `)
}
input.onButtonPressed(Button.B, function () {
    if (Cmd == 8) {
        Cmd = 0
    } else {
        Cmd = 8
    }
})
function SendCmd () {
    if (Cmd != PrevCmd) {
        radio.sendNumber(Cmd)
        PrevCmd = Cmd
        basic.clearScreen()
        if (Cmd == 0) {
            led.plot(1, 2)
            led.plot(2, 1)
            led.plot(2, 2)
            led.plot(2, 3)
            led.plot(3, 2)
        } else if (Cmd == 1) {
            led.plot(0, 2)
            led.plot(1, 1)
            led.plot(1, 2)
            led.plot(1, 3)
            led.plot(2, 0)
            led.plot(2, 2)
            led.plot(2, 4)
            led.plot(3, 2)
            led.plot(4, 2)
        } else if (Cmd == 2) {
            led.plot(0, 2)
            led.plot(1, 2)
            led.plot(2, 0)
            led.plot(2, 2)
            led.plot(2, 4)
            led.plot(3, 1)
            led.plot(3, 2)
            led.plot(3, 3)
            led.plot(4, 2)
        } else if (Cmd == 3) {
            led.plot(0, 2)
            led.plot(1, 1)
            led.plot(2, 0)
            led.plot(2, 1)
            led.plot(2, 2)
            led.plot(2, 3)
            led.plot(2, 4)
            led.plot(3, 1)
            led.plot(4, 2)
        } else if (Cmd == 4) {
            led.plot(0, 2)
            led.plot(1, 3)
            led.plot(2, 0)
            led.plot(2, 1)
            led.plot(2, 2)
            led.plot(2, 3)
            led.plot(2, 4)
            led.plot(3, 3)
            led.plot(4, 2)
        } else if (Cmd == 5) {
            led.plot(0, 0)
            led.plot(0, 1)
            led.plot(0, 2)
            led.plot(1, 0)
            led.plot(1, 1)
            led.plot(2, 0)
            led.plot(2, 2)
            led.plot(2, 3)
            led.plot(2, 4)
        } else if (Cmd == 6) {
            led.plot(2, 0)
            led.plot(2, 2)
            led.plot(2, 3)
            led.plot(2, 4)
            led.plot(3, 0)
            led.plot(3, 1)
            led.plot(4, 0)
            led.plot(4, 1)
            led.plot(4, 2)
        }
    }
}
let Pitch = 0
let Roll = 0
let Lvl = 0
let LastCheck = 0
let PrevCmd = 0
let Cmd = 0
LED_Level()
LED_Burst(1)
Cmd = 0
PrevCmd = 0
let Count = 0
LastCheck = 0
radio.setGroup(1)
basic.forever(function () {
    if (Cmd != 7 && Cmd != 8) {
        CheckMove()
    }
    SendCmd()
})
1 Like

Cart Code - Javascript from Make Code App.

function Left (deg: number) {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Forward, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Forward, 70)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Reverse, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Reverse, 70)
    Delay = Math.map(deg, 0, 90, 0, 600)
    basic.pause(Delay)
    All_Off()
}
radio.onReceivedNumber(function (receivedNumber) {
    Command = receivedNumber
})
function Veer_Right () {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Forward, 50)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Forward, 50)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Forward, 20)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Forward, 20)
}
function Turn_Right () {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Reverse, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Reverse, 70)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Forward, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Forward, 70)
}
function All_Off () {
    Kitronik_Robotics_Board.motorOff(Kitronik_Robotics_Board.Motors.Motor1)
    Kitronik_Robotics_Board.motorOff(Kitronik_Robotics_Board.Motors.Motor2)
    Kitronik_Robotics_Board.motorOff(Kitronik_Robotics_Board.Motors.Motor3)
    Kitronik_Robotics_Board.motorOff(Kitronik_Robotics_Board.Motors.Motor4)
}
input.onButtonPressed(Button.A, function () {
    Turn_Left()
    basic.pause(1000)
    All_Off()
})
function LED_Level () {
    Lvl = input.lightLevel()
    if (Lvl < 10) {
        Lvl = 10
    }
    led.setBrightness(Lvl)
}
function LED_Burst (num: number) {
    for (let index = 0; index < 2; index++) {
        basic.showLeds(`
            . . . . .
            . . . . .
            . . # . .
            . . . . .
            . . . . .
            `)
        basic.pause(20)
        basic.showLeds(`
            . . . . .
            . # # # .
            . # # # .
            . # # # .
            . . . . .
            `)
        basic.pause(20)
        basic.showLeds(`
            # # # # #
            # # # # #
            # # # # #
            # # # # #
            # # # # #
            `)
        basic.pause(num)
        basic.clearScreen()
        basic.pause(100)
    }
}
function All_BCK (spd: number) {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Reverse, spd)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Reverse, spd)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Reverse, spd)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Reverse, spd)
}
function Veer_Left () {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Forward, 70)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Forward, 70)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Forward, 20)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Forward, 20)
}
function Turn_Left () {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Forward, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Forward, 70)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Reverse, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Reverse, 70)
}
function All_FWD (spd: number) {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Forward, spd)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Forward, spd)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Forward, spd)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Forward, spd)
}
function Right (deg: number) {
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor1, Kitronik_Robotics_Board.MotorDirection.Reverse, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor2, Kitronik_Robotics_Board.MotorDirection.Reverse, 70)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor3, Kitronik_Robotics_Board.MotorDirection.Forward, 80)
    Kitronik_Robotics_Board.motorOn(Kitronik_Robotics_Board.Motors.Motor4, Kitronik_Robotics_Board.MotorDirection.Forward, 70)
    Delay = Math.map(deg, 0, 90, 0, 600)
    basic.pause(Delay)
    All_Off()
}
let Lvl = 0
let Delay = 0
let Command = 0
LED_Level()
LED_Burst(1)
radio.setGroup(1)
let Speed = 90
Command = 0
basic.showIcon(IconNames.Yes)
basic.forever(function () {
    if (Command == 0) {
        All_Off()
    }
    if (Command == 1) {
        Left(30)
    }
    if (Command == 2) {
        Right(30)
    }
    if (Command == 3) {
        All_FWD(60)
    }
    if (Command == 4) {
        All_BCK(60)
    }
    if (Command == 5) {
        Veer_Left()
    }
    if (Command == 6) {
        Veer_Right()
    }
    if (Command == 7) {
        Turn_Left()
    }
    if (Command == 8) {
        Turn_Right()
    }
})
1 Like

Hi James,

Awesome work here! Lovely to see the quick progress you and your son are making :slight_smile:

Keep 'em coming!
-James