Courier: real-time messaging for ESP32 with batteries included (new library)

5 min read Original article ↗

I hack on hardware a whole bunch, at Inanimate and at home.

AI is in the cloud. Interaction is in my room and in my hands. The job always begins by wiring together those two ends.

So the second thing I do, every single time, is bring up real-time messaging using JSON over websockets so I can connect my new device to a server, and have it emit events and listen for commands.

(The first thing I do is bring up the hardware and get basic blinkenlights.)

I want my on-device websockets client to have a super easy interface: give me an onMessage handler to deal with incoming messages.

I need built-in wi-fi config (so I can carry my prototype around to different places). And I don’t want to have to choose which libraries I’m going to use each time, I want good defaults.

That’s what Courier does, in just a handful of lines.

Honestly this isn’t rocket science. It’s no biggie. But it’s decisions I make and boilerplate I have to write for every new project, and I don’t want to vibe code and test this bit every time… I just want it to work. So I find Courier useful personally. And in the spirit of sharing, I hope it’s useful for you too.

Find the code and README here: Courier on GitHub

Quick start

Courier does a small and necessary job (messaging) in the most straightforward way possible.

Let’s say you’re using Arduino on ESP32. I’ll say more about ESP32 in a minute.

Add Courier to your project (we recommend managing your project with PlatformIO):

lib_deps = https://github.com/inanimate-tech/courier.git

Then here’s all the C++ code you need:

#include <Courier.h>

CourierConfig makeConfig() {
  CourierConfig cfg;
  cfg.host = "api.example.com";
  cfg.port = 443;
  cfg.path = "/ws";
  return cfg;
}

Courier courier(makeConfig());

void setup() {
  courier.onConnected([]() { courier.send(R"({"type":"hello"})"); });
  courier.onMessage([](const char* type, JsonDocument& doc) {
    Serial.printf("Got: %s\n", type);
  });
  courier.setup();
}

void loop() { courier.loop(); }

Now your server can send real-time messages in JSON to your device, and your device can handle them. (It pulls out the type automatically for easy routing.)

That’s it!

You don’t need to hardcode wi-fi details in your code. Courier bundles WiFiManager for portable connectivity: if a network can’t be found, this library pops up its own access point and open a captive portal.

Also you get for free: sane auto-healing of both the socket and wi-fi, NTP time sync so the internal clock doesn’t drift and break your secure connection (which happens after about 72 hours), and an easy upgrade path to MQTT.

Try Courier with an M5Stick

ESP32 is a family of microcontrollers that has a special place in the hardware ecosystem: thanks to its low cost, built-in wi-fi and Bluetooth, and ease of development,

  • it is the platform of choice for new hardware startups
  • and it is great in mass-market production.

It even has an Arduino compatibility framework, so you can start with that and then iterate as you go. It’s pretty unique to go from bench to production like that.

So we love ESP32 at Inanimate.

A big player in the ESP32 ecosystem is M5: they’re China-based and have about 400 SKUs that wrap ESP32 microcontrollers in all kinds of enclosures with all kinds of peripherals and sensors. I had a blast getting a personal tour of M5 when I visited Shenzhen last year – they use their own sensors in an industrial IoT network to run and monitor their assembly line.

Now you may have seen an M5Stick or two on the socials. They’re super popular at least in my circle, people love hacking on them.

Pick up an M5Stick-C Plus2 on Amazon for less than 30 bucks! It’s an ESP32 with a screen, buttons, buzzer, gyro, battery and mic in a tiny bright yellow package.

Get yourself one or two, bring it up by following the docs and then install Courier…

…or use our example code. Our example also supports the newer M5StickS3 which is grey and has a more powerful chip.

This is what I made with real-time messaging plus my backend websocket server:

My lil traffic guy tells me the top pages on my blog in real-time ^_^ v

I have live cursors on every page of my blog (write-up and open source code) so that same system sends JSON messages via websockets to the M5Stick on my desk.

If a post gets big then I have my stick on my desk so I see immediately, then I pop over to the page and say hi to everyone with the cursor chat.

More visitors = more flowers!

Plus: shake-for-QR code, so I can quickly follow the link back to the top post.

It’s amazing when hardware starts to feel alive.

Do show me if you make anything too.

Try Courier now

To use Courier right now, first bring up your M5Stick or other ESP32 hardware so you know it works ok, and then go to the Courier repo on GitHub where you can find installation instructions, API docs and examples.

It’s under active development: this is what we use for prototyping at Inanimate. Hey, subscribe to our Lab Notes newsletter!

Courier is distributed under an MIT license.