Previous posts | Description |
---|---|
BIBoP 1 - Introduction, game plan and rationale | Introduction to the project and overview, creators bios |
Next posts | Description |
---|---|
BIBoP 3 - Blood Pressure Inference - Machine Learning | The process of creating a Machine Learning model for Blood Pressure estimation, data cleaning and training the model |
BIBoP 4 - AWS Lambda deployment and MQTT communication | Deploying the trained model on the AWS Lambda and sending secure requests from the Arduino |
BIBoP 5 - Power efficency and interrupts | Implementing SAMD21 deepsleep mode and external interrupt handling |
Assembly and debugging | Assembly, 3D designing and debugging of the project |
Galvanometer creation | Process of creating my own galvanometer |
Sensor processing algorithms | Overview of various medical algorithms for detecting abnormalities in the cardiovascular activities |
Introduction
Hello! In case this is your first time with BIBoP it is a smart armband designed for remote patient monitoring and overall health assessment. It is based on Arduino Nano 33 IoT and some external sensors (PPG, Galvanometer and IMU).
Be sure to regularly check the official repository of this project!
Why use Makefiles, when we have Arduino IDE?
We have Arduino IDE, right. But apart from providing users with handy building scripts and libraries + toolchains management, it failed to meet the IDE standards in terms of code editing. Since we (Jakub and Szymon) are heavy vim users, we wanted to write our code in a familiar environment and with handy shortcuts and handy tools.
This is just one reason behind it, the other being code extensibility, compiler choice and language version freedom. Assuming you want to have your own libraries as a part of a bigger project, Arduino IDE does not present you with an easy way to do it - with a custom Makefile you can structure your project as desired. This unfortunately is by no means out of the box solution, but I was able to polish some rough edges and possibly make it easier to fall in step for whoever reads this post.
BTW: There is Arduino 2.0 IDE which is based off VS Code and looks quite promising (apart from the VS Debugger which I despise).
Let's start
Assuming you have read this far and are willing to create your own Makefile-based Arduino project, you need to create the folder structure or simply fork/clone this project. You have a bunch of unnecessary files to delete, such as exemplary Makefiles and mock libraries. Instead what you need to do is follow the INSTALL.md which guides you by hand mostly.
Once you have the Makefile in the project directory (src/ProjectName/Makefile), you have to fill it with some necessary variables which are used during the process of building the binary and during the flashing and debugging the code. Exemplary Makefile can be found below:
As you can see, not much is needed to make all of this work (most of the variables are pre-filled and just have to be tweaked by you - hopefully you won't need to know the Makefile content by heart like I did while repairing it ). Remember to point the USER_LIB_PATH to the ProjectRoot/lib path and to symlink/copy the libraries you plan to use to this directory.
The GitHub repository README mentions that you have to set the BOARD_TAG and BOARD_SUB if you have boards which have these two parameters, but for the Arduino Nano 33 IoT we just need to set the BOARD_TAG to nano_33_iot
Lastly, because the original Makefiles are for the regular AVR Arduinos, you need to change the last line which includes the main Makefile from include $(ARDMK_DIR)/Arduino.mk to include $(ARDMK_DIR)/Sam.mk
If you are wondering where the heck are the toolchains and how to get them - you can install them easily via the Arduino IDE (and that is what I recommend) or download them by hand and tweak the Makefile more...
Polishing the rough edges
If you tried compiling right now, you would be met by some errors about missing LTO plugins during running the binary linking step. The reason for this was fixed upstream but is not ported to the Makefile you have in the project, so I suggest changing the git submodule to the upstream. You can do it with following commands:
git submodule deinit Arduino-Makefile git rm Arduino-Makefile # now add the gitmodule git submodule add https://github.com/sudar/Arduino-Makefile Arduino-Makefile git submodule update --init --recursive
The --recursive flag was needed in case the submodule includes other submodules.
Having the upstream Makefile, we have some problems fixed. Unfortunately this does not fix the libraries you create by yourself so I just add the LTO plugin by myself by adding the following line to the Arduino.mk:
# SPECIAL WORKAROUND FOR LIBRARIES LTO_PLUGIN_DIR = $(HOME)/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/lib/gcc/arm-none-eabi/7.2.1/liblto_plugin.so
Now we should be able to add our files to the lib directory and compile successfully. So let's try that now!
Since this post is related to Arduino Nano 33 IoT I will make small detour on building the binary with the WiFiNINA library.
Here I spent a good day debugging what the problem might be - I got a bunch of errors related to violation of ODR (one definition rule) and one to a private method being inaccessible - I fixed it by removing the offending file and making the method public (don't judge me please ).
If you are interested in more details I opened an issue on the WiFiNINA library's GH.
Building and Flashing
In order to compile the program you simply run make in the ProjectName/src/AnotherName directory and wait for the magic to happen. If everything went fine it should have built the binary and left the build artifacts in the build folder (check which one this is!).
In order to flash the binary on the target just run make upload and be sure to put the proper port in the MONITOR_PORT variable. It is quite picky about the port being used so be sure to close all other serial connections on this port even if they are already dead.
You can also monitor and debug the code using a serial connection and GDB. You know the magic spells by now!
The monitor command will simply output your Serial messages (or other printing method you have set on the target) using the screen program so be sure to install it!
The debug command will run GDB (if you don't know how it works, be sure to learn some basics and refer to this cheatsheet).
UPDATE: The Arduino Nano 33 IoT exposes SWD debug pads, but does not provide a built-in debugger - you need to provide it on your own (like this one)
How cool is debugging Arduino projects without relying on print statements, eh?
Not without an external debugger
Bonus: Code completion dances (vim users unite)
In order to have a pleasant developing experience I had to wiggle around with the vim completion services and language servers. I decided to choose coc-nvim because it allows for many modern-IDE features, such as code snippets, refactoring and just pleasant flow. The language server backend is ccls and it requires the .ccls file to be present under root of your project (or in the root of every library you develop). I had to do some hacking around in order to get the completion I desire but it works quite well. If you are lazy you can of course use VS Code and forget about this paragraph .
I place a .ccls file in the root of my project with following structure:
You can see that I need to include the libraries in order to have code completion. Also you have to include all headers you are using into the root file (main.ino/c/cpp) in order to bring them into the completion scope... This is quite annoying but I could not circumvent it yet.
There are tools which generate these flags for you analyzing your CMake file (Bear) or even Makefiles, but having tried some of them I could not get any good flags generated and decided to copy the gcc/g++ invocation and just tweak the flags by hand - a minor hindrance.
Let me know if you have a different take on this!
Summary
We hope that this article proved to be informative and will help you in your endeavours with Makefiles when using powerful Arduino SAMD boards. It is a shame that users wanting to do things in non-standard way have to often wander in such darkness...
Next time we will go through the process of creating and training a Machine Learning model for Blood Pressure inference! Stay tuned.
Jakub & Szymon & Michał
Next post |
---|
BIBoP 3 - Blood Pressure Inference - Machine Learning |
Top Comments