Code organization of a larger project

Hi all, I am not entirely sure how to structure a larger project with platformio. I am going to start a larger project that includes several sensor nodes and a few actuators. All communicate using the same libraries (both 3rd party and my own additions on top). They therefore share code. I could put the code for each device in its own platformio project, and put the shared libraries each into a separate project too. But assuming each platformio project would be in a separate git repository, that might increase the numbers of repositories quickly. Is this the structure people generally use in their PlatformIO projects? Or do you put all projects in the same repos? But in that case, how does one project refer to a library located in another project in the same git repository? Or is it even possible to have the code for multiple devices in the same project? I wouldn’t know how that would work with uploading, and multiple c++ files that define loop and setup functions.

The cursory read I had through the docs didn’t really seem to cover this. There are many specific “how do I do x, y or z” but I couldn’t find a higher level structure explanation. Did I miss some docs? Or should I contribute some (after some discussion here)?
Cheers,

Dolf.

I’ll only target one or two bits of your question…

… one way around this could be git submodules. Allows you to have your shared libraries in their own git repositories with their own commit histories, etc, but still share them across projects. You also get the benefit of … nested versioning I suppose? Where if one project still uses an older version of the shared library, that’s fine, just don’t update the submodule.

Yes, it’s definitely possible, via pre-processor macros. You can have conditional code that only works when compiling for one environment or another, or for one board type or another. i.e. below code snippet from part of the setup() of some code I had testing a AXDL345 accelerometer caters for either the Arduino Uno or a specific ESP8266 boad I was using… allowing the one code base to do things differently for different boards. I was only targeting the Oak and the Uno, but if there were more combinations, I could have used multiple #if defined blocks.

void setup()
{
#ifdef ARDUINO_ESP8266_OAK
  Particle.variable("x_val", x);
  Particle.variable("y_val", y);
  Particle.variable("z_val", z);

  if (Particle.connected() == false) {
    Particle.connect();
  }

  Particle.publish("adxl345_test sketch starting");
#endif

  // join i2c bus (address optional for master)
  // Oak/ESP8266 needs SDA & SCL pins defined, Arduino Uno doesn't
#ifdef ARDUINO_ESP8266_OAK
  Wire.begin(0, 2);
#else 
  Wire.begin();
#endif

Or, for the same platform/board/architecture, but different environments…

platformio.ini
--------------

[env:Sensor 1]
build_flags = -D TX_PIPE=1 -D RX_PIPE=0

[env:Sensor 2]
build_flags = -D TX_PIPE=2 -D RX_PIPE=0

[env:Sensor 3]
build_flags = -D TX_PIPE=3 -D RX_PIPE=0
  main.cpp
  --------

  // Open a writing and reading pipe on each radio, with opposite addresses
  radio.openWritingPipe(pipes[TX_PIPE]); // write to configured pipe

  DebugPrint(F("Transmitting on pipe ["));
  DebugPrint(TX_PIPE);
  DebugPrint(F("] which is ["));
  DebugPrint((long)pipes[TX_PIPE]);
  DebugPrintln("]");

Food for thought :wink:

1 Like

Thanks for the awesome answer. Both options make sense indeed. So the main question is: do I want to version the code for the different devices separately? I could have everything in one repos and project and define a different env for each device, with a separate -D flag. Each device’s code is in lib/<sensorname>/ with its own loop and setup functions. In src/ there is only a main.cpp with

#ifdef SENSOR1
#include "lib/Sensor1/Sensor1.h"
#elseif SENSOR2
#include "lib/Sensor2/Sensor2.h"
#endif

Or if I want to version them separately, I go for the submodules approach, where the shared libraries are just submodules in lib/ and each device has it’s separate src/

1 Like

There’s quite a few permutations and variations you can use, but to my mind that’s what it boils down to. I’d also be interested to see what others think/alternative workflows. :slight_smile:

Yeah, more ideas, or feedback on the current ones is definitely welcome.

1 Like