This week we had to create an app that interfaces with our microcontroller. As controlling the microcontroller from other devices when it is working is really important, it is good to learn this skill.
I very much love the idea of cross-platform programs, so that you don't need to learn different languages and frameworks and write multiple apps but just learn one framework and export your app everywhere, be it desktop or mobile os. For this reason I decided to work with Qt. I had already worked with qt a few years back, so I thought it will be straightforward.
Qt also has modules for any cause, which are also cross-platform, which is just amazing. For this assignment the Qt bluetooth module is needed. If you are interested in what is possible, you can have a look at the qt showroom. There are also a lot of examples for very different use cases, so that you can find something similar. The nice thing is that examples are also tutorials, so there is a small documentation on what is done how for every example. A lot of popular software is also developed using qt. Which brings me to the next point:
Qt is that is a huge library, so you can easily lose the overview. There are a lot of modules for all different applications and even platform-specific modules. In qt you usually program everything using C++, but they also have another very easy script-like programming language to speed up the development of user interfaces: Qt quick / QML. With that you can easily define interfaces and interactions on them, it works really great and is quite fast to write. Compared to traditional programming it's a huge improvement. You can also connect C++ with the QML interface, so you can still program the logic or whatever in C++. But as powerful as everything is it is also some work required to get used to it.
First comes, of course, installing the IDE, which is straightforward. Qt also has a lot of examples available, so I did first look at the bluetooth examples and tried to figure out if one of them is similar to what I want to get. Basically I want to search for bluetooth devices, connect to one and send serial data to it. But none of the examples would send data over this (RFcomm) connection, so I searched some more and found this example online, where somebody else interfaced the hc-05 with qt.
With qt your project has a .pro file, which defines which files your project consists of and which modules. It is basically the makefile. Then you can have cpp files, header files, qml files or ui files.
I wanted to create a qml app and that is where the problems started. The example linked above is a C++ example, so I couldn't use it. I wanted to use qml because of the ease to create a nice ui. For qml there is also a specific bluetooth library available. But even after I studied the documentation and two examples I couldn't work out how to do it. I understand a lot and implemented the program, but something didn't work. My main problem was that the qml bluetooth class is very sparse documented and even the examples use functions that are not even listed in the documentation and doesn't exist in the C++ bluetooth class. I got to a point where the app could search for devices and list them and tried to connect by clicking on them. But somehow the connection never worked and I don't know what the problem was.
At this point I gave up on the qml app, even as a next step I could have connected the C++ Bluetooth class to the qml app, but this would also have been some work.
Here I based my work on the previously mentioned example. I loaded the example in the qt creator, which is the IDE from qt to develop their applications. You can see the interface below.
A nice feature it has is a designer, where you can design the ui interactively, which is much better than doing that in program code. But as I tried to adjust this app I found out that with C++ ui the designer is very limited. Years back when I worked with QML in it I remember that the designer worked well, but now in C++ I was not even able to change the button color to what I wanted, without defining completely new classes. So everything is now greenish and this are just the basic style PushButtons that are available in the qt framework.
The bluetooth connection in qt is set up using the following code. The agent is used to search for bluetooth devices and the socket is used to connect to the device that is chosen.
QBluetoothDeviceDiscoveryAgent *agent = new QBluetoothDeviceDiscoveryAgent; agent->start(); QBluetoothSocket * socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
To connect to the device you need the uuid of the service, which you can find online for the hc-05 module and the device adress:
static const QString serviceUuid(QStringLiteral("00001101-0000-1000-8000-00805F9B34FB")); socket->connectToService(QBluetoothAddress(string), QBluetoothUuid(serviceUuid), QIODevice::ReadWrite);
Sending data to the bluetooth module is then very easy:
That was basically all the logic in the cpp program and the rest is just the ui file, which was refined in the designer.
As the big advantage of qt is the ability to deploy software to multiple platforms I wanted to compile the program to run as an app on my smartphone. After installing everything I soon realized that it wouldn't be so easy. First it took some time to figure out which paths qt wanted to know and how to install the platform tools and usb driver. You can install the platform tools in android studio and the sdk path qt wants to know is
C:\Users\"User"\AppData\Local\Android\Sdk under windows in standard settings. Another point that is good to know is that the ndk can be installed from within the android studio, but for me this caused problems as stated here. Ndk version 20 is not compatible, so I installed 19c instead. Also when installing the jdk make sure that you install version 8, otherwise something else won't work. At some point I also needed to restart the qt creator to get rid of cryptic errors. The furthest I got without errors was that I could already choose the device on which my app should be installed to test.
The error I finally gave up on was this one. It seemed that it was again something that had to do with incompatible software versions of the qt creator, android studio, the ndk and jdk. This was not the first problem because of incompatible versions and I decided that I didn't want to put in more hours to get it working.
For the next time with qt that I try to compile an android app I will definitely search before the installation what version numbers have proven to be compatible and install those, because error hunting is annoying. Another possibility could be to search for a docker container for compilation, which would even take away the pain of searching compatible versions, and this looks quite promising. As I have a working program and won't use qt in the near future I am not motivated enough to get it working. Actually I am quite disappointed that everything worked so bad and I had to spend hours on searching for missing documentation or searching problems to just run an easy example for android, but I guess that is normal with such huge software frameworks.
I used the same setup from the communication week, but now I didn't use a serial terminal but my own app to communicate to the bluetooth module. In the demo you can see how I connect to the bluetooth module and then change the color of the LED strip. I hope you can see it, because I needed to make the image really dark so you can just see the color on the LED strip change.