Coding Tips


Bitty Data Logger Bitty Controller Bitty Blue Bitty Audio Prank Bitty Xmas Bauble


Bitty Data Logger

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

Code examples for you to learn from and adapt to your needs are available in the Bitty Data Logger code repository.

Find the right sample for your needs, create a MakeCode project, switch to JavaScript view and simply paste the code from our repository, into your MakeCode project.

Let's review a couple of examples:

AUTO capture mode and accelerometer data


            let connected = 0
            bluetooth.onBluetoothConnected(function () {
                connected = 1
                basic.showString("C")
            })
            bluetooth.onBluetoothDisconnected(function () {
                connected = 0
                basic.showString("D")
            })
            bluetooth.startAccelerometerService()


When you create your project, you must remember to add the Bluetooth extension from within the Advanced menu on the left. For ease of use, it is also recommended that you go into your project settings and switch off pairing (unless you know you wish to have security, in which case select from one of the other two pairing options).

This is very simple code, as you can see. We have two events handlers, one to respond to a Bluetooth connection being accepted from anotyher device, like a smartphone (onBluetoothConnected) and one for when the connection is lost (onBluetoothDisconnected).

The only other significant code is the line bluetooth.startAccelerometerService() which includes the Bluetooth accelerometer service. This is a code block which takes care of sampling from the accelerometer and transmitting the readings over Bluetooth, all automatically.

USER Code capture mode and general data


            let connected = 0
            bluetooth.onBluetoothConnected(function () {
                connected = 1
                starttime = input.runningTime()
            })
            bluetooth.onBluetoothDisconnected(function () {
                connected = 0
            })
            let message_type = 0
            let timestamp = 0
            let starttime = 0
            let value1 = 0
            let value2 = 0
            let value3 = 0
            let value4 = 0
            
            bluetooth.startUartService()
            let message = pins.createBuffer(11);
            
            function transmitData() {
                timestamp = input.runningTime() - starttime
                message.setNumber(NumberFormat.Int8LE, 0, message_type);
                message.setNumber(NumberFormat.Int32BE, 1, timestamp);
                message.setNumber(NumberFormat.Int16BE, 5, value1);
                message.setNumber(NumberFormat.Int16BE, 7, value2);
                message.setNumber(NumberFormat.Int16BE, 9, value3);
                bluetooth.uartWriteBuffer(message)
            }
            basic.forever(function () {
                if (connected == 1) {
                    message_type = 1
                    // random numbers used solely for demonstration purposes. Acquire your data here as required.
                    value1 = Math.randomRange(0, 1023)
                    transmitData()
                    message_type = 2
                    // random numbers used solely for demonstration purposes. Acquire your data here as required.
                    value1 = Math.randomRange(0, 1023)
                    transmitData()
                    message_type = 3
                    // random numbers used solely for demonstration purposes. Acquire your data here as required.
                    value1 = Math.randomRange(0, 1023)
                    transmitData()
                    message_type = 4
                    // random numbers used solely for demonstration purposes. Acquire your data here as required.
                    value1 = Math.randomRange(0, 1023)
                    transmitData()
                }
                basic.pause(1000)
            })   


bluetooth.startUartService() creates the Bluetooth UART service. This service allows data to be sent as messages to the connected device and is the way 'general data' is sent to Bitty Data Logger since the release of version 4.0.

let message = pins.createBuffer(11) creates a 'buffer'. This is an area of memory which can contain (in this case), 11 bytes of data. We use the buffer to formulate messages in the required format before transmitting them over Bluetooth.

In the forever block, we loop... forever and in this case we generate general data item values as random numbers. You would probably acquire those values from somewhere else, perhaps reading from an analog pin to which a sensor has been connected. The type of data to be transitted to Bitty Data Logger is identified by a message type value. This is then set and a variable corresponding to the general data item # (1 - 4) has the value stored in it. We then call a function called transmitData() which completes the formulation of the message in the buffer and transmits it using the Bluetooth UART service.


Bitty Controller

Common Information

Regardless of what you choose to control, there's some common technical information which always applies concerning how Bitty Controller communicates with a micro:bit.

