How should I manage different application "modes" (reader, writer, etc)?

Hi everyone,

I’m working on a project using RF24 that’ll run on two different boards (a reader and a writer). There’s some shared logic between them (configuring the radio, encoding/decoding payloads, etc). How can I structure my codebase to use these shared resources, easily be able to specify which version of main() I want to compile, and not upload unnecessary code (i.e. avoid bundling both the reader main and the writer main and branching at runtime)?

Right now, my solution for this is putting the entrypoints in a folder and using build_src_filter to ignore all modes but one:

build_src_filter =
  +<*>
  -<modes/*.cpp>
  +<modes/writer.cpp>

Is there a more standard solution for these sorts of things, e.g. if someone wants to run my project?

You can define two environments and specify build_src_filter for each env. When compiling, just select different environment.

Assume your src directory is like:

src
├── common
│   └── common.cpp
├── reader
│   └── reader.cpp
└── writer
    └── writer.cpp

This can be added to platformio.ini:

[env]
framework = arduino
; ... common settings

[env:reader]
build_src_filter =
  +<common>
  +<reader>

[env:writer]
build_src_filter =
  +<common>
  +<writer>

This can be simplified as:

[env]
framework = arduino
build_src_filter =
  +<common>
  +<${PIOENV}>

[env:reader]
; ...
[env:writer]
; ...

Alternatively, you can do this:

[env:reader]
build_flags =
  -DSOURCE_READER

[env:writer]
build_flags =
  -DSOURCE_WRITER

…and add some #ifdef guard to respective sources and do something like

#ifdef SOURCE_READER
// code goes here
#endif

This is less elegant though.

Oh cool, I did not know about the ${PIOENV} interpolation. This is nice, thanks!