Scaling an IoT deployment? Join our webinar on May 28th where we dive into real-world scaling pain points and how to overcome them.

Blues Developers
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
Button IconHelp
Notehub StatusVisit our Forum
Button IconSign In
Sign In
Sign In
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
homechevron_rightBlogchevron_rightDynamically Switching Wi-Fi Networks on a Notecard

Dynamically Switching Wi-Fi Networks on a Notecard

Dynamically Switching Wi-Fi Networks on a Notecard banner

December 12, 2023

Learn a technique you can use to switch a Notecard’s Wi-Fi network using environment variables.

  • Wi-Fi
  • Environment Variables
TJ VanToll
TJ VanTollPrincipal Developer Advocate
email
warning

As of Notecard firmware version 7.5.2, there’s a much easier way to implement this article’s workflow using the built-in _wifi environment variable. Learn more in Specifying Multiple Access Points.

One powerful feature of the new Notecard Cell+WiFi is the ability to use a Wi-Fi connection with a built-in fallback to cellular connectivity.

To use this feature you must tell the Notecard which Wi-Fi network to use with the card.wifi request. If the Notecard detects that the provided network is available and has connectivity, the Notecard will use that network to send your data; if the Notecard detects that the provided network is unavailable or lacks connectivity, the Notecard will instead send your data over a cellular connection.

In this article I want to discuss an extension to this workflow you might want to use: the ability to dynamically switch which Wi-Fi network your Notecard uses.

How to Switch Networks

To show what I mean, let’s start with an example. Here’s the typical way you associate a Notecard with a Wi-Fi network using the card.wifi request.

{
  "req": "card.wifi",
  "ssid": "your_network",
  "password": "your_password"
}

This request is simple and easy to run in our In-Browser Terminal.

The request running in the In-Browser Terminal

This works, but suppose you’re using the same Notecard across many different facilities, such a piece of manufacturing equipment. Or suppose you’re building the Notecard into a product where the customer has to enter their personal Wi-Fi information. In situations like these it’s not ideal (or sometimes not even possible) to issue an explicit card.wifi request every time you want to update the Wi-Fi network the Notecard should use.

Luckily, the Notecard gives you other options for more robust automation.

Using Environment Variables

The Notecard and its backing cloud service, Notehub, offer a settings management feature called environment variables.

Environment variables are key-value pairs that can be set in the Notehub UI or through the Notehub API, and propagate to devices or fleets of devices using the same synchronization mechanism used by the Notecard.

Let me explain using an example. Suppose you’re building a fan that activates when the temperature goes above a certain threshold—for example, the fan should turn on when the room’s temperature hits 30 degrees Celsius. Although you could hardcode the threshold value into your firmware, that would make the value very difficult (if not impossible) to update in the future.

As an alternative, you could instead define an environment variable that has this value. Here’s what that might look like in the Notehub user interface.

An example environment variable defined in Notehub

With an environment variable defined, your firmware can retrieve the value using the Notecard’s env.get request. The big thing you gain by doing this is, if you ever need to update the threshold, you can do so either in the Notehub UI or by using the Notehub API’s environment variable requests.

Using the Notehub API is especially important here, as it allows you to build your own interfaces (web applications, mobile applications, etc) that can update environment variables—meaning you can pretty easily build user interfaces with controls that affect your live devices.

The flow of environment variables with BluesThe flow of environment variables in the Blues ecosystem. The browser invokes the Notehub API, which saves the temperature value as an environment variable. On its next inbound sync, the Notecard receives the environment variable and passes it to the fan’s host firmware.

note

But wait, there’s more!

Environment variables also have a built-in hierarchy system that allow you to define variables at the device level, fleet level, or project level. You could use this ability to, for example, set a temperature threshold for an entire project, but allow individual devices to override the threshold.

For instance, if you set the temperature_threshold above at the project level, you would then have the ability for individual devices to override that default as necessary—all while keeping all hardcoded values out of your firmware.

Storing Wi-Fi Credentials in Environment Variables

This same technique can be applied to Wi-Fi credentials. Instead of manually providing your credentials through a card.wifi request, instead you can create environment variables for a network ssid and password.

An example set of Wi-Fi environment variables defined in Notehub

Now, your firmware can use one of the Notecard’s firmware libraries to perform an env.get request to retrieve the Wi-Fi credentials, and apply them with a card.wifi request.

If your firmware is C-based, we offer a library to make this process easier: Notecard Environment Variable Manager . With Notecard Environment Variable Manager you start by initializing a NotecardEnvVarManager object.

NotecardEnvVarManager *manager = NotecardEnvVarManager_alloc();

Next, you tell the NotecardEnvVarManager which variables you want to monitor using NotecardEnvVarManager_fetch.

const char *vars[] = {
    "wifi_ssid",
    "wifi_password"
};
const size_t numVars = sizeof(vars) / sizeof(vars[0]);

int ret = NotecardEnvVarManager_fetch(manager, vars, numVars);

The NotecardEnvVarManager_fetch function makes an env.get request to the Notecard for the specified variables and invokes a user-provided callback on each key-value pair in the response. Here’s an example callback that handles the wifi_ssid and wifi_password values, and invokes the card.wifi request if it detects an updated value.

