2019-03-12
Well, I'm not unemployed anymore. I did get a few interesting things done over funemployment:
- I worked through a bunch of electronics stuff.
- I (re)discovered my Feathers and got some more.
- Wrote an AVR I2C implementation and had to debug it with an oscilloscope.
- Wrote a lot of feather code and finally put it into a library.
- Started working on a LoRa mesh.
- Gave micro/circuitpython a fair shake.
And I have more stuff going on:
- Working on a LoRa gateway to extend networks of small sensors - there are solutions for this, but this is a forcing function for making me think and learn about network design.
- Working on an OTA update system for micropython.
After working on a largish feather project (my computational beauty of nature playground, I decided to turn the HAL into a standalone library, the featherlib.
In the CBN project, I had the HAL implemented as static instances hidden in the header file, roughly along the lines of this:
// lib/hal/graphics.cc
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoPixel.h>
#include <math.h>
#include <string.h>
#include <hal/graphics.h>
#include <hal/power.h>
namespace hal {
// ...
namespace OLED {
// The Adafruit SSD1306 in use is the FeatherWing version.
// https://www.adafruit.com/product/2900
Adafruit_SSD1306 oled(128, 32, &Wire);
void
setup()
{
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(1);
oled.setTextColor(WHITE); // Draw white text
oled.clearDisplay();
}
// ...
}
}
In featherlib, I went with a class-based approach; the above implementation would look more like
// include/feather/wing/oled.h
// ...
class OLED : public FeatherWing {
public:
// ...
bool setup();
// ...
private:
// ...
Adafruit_SSD1306 oled;
// ...
};
with an implementation similar to the above:
// src/wing_oled.cc
#include <Arduino.h>
#include <feather/wing/oled.h>
#include <feather/wing/wing.h>
bool
OLED::setup()
{
if (!this->oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
return false;
}
this->oled.setTextSize(1);
this->oled.setTextColor(WHITE); // Draw white text
this->oled.clearDisplay();
return true;
}
// ...
There's advantages and disadvantages to both of these, but I've
noticed the effect that it has on my code: with the class-based
system, all of the peripheral interaction happens in main.cc - where
the peripherals are declared as global objects. I suppose I could do
something like extern GPS gps elsewhere, but I do kind of like
having the top-level code all together in one file. This works
building small motes or control systems, but CBN would suffer -
especially considering each of the "experiments" has a need to access
the graphics directly or something similar. The jury's still out, and
I don't have a ton of experience with
PlatformIO so we'll see if it pans out.
There's more I could write about the OTA idea, but I'll save that for tomorrow.