Introduction ============ featherlib is a set of tools for quickly building programs on the Adafruit Feather ecosystem without sacrificing readability and modularity. It's the same sort of hardware abstraction layer (or HAL) that I find myself either copying over or reimplementing in new projects, so I decided to package it up as a PlatformIO library. One of the examples that I use regularly is the program for setting the RTC in an Adalogger using the time from an Ultimate GPS wing:: // rtcgps is a small sketch that sets an Adalogger's RTC to the // current GPS time. It uses a Feather M0, the Ultimate GPS // Featherwing, and the Adalogger Featherwing. #include #include #include #include #include #include #if defined(FEATHER_M0) FeatherM0 board(INPUT, A1); #elif defined(FEATHER_M4) FeatherM4 board; #else #error Unknown board. #endif // The default GPS constructor uses Serial1 for the // connection. GPS gps; // NB: setting the Adalogger's CS pin to 0 disables the SD card, // which isn't used in the sketch and therefore doesn't require an // SD card to be inserted. Adalogger logger(0); void setup() { // Start the serial port at 9600 baud but don't wait for a // serial connection to continue booting. board.setup(9600, false); // Registering wings allows them to be set up in one pass and // allows any update tasks to be started later on. registerWing(&gps); registerWing(&logger); if (!initialiseWings()) { // If a wing fails to initialise, a message will be // printed to serial. while (true) ; } // This starts a background thread that runs the update tasks // for the featherwings. For example, in this sketch, the GPS // needs to be updated in the background. Another scheduler // can be used that calls `runWings`, too. scheduleWingTasks(); } void loop() { // rtcSet will be set to true when the GPS is used to set the // RTC. static bool rtcSet = false; DateTime dateTime; // when rtcSet is true, the program will stop. while (rtcSet) ; if (!gps.getDateTime(dateTime)) { return; } if (!logger.adjustRTC(dateTime)) { Serial.println("Failed to adjust the RTC."); return; } rtcSet = true; Serial.println("RTC is set; halting."); } I find this is relatively easy to read; organising the functionality under a wing is debatable (and arguably makes this not a true HAL) but it seems to be working out well for the projects I've been using it in. Overhead -------- As a test, I've compiled a basic Arduino sketch for the Feather M0:: #include void setup() { Serial.begin(9600); while (!Serial) ; Serial.println("boot OK"); } void loop() { } Building this with PlatformIO shows the following sizes:: Building .pioenvs/adafruit_feather_m0/firmware.bin Memory Usage -> http://bit.ly/pio-memory-usage DATA: [= ] 8.0% (used 2620 bytes from 32768 bytes) PROGRAM: [ ] 4.2% (used 10992 bytes from 262144 bytes) and the equivalent using the featherlib library:: #include #include FeatherM0 board; void setup() { board.setup(9600, true); Serial.println("BOOT OK"); } void loop() { } yields the following sizes:: Building .pioenvs/adafruit_feather_m0/firmware.bin Memory Usage -> http://bit.ly/pio-memory-usage DATA: [= ] 8.1% (used 2648 bytes from 32768 bytes) PROGRAM: [= ] 5.2% (used 13568 bytes from 262144 bytes) The additional program space is taken up by the random number seeding. It's worse in this case because a fair amount of additional setup is done, but once more peripherals are added, the tradeoff is generally useful to me. As additional examples for the Feather M0: +-----------+----------------+------------------+---------------------------------+ | Example | Data (bytes) | Program (bytes) | Components (plus Feather) | +===========+================+==================+=================================+ | calamity | 3496 (10.7%) | 24784 (9.5%) | OLED | +-----------+----------------+------------------+---------------------------------+ | rtcgps | 4844 (14.8%) | 48576 (18.5%) | Adalogger, GPS | +-----------+----------------+------------------+---------------------------------+ | loraspy | 5216 (15.9%) | 48336 (18.4%) | Adalogger, OLED, RFM95, Trigger | +-----------+----------------+------------------+---------------------------------+ | lorabcn | 3832 (11.7%) | 35136 (13.8%) | RFM95, Trigger | +-----------+----------------+------------------+---------------------------------+