Notecard notecard;
static char *wifi_ssid = nullptr;
static char *wifi_password = nullptr;

void envVarManagerCb(const char *var, const char *val, void *user_ctx) {
  bool update_wifi = false;

    if (strcmp(var, "wifi_ssid") == 0) {
        if (!wifi_ssid || strncmp(wifi_ssid, val, 255) != 0) {
            delete(wifi_ssid);
            if (256 < strnlen(val, 255)) {
                notecard.logDebugf("[ERROR] Wi-Fi SSID is too long! (max: 255)\n");
            } else {
                const size_t ssid_len = (strnlen(val, 255) + 1);
                wifi_ssid = new char[256]; // Allocate as reusable chunk to preserve heap
                strlcpy(wifi_ssid, val, ssid_len);
                notecard.logDebugf("[APP] Updating Wi-Fi SSID to %s.\n", val);
                update_wifi = true;
            }
        }
    } else if (strcmp(var, "wifi_password") == 0) {
        if (!wifi_password || strncmp(wifi_password, val, 255) != 0) {
            delete(wifi_password);
            if (256 < strnlen(val, 255)) {
                notecard.logDebugf("[ERROR] Wi-Fi password is too long! (max: 255)\n");
            } else {
                const size_t password_len = (strnlen(val, 255) + 1);
                wifi_password = new char[256]; // Allocate as reusable chunk to preserve heap
                strlcpy(wifi_password, val, password_len);
                notecard.logDebug("[APP] Updating Wi-Fi password to ");
                for (size_t i = 0; i < password_len; ++i) {
                    notecard.logDebug("*");
                }
                notecard.logDebug(".\n");
                update_wifi = true;
            }
        }
    } else {
        notecard.logDebugf("[APP] Ignoring unknown environment variable: %s\n", var);
    }

    // Update Wi-Fi credentials (if necessary)
    if (update_wifi) {
        if (J *req = notecard.newRequest("card.wifi")) {
            JAddItemReferenceToObject(req, "ssid", JCreateString(wifi_ssid));
            JAddItemReferenceToObject(req, "password", JCreateString(wifi_password));
            notecard.sendRequest(req);
        }
    }
}
note

For full context on how to use this approach, see the Blues Smart CO2 Detector accelerator. The project’s source code is open source, and contains firmware that implements the Wi-Fi credential management workflow discussed in this article.

A couple of additional important notes:

  • Although the example code above is written in C, this technique can be used with any of the Notecard’s firmware libraries. All you need to do is invoke env.get at a regular cadence, and when you detect a change, invoke the card.wifi request to update the Notecard’s Wi-Fi credentials.

  • Invoking the Notecard’s env.get request does not initiate a network request. Instead, the request retrieves the latest version of the environment variable locally on the Notecard. How often the Notecard checks for environment variable updates is determined by the inbound value you provide to the hub.set request. You can have the Notecard immediately retrieve new environment variables on all changes by setting the hub.set request’s mode to "continuous" and sync argument to true. With these values set the Notecard maintains a continuous connection to Notehub, which allows you to receive environment variable updates immediately, but also means the Notecard will use considerably more voltage. As such, setting these values is only recommended if you’re running on mains power.

  • If you can’t use the Notecard’s continuous mode with sync because you’re running on battery power, note that there will be some delay between updating environment variables and getting the updated values on your Notecard. If you’re using the Notecard Cell+WiFi you don’t have to worry too much about this delay, as the Notecard will continue to work over cellular until it receives the updated credentials. But this could be a concern if you’re moving the Notecard to a location where Wi-Fi coverage is available but cellular coverage is not.

Wrapping Up

And that’s it!

In this article we looked at one technique you can use to switch the Notecard between multiple Wi-Fi networks using environment variables. In short, you store the Wi-Fi network credentials you’d like to use in environment variables, and you write firmware that receives the updated credentials and invokes the Notecard’s card.wifi request.

If you give this technique a shot let us know how it goes in this article’s comments . Or feel free share any other techniques you’ve used to manage Wi-Fi networks in your projects or solutions. Happy hacking!

In This Article

  • How to Switch Networks
  • Using Environment Variables
  • Storing Wi-Fi Credentials in Environment Variables
  • Wrapping Up

Blues Developer News

The latest IoT news for developers, delivered right to your inbox.

Comments

Join the conversation for this article on our Community Forum

Blues Developer Newsletter

The latest IoT news for developers, delivered right to your inbox.

© 2025 Blues Inc.
© 2025 Blues Inc.
TermsPrivacy
Notecard Disconnected
Having trouble connecting?

Try changing your USB cable as some cables do not support transferring data. If that does not solve your problem, contact us at support@blues.com and we will get you set up with another tool to communicate with the Notecard.

Advanced Usage

The help command gives more info.

Connect a Notecard
Use USB to connect and start issuing requests from the browser.
Try Notecard Simulator
Experiment with Notecard's latest firmware on a Simulator assigned to your free Notehub account.

Don't have an account? Sign up