The General Approach

Bitty Controller uses Bluetooth to communicate with a microcontroller such as a BBC micro:bit or Arduino or with a computer such as a Raspberry Pi. Here, we'll use the term remote device to refer to the thing Bitty Controller is connected to over Bluetooth or sometimes, just device.

Bitty Controller sends special data values to the remote device over Bluetooth to indicate something the user just did, such as pressing or releasing one of the pads in the D-Pad controller user interface (UI) or sliding the trackball up the touchpad with a finger. It is then up to the code on the micro:bit to decide what to do with the data it receives. Perhaps a motor will be started or a light flashed.

Writing code for a remote device to respond to Bitty Controller falls into two parts therefore.

1. Communication between Bitty Controller and the remote device
Bitty Controller does not know what is electrically connected to the remote device. What it sends to the remote device varies only according to the action taken by the user when interacting with the UI and is not affected by what the remote device is connected to.

Code on the remote device will therefore need to ensure that it handles relevant communication from Bitty Controller and then use appropriate logic to initiate the required action.

2. Controlling things physically connected to the remote device
Having determined what it is that the user just did, by examining the data received from Bitty Controller, the remote device code will need to perform some kind of action to instigate the required type of control. Maybe this means rotating a servo through 90 degrees. Maybe it means speeding a motor up to full speed. Or maybe it means flashing a series of LEDs. It could mean anything and this is where you, the firmware developer will need to know what it is that you want to do and how to go about accomplishing it with your device's APIs or graphical programming blocks. This will require you to have some information about your device such as which pins its motors are connected to.

The Bitty Controller example code here at bittysoftware.com is a good source of information on the details of controlling a variety of popular bots and other maker kits.

A Choice of Two Communication Styles

Bitty Controller supports two styles of communication or to be more technically accurate, two distinct Bluetooth profiles. You will need to decide which of these is best for the type of remote device you are using.

If you are unfamiliar with terms like profile or Bluetooth characteristic, you should take 5 minutes to read our Bluetooth Low Energy for Beginners page.

The micro:bit profile

The micro:bit profile is, per the name was originally designed for the BBC micro:bit and tools like MakeCode support it. It uses a system of micro:bit events to indicate user interactions and micro:bit code must register to receive and handle particular event types.

The micro:bit profile also allows pins to be written to directly, without the need for special micro:bit code written by you (the code is standard and included within the micro:bit base firmware, known as the DAL).

There's nothing to stop you using the micro:bit profile on a device which is not a BBC micro:bit. If your device allows custom Bluetooth profiles to be created using APIs, then you can implement the micro:bit profile, and Bitty Controller will think it's communicating with a micro:bit.

The micro:bit profile is documented at https://lancaster-university.github.io/microbit-docs/ble/profile/. Bitty Controller uses the Event Service for most interactions and the IOPin Service for the on/off switch UI.

Now review details of how communication from Bitty Controller works when using the micro:bit profile.

The serial profile

Some Bluetooth modules such as the popular (and cheap) HM-10 provide a very simple Bluetooth profile which mimics a serial interface, allowing a connected device to read or write arbitrary sequences of byte values in much the way you would if the connection was formed from a physical, serial cable.

The profile consists of a single custom service with a single characteristic. To send data to the remote device, Bitty Controller writes to this characteristic. To receive data from the remote device, the code on the remote device must send it as a Bluetooth notification on this single characteristic.

The serial profile has the following design. Note that the 128-bit UUIDs can be configured in the Bitty Controller Options screen so it is not necessary to use the examples shown here, which are the values used by an HM-10 module by default.

        Service: serial service
            Characteristic: serial_buffer
              Properties: NOTIFY, READ, WRITE, WRITE NO RESPONSE 
            Descriptor: Client Characteristic Configuration

The service and its characteristic, as implemented on an HM-10 module is shown here. The screenshot is from the nRF Connect mobile application.



Now review details of how communication from Bitty Controller works when using the serial profile.

What do you want to control?


1. Roger Wagner's Makerbit


1.1 Controlling the MakerBit Smart Car

