Repository navigation
add the extension
Load
pxt-diff-driveinto any micro:bit MakeCode project to get closed-loop driving, accurate turns and odometry on a Nezha robot.
Use this path when you already have a project, or want to start from a blank
one, and only need the robot driving blocks. You get the same diffDrive API
the template
uses, without its menu or example programs.
-
Open your project at https://makecode.microbit.org/, or click New Project.
-
Click the gear menu (⚙), then Extensions.
-
Paste this URL into the search box and press Enter:
https://github.com/League-Microbit/pxt-diff-drive -
Click the nezha-diffdrive card that appears.
A DiffDrive category appears in the toolbox. Its Setup subcategory holds the tuning blocks.
Which URL? The extension's source is
League-Robotics/pxt-nezha-diffdrive.
Every change there is published automatically to
League-Microbit/pxt-diff-drive,
a smaller copy with only what MakeCode needs. Add that one. It carries the same
version tags, for example v1.20260925.1.
The extension runs only on a micro:bit V2. It expects the left wheel on M2 and the right wheel on M1.
Switch to JavaScript, replace what's there with this, and download it:
basic.showIcon(IconNames.Happy)
// A: drive a 30 cm square, then show the heading it ended on
input.onButtonPressed(Button.A, function () {
diffDrive.resetPose()
for (let i = 0; i < 4; i++) {
diffDrive.move(30, 0) // 30 cm straight
diffDrive.move(0, 90) // turn 90° counter-clockwise
}
basic.showNumber(Math.round(diffDrive.heading()))
})
// B: drive 30 cm while a bar graph shows how far along it is
input.onButtonPressed(Button.B, function () {
diffDrive.whileMoving(30, 0, function (x, y, heading) {
led.plotBarGraph(diffDrive.moveProgress() * 100, 100)
})
basic.clearScreen()
})
// A+B: stop
input.onButtonPressed(Button.AB, function () {
diffDrive.stop()
basic.showIcon(IconNames.No)
})Everything is in centimetres, cm/s, degrees and degrees per second. A positive turn is counter-clockwise, to the left.
// Moves that finish before the next line runs
diffDrive.move(20, 0) // drive 20 cm straight
diffDrive.move(0, 90) // turn in place 90° left
diffDrive.goTo(30, 20) // curve to a point: 30 cm ahead, 20 cm left
// The same moves, but your code runs while the robot drives
diffDrive.whileMoving(50, 0, function (x, y, heading) {
if (input.buttonIsPressed(Button.A)) diffDrive.stopMove()
})
// Continuous driving: YOU keep the control loop running
diffDrive.driveTwist(15, 45) // 15 cm/s forward while turning 45°/s left
while (diffDrive.driveTick()) {
if (input.buttonIsPressed(Button.A)) diffDrive.stop()
}
// Where am I? (from the wheel encoders)
diffDrive.poseX(); diffDrive.poseY(); diffDrive.heading()
diffDrive.resetPose()
// Stopping, and noticing when the robot is stuck
diffDrive.stop()
diffDrive.emergencyStop()
diffDrive.isStalled()Why the while loop? The robot only moves while something keeps its
control loop running. move, goTo, whileMoving and whileGoingTo do that
for you. setWheelSpeeds and driveTwist only start driving: follow them
with while (diffDrive.driveTick()) { … }. When you leave that loop, the robot
coasts to a stop.
The defaults fit the standard Nezha kit. If your squares don't close, set your robot's measurements with the Setup blocks at the top of your program:
diffDrive.setTrackWidth(11.5) // cm between the wheel centres
diffDrive.setWheelCalibration(0.7837) // mm the wheel travels per motor degree
diffDrive.setDefaultSpeed(15) // cm/s for move and goToYou don't have to guess these numbers. The template's cal-wheels and cal-turn programs measure them; see Start from the template.
For the full block reference, and the rules for keeping the control loop running, see the extension README.