Making an Android app for LEGO Powered Up – explanation

So how does this “App Inventor”-thing work?

To create an app for Android we just need a browser to access the online app creator tool. We have a Design view where we add our components like buttons and sliders and a Blocks view where we use the method blocks provided  by each component we added to our Design.

We can build our app and download an ‘apk’ file to install on our Android phone or tablet but that’s not practical while we are still testing some ideas and debugging the way our blocks work. So the best way is installing the MIT AI2 Companion App on our Android device so every action we make in the online tool is synchronized to it through USB or wi-fi.

App Inventor 2 provides a Palette with lots of usefull components but to use LEGO Powered Up we need to add an Extension that allows AI2 to talk with Bluetooth Low Energy devices. At the moment BluetoothLE is the only supported extension and I must say they have been doing a great work this last year (they even gave me access to a beta version a few months ago while fixing a bug I was dealing with) including writing a good explanation of all the blocks provided with some examples for Arduino and BBC micro:bit.

After importing the extension  we just drag it to the Viewer to get a ‘BluetoothLE1′ component at the bottom of the Viewer, on the “Non-visible components” area. Doesn’t seem much but if we change to Blocks view and look to this component we’ll see lots of blocks.

So let’s start creating our App!

We will use some BluetoothLE blocks to communicate with our LEGO “HUB NO.4” device. This blocks require a ServiceUUID and a CharUUID that we will store in global variables:

Currently the ServiceUUID and CharUUID are the same as LEGO BOOST hub but please note that there is no guarantee that future firmware releases will keep them allways equal.

We will also create a list of our devices:

Yes, a list of one device is silly but I have more devices like my BOOST Vernie and of course I’m planning to have a few more Powered Up devices in a near future so a list is usefull. You can call whatever you want to your devices but you need the Bluetooth address of it (so “PUP#1” is just an easy to remember tag that I choose for my “90:84:2B:06:AB:5D” hub).

You can get your BT address installing Nordic nRF Connect for Mobile app on your Android device and scanning nearby BLE devices while turning your LEGO hub on. If you changed its name with the LEGO App you will see a BLE device with that name, if not you will see “HUB NO.4” or “Smart Hub”, depending on the firmware version of your hub:

Now we go to Design View and add all components needed:

From the ‘User Interface’ section:

  • two buttons: ‘BtnConnection’ and ‘BtnRst’
  • one ListPicker

From the ‘Drawing and Animation’ section:

  • one Canvas
  • one ImgSprite

And from the ‘Sensors’ section:

  • one Clock

I added a few others that are really not needed, just used them for aligning and cosmetic purposes.  I also renamed the buttons names to better remember their purpose and changed some of their properties.

Now back to our Blocks view, we need to take care of what happens when our App starts:

We start a Bluetooth LE scan to find all BLE devices nearby. This is necessary later on when we want to connect to our LEGO device.

Then we create our list of Hubs (seen above), set the text of the Button used for the BLE connection, draw our Joystick at the center of the canvas and initialize our Clock.

This Clock will be used to keep the BLE connection active after we connect: we need to keep talking with the LEGO hub because after a pre-defined period without communication it will shutdown to prevent battery draining.

For now we just keep the clock disabled and set the period  to match the global variable “TRACKSPERIOD”.

We also define what happens when we click our ListPicker:

(we change the text to the friendly name of the chosen LEGO hub)

Now we define what happens when we click on our connection Button – we want it to connect to the device we chose whenever there is no connection yet and to disconnect when already is:

(we also activate or deactivate our Clock at the sametime)

I will not explain the blocks related to the Joystick – they are used to calculate the duty cycle (speed) of the two motors from the position of the joystick. These values are store in two global variables: ‘SpeedA’ and ‘SpeedB’.

The next important part is sending the calculated values to the motors.

The hexadecimal command used to control a WeDo 2 Motor (we should probably call it a “Powered Up Medium Motor) is:

0800810 p 115100 dt


  • ‘p’ is ‘0’ if we are using ‘Port A’ and ‘1’ if using ‘Port B’
  • dt is the hexadecimal representation of the duty cycle (a percentage value)

The AI2 BuetoothLE extension uses a list of decimal values so

8 0 129 0/1 17 81 0 dt

Lucky for us the extension also accepts signed or unsigned values so we don’t need to take care of the conversion when duty cycle is negative:

so every time the Clock reaches our “TRACKSPERIOD” value it sends the commands for the two motors. Setting a smaller period allows a better control but also increases the activity of the App so for too small periods it might not work properly. And, of course, setting a larger period will increase the latency of our control and might also cause our connection to drop.

Hope this explanation is clear enough for anyone that wants to try their own app. Feel free to make questions on my YouTube channel, I’ll try to answer the best I can.