CODE
This section outlines the logic and implementation of the micro:bit code for transmitting and receiving data, including altitude measurements from the BMP280 sensor.
I used the BBC micro:bit MakeCode editor to build a rocket telemetry system with two micro:bits — one on the rocket and one as a ground receiver.
I used the BMP280 sensor for altitude and temperature, and the built-in accelerometer to calculate speed and detect launch/landing.
TRANSMITTER
RECIEVER
I set it up to start logging and sending data automatically after detecting launch, and to send max speed and altitude after landing. The receiver displays live data and cycles through speed, altitude, temperature, and max values using button A.
I kept the system simple, automated, and reusable, with reset functions and efficient radio communication for real-time tracking.
This simulation showcases how the Micro:Bit transmitter and receiver will operate during the water rocket flight, displaying the kind of real-time data transmission and reception we can expect once the code is installed and the system is deployed in the actual rocket.
Download
// Note: Add the BMP280 extension before using this code
let currentSpeed = 0
let maxSpeed = 0
let lastTime = 0
let currentTime = 0
let timeDifference = 0
let currentAltitude = 0
let maxAltitude = 0
let groundAltitude = 0
let temperature = 0
let isLaunched = false
let landedCounter = 0
let dataString = ""
let dataLogging = false
let telemetryCounter = 0
radio.setGroup(1)
radio.setTransmitPower(7)
basic.showString("RKT")
BMP280.PowerOn()
basic.pause(1000)
resetAll()
function resetAll() {
currentSpeed = 0
maxSpeed = 0
currentAltitude = 0
maxAltitude = 0
isLaunched = false
landedCounter = 0
dataLogging = false
lastTime = input.runningTime()
telemetryCounter = 0
basic.clearScreen()
}
function calibrateAltitude() {
basic.showString("CAL")
let sum = 0
for (let i = 0; i < 10; i++) {
sum += BMP280.altitude()
basic.pause(100)
}
groundAltitude = sum / 10
basic.showIcon(IconNames.Yes)
basic.pause(500)
basic.clearScreen()
}
function updateSpeed() {
let acceleration = input.acceleration(Dimension.Strength)
currentTime = input.runningTime()
timeDifference = (currentTime - lastTime) / 1000
if (timeDifference > 0) {
currentSpeed = currentSpeed + (acceleration / 1000) * timeDifference
if (currentSpeed > maxSpeed && isLaunched) {
maxSpeed = currentSpeed
}
}
lastTime = currentTime
return acceleration
}
function updateAltitude() {
let rawAltitude = BMP280.altitude()
currentAltitude = rawAltitude - groundAltitude
if (currentAltitude > maxAltitude && isLaunched) {
maxAltitude = currentAltitude
}
return currentAltitude
}
function detectLaunch(acceleration: number) {
if (acceleration > 1500 && !isLaunched) {
isLaunched = true
dataLogging = true
basic.showIcon(IconNames.Butterfly)
radio.sendString("LAUNCH")
}
}
function detectLanding(acceleration: number) {
if (isLaunched && acceleration < 1200) {
landedCounter += 1
} else {
landedCounter = 0
}
if (landedCounter > 10 && isLaunched) {
isLaunched = false
dataLogging = false
radio.sendString("LANDED:" +
"SPD=" + Math.round(maxSpeed) +
",ALT=" + Math.round(maxAltitude))
showLandingData()
}
}
function showLandingData() {
basic.clearScreen()
basic.showString("MAX:")
basic.showString("S:" + Math.round(maxSpeed) + "m/s")
basic.showString("A:" + Math.round(maxAltitude) + "m")
}
function transmitTelemetry() {
if (dataLogging) {
telemetryCounter += 1
if (telemetryCounter >= 5) {
telemetryCounter = 0
temperature = BMP280.temperature() / 100
dataString = "DATA:" +
Math.round(currentSpeed) + "," +
Math.round(currentAltitude) + "," +
Math.round(temperature)
radio.sendString(dataString)
}
}
}
basic.forever(function () {
let acceleration = updateSpeed()
let altitude = updateAltitude()
detectLaunch(acceleration)
detectLanding(acceleration)
transmitTelemetry()
basic.pause(100)
})
input.onButtonPressed(Button.A, function () {
if (!isLaunched) {
calibrateAltitude()
}
})
input.onButtonPressed(Button.B, function () {
basic.showString("S:" + Math.round(currentSpeed))
basic.showString("A:" + Math.round(currentAltitude))
})
input.onButtonPressed(Button.AB, function () {
resetAll()
basic.showString("RESET")
})Transmitter Javascript
Reciever Javascript
let receivedString = ""
let dataValues: string[] = []
let currentSpeed = 0
let currentAltitude = 0
let currentTemp = 0
let maxSpeed = 0
let maxAltitude = 0
let dataMode = 0 // 0=speed, 1=altitude, 2=temp, 3=max values
let rocketLaunched = false
let rocketLanded = false
radio.setGroup(1)
basic.showString("RCV")
radio.onReceivedString(function(receivedString) {
if (receivedString == "LAUNCH") {
rocketLaunched = true
rocketLanded = false
basic.showIcon(IconNames.Butterfly)
basic.pause(1000)
}
else if (receivedString.includes("LANDED:")) {
rocketLanded = true
rocketLaunched = false
let landData = receivedString.substr(7)
let parts = landData.split(",")
if (parts.length >= 2) {
let speedPart = parts[0]
if (speedPart.includes("SPD=")) {
maxSpeed = parseInt(speedPart.substr(4))
}
let altPart = parts[1]
if (altPart.includes("ALT=")) {
maxAltitude = parseInt(altPart.substr(4))
}
}
basic.showIcon(IconNames.Square)
music.playTone(Note.C5, music.beat(BeatFraction.Whole))
}
else if (receivedString.includes("DATA:")) {
let telemetryData = receivedString.substr(5)
dataValues = telemetryData.split(",")
if (dataValues.length >= 3) {
currentSpeed = parseInt(dataValues[0])
currentAltitude = parseInt(dataValues[1])
currentTemp = parseInt(dataValues[2])
}
if (currentSpeed > maxSpeed) maxSpeed = currentSpeed
if (currentAltitude > maxAltitude) maxAltitude = currentAltitude
led.toggle(0, 0)
}
})
basic.forever(function() {
if (rocketLaunched && !rocketLanded) {
if (dataMode == 0) {
// Show current speed
basic.clearScreen()
basic.showString("S:" + currentSpeed)
} else if (dataMode == 1) {
basic.clearScreen()
basic.showString("A:" + currentAltitude)
} else if (dataMode == 2) {
basic.clearScreen()
basic.showString("T:" + currentTemp)
} else {
basic.clearScreen()
basic.showString("MS:" + maxSpeed + " MA:" + maxAltitude)
}
}
if (rocketLanded) {
if (dataMode == 0) {
basic.showString("MAX SPD:")
basic.showNumber(maxSpeed)
} else if (dataMode == 1) {
basic.showString("MAX ALT:")
basic.showNumber(maxAltitude)
} else {
basic.showString("LANDED")
}
}
basic.pause(1000)
})
input.onButtonPressed(Button.A, function() {
dataMode = (dataMode + 1) % 4
if (dataMode == 0) {
basic.showString("SPD")
} else if (dataMode == 1) {
basic.showString("ALT")
} else if (dataMode == 2) {
basic.showString("TEMP")
} else {
basic.showString("MAX")
}
})
input.onButtonPressed(Button.B, function() {
basic.showString("MAX:")
basic.showString("S:" + maxSpeed)
basic.showString("A:" + maxAltitude)
})
input.onButtonPressed(Button.AB, function() {
maxSpeed = 0
maxAltitude = 0
currentSpeed = 0
currentAltitude = 0
currentTemp = 0
rocketLaunched = false
rocketLanded = false
basic.showString("RESET")
})