C++
Heltec WifiKit 8
Ordered myself two Wifikit8 Esp8266-based boards from Aliexpress.
Received them after roundabout two weeks and now the fun can start.
With the integrated 0.91″ display (128×32 Pixel) a lot of effort for integrating some display or LEDs can be saved. Just noticed that a LiPo-charger is built-in as well, wow. For 4,50 € not a bad choice. But I am not 100% sure if this is the real device or some copycat – nevertheless: in the end the functionality matters.
First project-idea is to create an extended and verifyable version of the random-reviewer. With display of the currently chosen person, a big buzzer-button as trigger and a web-interface for those who doubt the true randomness ..
good guides:
- https://robotzero.one/heltec-wifi-kit-8/ – hints for the board itself
- https://www.bastelgarage.ch/heltec-wifi-kit8-board-esp8266-32mbit – hints for the board itself
- https://github.com/olikraus/u8g2/wiki/u8x8reference#drawstring – library for drawing text; works well
Qt: clean includes
(I’ve decided to follow a more agile workflow: instead of creation a “one post covers the whole topic”-post, to post also updates for each step. Article will be therefore edited while “doing”)
Last week I’ve cleaned Qt-includes for a larger project. Like #include
to #include
how it should be. With proper indirection, so that the Qt-library handles how and where the class is implemented.
A colleauge raised the question, why not use #include
to be even more precise and to see the used module directly (needed for the CMakeLists or qmake).
First step: identify all used Qt-includes
1 2 3 4 5 6 |
$ git grep "include <Q" | cut -d : -f 2 | sort -u # include <QApplication> # include <QAtomicInt> # include <QDebug> # include <QFileDialog> # include <QHBoxLayout> |
Greps all includes starting with an uppercase Q; then split the result at the “:”; then sort und make it unique
Second step: create a replacement-list and a (python?) script which does this for all .h/.cpp-files
tdb
C++: proper init for double/float and the proper check
Problem was that I initialized some doubles with 0.0 and then hoped that the imported values are assigned, which does not happen always. So a check was needed. But checking if(0.0 == x)
is a really bad idea. MinGW will tell you too (as other compilers).
So I was searching for a proper way to check against 0.0. And then I found a better idea: initialize with NaN and use the standard-check against this. Much better!
1 2 3 4 5 6 7 8 9 10 |
#include <limits> .. // init them with NaN to prevent later issues double x{std::numeric_limits<double>::quiet_NaN()}; .. if(isnan(x)) { qDebug() << "uninitialized"; // todom remove return false; } |
(addendum: I know, a variant would be the best to fix the given task.)
Advanced debugging: find call which triggers Qt-errors
Currently the debugging version of the Qt-libraries is not available. But I receive a report "QIODevice::write (QIODevice): Called with maxSize < 0"
deep within them.
Our codebase is quite large, I am more familiar with other sections and let's say it: some is 'legacy'. So, where to start looking?!?
Yesterday I remembered a trick to get via call-stack to the last-recent position where our functions trigger that mistake.
Inserted in the main.cpp after show from the MainWindow was called a
1 |
qInstallMessageHandler(messageHandler); |
which stands for this
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg ) { Q_UNUSED(context); switch( type ) { case QtDebugMsg: qDebug() << msg.toLatin1().data(); break; case QtWarningMsg: qDebug() << msg.toLatin1().data(); break; case QtInfoMsg: qDebug() << msg.toLatin1().data(); break; case QtCriticalMsg: qDebug() << msg.toLatin1().data(); break; case QtFatalMsg: qDebug() << msg.toLatin1().data(); break; default: qDebug() << msg.toLatin1().data(); break; } } |
Add a breakpoint in the messageHandler and debug the app. Maybe disable the breakpoint until you start to trigger the critical functionality.
When it breaks, you have a nice callstack and can backtrace where it came from :)
ESP32: integrated the YL-69 for moisture-metering, also fried my first BME280
Acquired a Bosch BME280 for improved humidity, air pressure and temperature-measurement (DHT22 can’t read barometric pressure) and tried to attach it via I2C.
Let’s keep it short: the sensor got very hot after several tries to find the correct wiring. Even using the i2c-scanner testprogram did not yield any results. But I learned how to use the breadboard more effectively. The burnt IC will be sold as ‘Lehrgeld’ 😉 (Oh, the days when I fried my AMD Duron, because I thought that a CPU won’t heat up so fast at boot. Boy was I wrong.)
Integrated then at least via analog reading the YL-69 moisture sensor. Worked well and on first try. Guess I just need to read much, much .. more about I2C, wiring and the sensors.
Another lesson learned: if you want to see really badly structured, basic coding: check tutorials for microcontrollers :/ (especially mine ;))
———
Code is committed and pushed to github.
Output is something like:
1 2 3 |
Humidity (DHT22): 72.90 % Temperature (DHT22): 24.10 °C Temperature (internal): 31.11 °C Moisture (YL-69): 27% |
ESP32 and DHT22: temperature and humdity
To give my (non-existant) skills for microcontrollers and reading out sensor-values a kick-start, I decided to connect today an DHT11 to the ESP32.
So, at first I realized I have no clue how a breadboard works, then that I need a calculator to determine the resistors properly, then “how to determine the correct pin-numbering”, then … it did not work, no matter what I tried. The C++-code was the least issue. Several sources provide examples, also with webserver (looks like everyone ~stole~ got inspired from each other ..), but the read-out always failed.
Luckily I had two (a bit more ‘expensive) DHT22 at hand and it worked like a charm!
Lessons learned: 0. accept that you know nothing 1. reading and experimenting is fun 2. seeing finally a presentable result is great <3
Result:
* code
* output:
1 2 |
Humidity: 71.20 % Temperature: 24.40 °C Temperature (internal): 31.67 C |
advanced whitespace-correction
(for CMake/C++-projects)
Find all fitting files and run the fixer-script in parallel over it.
1 |
( find . -name "CMakeLists.txt" ; find . -name "*.cmake" ; find . -name "*.h" ; find . -name "*.cpp" ) | parallel --bar ../removeTrailing.sh |
After playing for a while with sed and awk and not being able to get a fitting solution, I decided to create my own as python-script. It squashes all consecutive double-whitespace-lines (and adds one to the end if missing).
Or “run it on the files changed for the last commit”:
1 |
$ git diff --name-only HEAD~1 HEAD | parallel --bar ../removeTrailing.sh |
Sources:
removeTrainling.sh
squashMultipleWhitespace.py
How to get GNU parallel (developed by Ole Tange):
1 |
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash |
Updating to the current package of Qt Charts (from the commercial version)
Qt (or Digia? or how was the company-owning-Qt called at that time?) released in 2014 the version 1.4 of their Charts add-on for Qt. It was available only for the commercial-license and had some distinc namespace-requirements. And was also quite bare-metal.
Further development lead to more opportunities regarding the emitted signals for the cursor-handling (pressed/released instead of just clicked, for instance) and it became part of the regular package for Qt.
## Advice for a CMake-based project ##
If you want to maintain and upgrade your legacy code, then:
- add “Charts” to your find_package:
1find_package(Qt5 COMPONENTS Widgets Charts REQUIRED) - change the namespace inside the CMakeLists from “former naming” to “Qt5::Charts”
- remove the dependency to the old package in the top-level CMakeLists.txt
- replace inside the h/cpp all occurences of “QtCommercialChart::” with “QtCharts::”
- replace inside the h/cpp all occurences of “QTCOMMERCIALCHART_USE_NAMESPACE” with “using namespace QtCharts;”
- update the installer-creator-script(s) to include the Qt5Charts.dll
Et voilà , it should build now.
Retrospective view at 2018
The first month of 2019 already passed. And we passed it with flying colors!
But let’s have a look at 2018 – a year full of challenges and success: I’ve worked full-time, organized and participated in advanced courses for Python and in Requirements Engineering (officially: IREB Requirements Engineering Foundation Level-approved) and pursued a new employment as software engineer.
And I wrote some software in my spare-time, as you can see in the graph for the public github-repositories. The gaps in the commits can be explained with the birth of my daughter and the time where I acquired the new job and moved nearly 900 km across the country. Yay! Nice personal projects were and are Cullendula and the Daily Coding Challenges, which I solve mostly with fully Unit-tested Python (3).
More new, hands-on knowledge was gained in the area of CMake and Qt-charts.
Well – 2018 was great. Let me make 2019 greater! 💪
Fixing ~crappy~ no-good Qt-includes
How to locate all includes of that style:
1 |
#include <QtWidgets/qcombobox.h> |
with proper
1 |
#include <QtWidgets/QComboBox> |
Fired up https://regex101.com/ and set it to PHP and created an expression, which matches:
starting with slash, then a q, then characters, then . then h
1 |
\/[qQ][a-zA-Z]+\.h |
(Replace & check has to be done by YOU ;))