The MakerBit Smart Car has a BBC micro:bit connected to it via its edge connector. Switching specific edge connector pins on or off causes either or both of the motors which drive the Smart Car's wheels to be switched on and running either forwards or backwards or to be stopped completely. Other pins control the speed the motors run at. The different combinations of pin state and the actions they cause are summarised in the following table:


PIN 11 PIN 12 PIN 13 PIN 14 PIN 15 PIN 16 EFFECT
0 0 0 0 0 0 All motors off
1 0 Motor A forwards
0 1 Motor A backwards
0 0 Motor A off
0 0 0 0 0 0 All motors off
1 0 Motor B forwards
0 1 Motor B backwards
0 0 Motor B off
1 or PWM 0-255 Motor A speed
1 or PWM 0-255 Motor B speed


1.2 MakeCode Examples for Roger Wagner's MakerBit


For use with the Bitty Controller Touchpad UI

For use with the Bitty Controller D-Pad UI

2. GiggleBot



GiggleBot uses something called I2C which is pronounced "I squared C" to communicate with its various components, such as the motors that drive the wheels. This is a different approach to some other bots which require you to write analog or digital values to specific micro:bit pins to control the direction and speed of motors but... it turns out to be very easy to use, especially since MakeCode has I2C blocks available.

When using I2C, we're required to specify an I2C address and a value. In our case, the I2C address for the GiggleBot motors is 4. Best of all, GiggleBot's use of I2C allows us to provide a command meaning "set the power to the motors" and values for the power level of each of the two motors in a single operation, represented by a single MakeCode block.

The Bluetooth communication between Bitty Controller and the GiggleBot is the same as for other bots and varies depending on whether you are using the D-Pad UI, the touchpad UI or the touchpad with sensor data UI. Review other Bitty Controller tutorials to see more details on this topic.


To make your own, look at these examples:





3. 4tronix Bit:Bot



The 4tronix Bit:Bot uses pins as follows:


PIN Purpose Digital Values Analog (PWM) Values
0 Left motor speed 0=stopped, 1=full speed 0-1023 where 0=always off, 1023=always and (e.g.) 511=50% on
1 Right motor speed 0=stopped, 1=full speed 0-1023 where 0=always off, 1023=always and (e.g.) 511=50% on
8 Left motor direction 0=forwards, 1=backwards N/A
12 Right motor direction 0=forwards, 1=backwards N/A

There are MakeCode examples for the 4tronix Bit:Bot here: https://github.com/bittysoftware/bitty_controller_device_code/tree/master/microbit/makecode

4. Kitronik Buggies


Controlling the Kitronik buggy

The Kitronik buggy has a BBC micro:bit connected to it via its edge connector. Switching specific edge connector "pins" on or off causes either or both of the motors which drive the buggy's wheels to be switch on and running either forwards or backwards, or stopped completely. The different combinations of pin state and the actions they cause are summarised in the following table:

PIN 0 PIN 8 PIN 12 PIN 16 EFFECT
OFF OFF OFF OFF Buggy is stopped
OFF OFF ON ON Buggy drives forwards in a straight line
ON ON OFF OFF Buggy drives backwards in a straight line
OFF OFF ON OFF Buggy turns left in the forwards direction
OFF OFF OFF ON Buggy turns right in the forwards direction
OFF ON OFF OFF Buggy turns left in the backwards direction
ON OFF OFF OFF Buggy turns right in the backwards direction

There are MakeCode examples for the Kitronik buggies here: https://github.com/bittysoftware/bitty_controller_device_code/tree/master/microbit/makecode



Bitty Blue

Example code which will allow your micro:bit to be used with the various functions of the Bitty Blue application is available here: https://github.com/bittysoftware/microbit_blue_device_code 


Bitty Audio Prank

Example code which will allow your micro:bit to be used with the Bitty Audio Prank application is available here: https://github.com/bittysoftware/bitty_audio_prank_device_code

This application is no longer available


Bitty Xmas Bauble

Example code which will allow your micro:bit to be used with the Bitty Xmas Bauble application is available here: https://github.com/bittysoftware/bitty_xmas_bauble_device_code

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Bluetooth communication roles