PlatformIO part 2

I hope you guys enjoyed my first posting about the PlatformIO IDE. Given the complexity of the product, I thought I’d better split stuff up and give some insights on the more advanced features. In this post I’d like to give some clues away about the usage of the integrated Terminal. This is, on any given platform, a very nice thing to know about.

If you open up a project or create a new one, you can add Terminals to the user interface. I’m gonna show you some things using the “platformio” command, which is the basic thing to know about.

Via the PlatformIO menu you can add more terminals to your screen:

It will add a terminal to your editing environment on the bottom part:

This terminal works like any old terminal would on the OS layer. This basically means that if you are on Windows (which is why I’m showing this on the Mac, haha) you can’t use tab-completion. There are a couple of buttons around the edges, as you might have noticed. They can take you full screen, change the coding table and so on, it’s all very self-explanatory.

Any of the actions you can do with pointing and clicking can also be achieved with this terminal. Sometimes it’s faster, sometimes it’s not. I’ve noticed a difference on Windows and Mac as far as shortcuts go, they tend to be better on the Mac. For example Command-Shift-B builds your project, but in Windows you have to find the menu entry and click it.

Anyway, all this boils down to the use of the command “platformio”. If given without any parameters it will display a list of possible options:

There are lots of options here to use and I’ll show you a couple. Let’s start with the “lib” command. This handles anything to do with the libraries. Again, if given without a parameter (e.g. platformio lib) it will display a list of possible options:

The library option/command can have different flags. For one, the -g is good to keep in mind. It shows you the global value of the command you give. So if you want to check which libraries are installed for global usage, you’d type in “platformio lib -g list”. This will list all globally stored libraries and where they are stored:


As you can see I have no global libraries because I’m using my “old” Arduino path with existing libraries. I’ve set it up that way so I always have access to my most important libraries. The reason I’m not using the PIO directory is that I have my libraries on my Google Drive.

Anyway, we could, if we want to, install a library from the repository into the global library path. But first, we need to find the library. “platformio lib search <libraryname>” can sort that for us! We are gonna install the VirtualWire library into the global storage location, so, we find it first:

So, now we know it exists in the repository (at this point I have no idea where this repository comes from, but I suspect it’s from the Arduino Library Manager). On Windows this screen will look a bit different by the way. You can see a short description here and the ID of the library. Each library has a unique ID (really strange, I know … ). It also lists the compatibility with the platforms and framework(s).

There are two ways to install the library. You can install it by name or by ID. This comes in handy when there are libraries which have similar names (try and search for “DHT” … ). “platformio lib -g install 251” will install the library in the global storage location, so all your projects can access it. If you omit the “-g” part it will install the library in a folder called “.piolibdeps” in the current project directory. Make a mental note of this, because with this terminal you can do the same as with a regular terminal. You can cd and so on.

In my example you see I’m working on a project called “ClockLamp_v5”. So, I will install the library in the global location:

You can see it downloaded the library and added it to the global storage location. I can now use it in any project I like.

You can see it doesn’t list the library when you omit the “-g” and vice versa:

It may be a bit confusing in the beginning, but it definitely has it’s merits.

So, how does all this interact? That’s the big question. In part 1 of my tutorials I’ve showed you how to use the an environment variable to point to the Arduino library (since I’m on two platforms, the libraries will always be in sync that way). For the purpose of this tutorial I’ve created several copies of the TFT library and changed the version numbers, so we can see what happens when we put a library in a certain storage location.

This part is, by the way, all done with a default platformio.ini, nothing fancy, just a description of the used board:

First off, I’ve created/copied the libraries to (and changed their version numbers):

  1. My Arduino library directory on Google Drive (1.0.5)
  2. The general storage location (<homedir>/.platformio/lib, 1.0.2)
  3. The deps directory of the project (project/.piolibdeps, 1.0.4)
  4. The lib directory of the project (project/lib,  1.0.3)
  5. Lastly, there is a built-in version (1.0.6, most recent) somewhere…

Because I have the environment variable that overrides all cases, at compile time I will see it uses the “1.0.5” version from my Google Drive:

You’ll notice it also gives a nice tree of dependencies from other libraries. So, let’s start messing about! I removed the environment variable from my system and now it compiles to the “1.0.3” version from the lib directory!

Ok, but suppose we removed it from the lib directory and still with a default platformio.ini? Ok, let’s see what happens:

Ok, now it compiles the library from the (hidden) .piolibdeps directory. We are getting somewhere… I remove that too and re-compile:

Going to the “1.0.2” version now, or as we know it, the global storage location (as per the PIO default). We remove that too now:

And the runner-up is the built-in loction for libraries (like we know from the Arduino environment). Awesome! Now we know in which order the library locations are processed and we also know that the PLATFORMIO_LIB_EXTRA_DIRS overrules them all. With this knowledge we can do very good tests to see how libraries interact with each other. This is somewhat of an advanced feature, but nonetheless a very important one.

Of course it depends a bit on what sort of developer you are. Do you want to be bleeding edge or just make some stable stuff? PIO gives you all those possibilities. I hope this little write-up makes it a bit more clear how the libraries interact and in the mean time I’ve shown you a couple of terminal commands too!

It’s way too much to handle everything here (and I’m only just a beginner too). The PIO library system is well developed and offers a wide range of library management possibilities. The one thing I’ve mentioned in the first tutorial (to access all your Arduino libraries with the environment variable) lead to somewhat of a discussion on Twitter with PIO. I like to keep it KISS, hence, that is why I used the lib_ldf_mode = deep and the environment variable. WIth those basic settings you can access the PIO projects from all of your machines. Wether it be Linux, macOs or Windows.

But as we’ve seen here there is much more too it to setup the PIO to yor prefered method of working. Well, enjoy and see you next time with something else (I’m not sure what yet, haha, so much to explore!).

For more information you can always visit the very good documentation pages at