MakeCode coding tutorial - bitty data logger

micro:bit code

Bitty Data Logger can capture and chart accelerometer, magnetometer, temperature data and data from connected, external sensors. Your micro:bit will need the right code for Bitty Data Logger to work properly.

As with all our apps you can simply download and install a hex file which we've prepared for you or you can code it yourself, following the Bitty Software coding tutorial below. Naturally, we recommend you code it yourself!

Let's write that code using the MakeCode tool, right now.


before you start

You should install the bitty data logger application on your phone so you can use it for testing whilst you develop the micro:bit code. Check the bitty data logger page for details of where to find the app for your type of phone or tablet.


step 1 - MakeCode

Go to the MakeCode web site in your web browser or if you're already there, start a new project by clicking on the menu icon and then New Project.


step 2 - make sure your project includes the right packages

Packages

MakeCode groups function blocks together in "packages" and these are listed in a column. A screenshot of a list of MakeCode packages is shown above. By default it includes a package called "Radio" which allows you to use a very simple wireless capability of the micro:bit. "Radio" is good if you want to broadcast a short string of characters to any / all micro:bits around. It's not Bluetooth and is not what we need for the Bitty Data Logger application. Most importantly, a MakeCode project cannot include both the Radio package and the Bluetooth package at the same time. Add the Bluetooth package to your project and when prompted to, choose to remove the radio package.

Click on the menu icon, Add Package and select the bluetooth package.

When prompted, opt to remove the radio package


step 3 - Variables and Bluetooth Services

We'll start by declaring and initialising some variables. You'll discover what each of them are for later on. We'll also include the Bluetooth accelerometer, magnetometer and temperature services in our code. These are special software components which make the given type of data available over Bluetooth to another device. Sensor data will use something called the event service, but that's automatically included in all MakeCode projects, so we don't need to do anything to include it as it will be there automatically.

Add the following code. If you use JavaScript, you can use "let" to declare variables. If you're just using the Blocks editor, use the Variable package's "set item to..." block.


step 4 - Bluetooth connection tracking

Now we'll use some of the blocks in the Bluetooth package to add connection tracking to our project. What we'll do is set the "connection" variable to 1 whenever a connection is established and display "C" on the micro:bit display or we'll set the variable to 0 and display "D" if a connection gets dropped.

From the Bluetooth tray, click on the "on bluetooth connected" block and then the "on bluetooth disconnected" block to add them to your project.


step 5 - The Sampling Frequency Event - 9021

Bitty Data Logger will communicate with the micro:bit by sending events over Bluetooth. An event has a numeric ID to indicate what type of event it is and an associated, numeric value. One of the events that will be received by the micro:bit is event 9021 whose value will be the frequency with which the micro:bit pins 0, 1 and 2 should be read, in milliseconds.

Add the folowing blocks to handle event 9021:


step 6 - The Pin Selection Event - 9020

Bitty Data Logger will send event 9020 to indicate which of pins 0, 1 and 2 the micro:bit should be sampling. Add the following blocks:

Pin selection event values contain a bit mask where bit n selects pin n, where n <= 2

Note that if any one or more of the three pins has been selected, out code raises event 9022. We'll add a new event handler for this event type next. This is where we start reading values from the micro:bit pins.


step 7 - The Start Sampling Event - 9022

Event 9022 starts a loop in which selected pins will be read at a frequency determined by the sampling_frequency_ms variable. Add the following blocks:

Each time we read from a pin, we calculate two variables, analog_value and pin and then call a function transmitSensorData. Our final coding task is to write that function.


step 8 - The transmitSensorData function

Add the following blocks:

The pin number and analog value read from that pin, get combined by applying a bitwise OR operation. We then include the composite value in event 9030. Event code 9030 is sent to Bitty Data Logger over Bluetooth because Bitty Data Logger has sent a message to the micro:bit to indicate that it is interested in that type of event. We don't have to write any code to handle that interaction, it's taken care of by the micro:bit firmware automatically. The net effect of this function though, is that the analog value read from a pin is sent over Bluetooth, together with the number of the pin the data came from, to Bitty Data Logger.


step 9 - testing

That's it! You've created a cool micro:bit application which can send accelerometer, magnetometer, temperature data and sensor data to the Bitty Data Logger application.

You should now test your code carefully and fix any problems you find. Good luck and enjoy having fun with bitty data logger!


if you get stuck

Take a close look at the solution here.

Or edit the solution live in MakeCode!

Or copy and paste the following code into the JavaScript editor in MakeCode:

    let sampling_frequency_ms = 0
    let connected = 0
    bluetooth.onBluetoothConnected(() => {
        connected = 1
        basic.showString("C")
    })
    bluetooth.onBluetoothDisconnected(() => {
        connected = 0
        basic.showString("D")
    })
    // pin select event over Bluetooth
    control.onEvent(9020, EventBusValue.MICROBIT_EVT_ANY, () => {
        pin0_selected = control.eventValue() & 1;
    pin1_selected = control.eventValue() & 2;
    pin2_selected = control.eventValue() & 4;
    if (pin0_selected != 0 || pin1_selected != 0 || pin2_selected != 0) {
            control.raiseEvent(
            9022,
            EventBusValue.MICROBIT_EVT_ANY
            )
        }
    })
    function transmitSensorData()  {
        pin_shifted = pin << 14;
    let ev = pin_shifted | analog_value;
    serial.writeValue("pin", pin)
        serial.writeValue("val", ev)
        control.raiseEvent(
        9030,
        ev
        )
    }
    // sample loop, started from the pin select event
    // handler
    control.onEvent(9022, EventBusValue.MICROBIT_EVT_ANY, () => {
        basic.showString("S")
        while (connected == 1 && (pin0_selected != 0 || pin1_selected != 0 || pin2_selected != 0)) {
            if (pin0_selected != 0) {
                analog_value = pins.analogReadPin(AnalogPin.P0)
                pin = 0
                transmitSensorData()
            }
            if (pin1_selected != 0) {
                analog_value = pins.analogReadPin(AnalogPin.P1)
                pin = 1
                transmitSensorData()
            }
            if (pin2_selected != 0) {
                analog_value = pins.analogReadPin(AnalogPin.P2)
                pin = 2
                transmitSensorData()
            }
            basic.pause(sampling_frequency_ms)
        }
        basic.showString("X")
    })
    // sampling frequency being set over Bluetooth
    control.onEvent(9021, EventBusValue.MICROBIT_EVT_ANY, () => {
        sampling_frequency_ms = control.eventValue()
    })
    let pin = 0
    let pin0_selected = 0
    let pin1_selected = 0
    let pin2_selected = 0
    let analog_value = 0
    let pin_shifted = 0
    sampling_frequency_ms = 1000
    bluetooth.startAccelerometerService()
    bluetooth.startMagnetometerService()
    bluetooth.startTemperatureService()
    basic.forever(() => {
      
    })