Collecting Sensor Data
CircuitPython, Adafruit HUZZAH32, and Notecarrier A
Don't see your favorite hardware here? Rest assured the Notecard works with virtually every MCU and SBC available. If you can't figure out how to complete this tutorial let us know in our forum and we can help you out.
Introduction
This tutorial should take approximately 40-50 minutes to complete.
In this tutorial, you'll learn how to take sensor readings from a Device and send readings to your Notecard and the Blues Notehub. You'll use CircuitPython running on a Adafruit HUZZAH32 wired up to Notecarrier A hardware. If you would like to use a different language, board, or Notecarrier, modify the dropdowns at the top of this guide. And if you get stuck at any point, the full source code for each example is available on GitHub.
The tutorial uses mock sensor readings for simplicity, but feel free to hook up a physical sensor of your choice and use that instead.
Set up Hardware
First, you'll need to get all of your hardware connected. Follow the instructions below to connect your Adafruit HUZZAH32 and Notecard mounted on a Notecarrier A.
In order to complete this guide, you'll need the following:
- Notecard mounted to Notecarrier A.
-
Any CircuitPython-capable Microcontroller (MCU) with Feather headers. We'll be using the Adafruit HUZZAH32, but any MCU with a CircuitPython bootloader and binary will do.
-
Follow the ESP32-specific instructions for burning the bootloader and flashing the CircuitPython binary to your device. If you're using the Adafruit HUZZAH32, update your board to the latest version of CircuitPython. (We recommend using the "Open Installer" method and using the Web Workflow to use the CircuitPython Code Editor).
- Micro USB to USB-A cable.
For this tutorial, you'll be powering the Notecard through the Micro USB connection of your Adafruit HUZZAH32. Some Feather-compatible devices cannot handle 2 Amp pulses from the Notecard when connected to GSM, so if you experience resets or other power-related issues, we suggest powering your Notecard separately through the USB or LiPo connector on the Notecarrier.
Connect the Adafruit HUZZAH32 to your Notecard
Now, let's connect your Notecard using a Serial connection.
-
Connect
V+
from the Notecarrier A to theUSB
pin on your Adafruit HUZZAH32. -
Connect
GND
from the Notecarrier A to aGND
pin on your Adafruit HUZZAH32. -
Connect
TX
from the Notecarrier A to theRX
pin on your Adafruit HUZZAH32. -
Connect
RX
from the Notecarrier A to theTX
pin on your Adafruit HUZZAH32. -
Plug the USB cable directly into your Adafruit HUZZAH32, which will allow you to flash firmware to your device.
NOTE: Make extra sure you've plugged in the jumper wires next to the
TX
andRX
pins on the Feather. The pin names are actually printed underneath the pin they're referring to, and mis-wiring will cause a serial error ofnotecard not responding
without much else to help debug the actual issue.
Create a Notehub Project
Now that your hardware is all connected, let's create a new Notehub project to receive sensor readings from your Notecard.
-
Navigate to notehub.io and log-in, or create a new account.
-
Using the New Project card, give your project a name and ProductUID.
note The ProductUID must be globally unique, so we recommend a namespaced name like
"com.your-company.your-name:your_product"
. -
Take note of your ProductUID. This identifier is used by Notehub to associate your Notecard to your project.
Write Firmware
Now you're ready to write some firmware. When communicating with the Notecard,
you can manually send requests using the Serial write
function and passing-in
JSON objects, or use the note-python
library (the recommended path).
The rest of this tutorial assumes you have already burned the bootloader and flashed the CircuitPython binary to your MCU.
If you haven't, please consult Adafruit's guide for Installing CircuitPython on ESP32. The following instructions assume you are using the Web Workflow for programming your ESP32.
Configure your Notecard
Install the Notecard Python Library
-
To use the
note-python
library, you'll first need to download or clone it from the GitHub repo.
-
Unzip the archive and upload the
notecard
directory into thelib
directory using the CircuitPython Code Editor.
-
Add an
import
for the library at the top of yourcode.py
file.import notecard
Set up Your Notecard
-
Add some additional imports to the top of your
code.py
file:import board import busio import time import json
-
Add a definition for your ProductUID using the value you specified when creating your Notehub project.
productUID = "com.your-company.your-name:your_product"
-
Configure the serial connection to your Notecard, and write a newline to clear its buffer. Initialize the serial connection to the Notecard using the
OpenSerial
function.serial = busio.UART(board.TX, board.RX, baudrate=9600) card = notecard.OpenSerial(serial)
-
Now, we'll configure the Notecard. Using the
hub.set
request, we associate this Notecard with the ProductUID of your project and set the Notecard to operate incontinuous
mode, which indicates that the device should immediately make a connection to Notehub and keep it active.req = {"req": "hub.set"} req["product"] = productUID req["mode"] = "continuous" rsp = card.Transaction(req)
The lines above build-up a JSON object by adding two string values for product and mode, and then fires the request off to the Notecard with the
Transaction
function.
-
Click the "Save + Run" button in the CircuitPython Code Editor to flash this code to your device.
-
The serial monitor will open automatically. If everything has been connected and configured properly, you'll see a few debug messages, including the JSON object you sent, as well as the response from the Notecard:
{}
.
Read from the Sensor
Now that you've configured your MCU to communicate with the Notecard, let's grab
some pseudo sensor readings, where the temperature
comes from the onboard
temperature sensor of the Notecard and the humidity
is a random number.
If you have your own sensor, feel free to hook it up and use your own values instead of this tutorial's mocked ones.
-
To generate psuedo sensor readings you'll use the
notecard-pseudo-sensor
library. Start by downloading or cloning the library from its GitHub repo.
-
Unzip the archive and upload the
notecard_pseudo_library
directory into thelib
directory using the CircuitPython Code Editor.
-
Add an import for the library at the top of your
code.py
file.import notecard_pseudo_sensor
-
Configure the pseudo sensor with a reference to the Notecard you created earlier.
sensor = notecard_pseudo_sensor.NotecardPseudoSensor(card)
-
Add the following code block to the bottom of your
code.py
file. This takes a mock temperature and humidity reading before sleeping for 15 seconds and repeating the process.while True: temp = sensor.temp() humidity = sensor.humidity() print("\nTemperature: %0.1f C" % temp) print("Humidity: %0.1f %%" % humidity) time.sleep(15)
-
Click the "Save + Run" button in the CircuitPython Code Editor to flash this code to your device.
-
The serial monitor will open automatically. Every 15 seconds, you'll see new debug statements and sensor readings.
{"req": "card.temp"} {"value":26.25,"calibration":-1.0} Temperature: 26.3 C Humidity: 47.0 %
Send Sensor Readings to the Notecard
Now that we're getting sensor readings, let's send these to our Notecard.
-
To send a sensor reading to the Notecard, we'll need to construct a new JSON request to the
note.add
API that includes a new Notefile name (sensors.qo
), sets thesync
field to true to instruct the Notecard to sync to Notehub immediately, and finally, sets thebody
to the sensor temperature and humidity. Add the following inwhile
loop right after theprint
commands to print out readings.req = {"req": "note.add"} req["file"] = "sensors.qo" req["sync"] = True req["body"] = { "temp": temp, "humidity": humidity} rsp = card.Transaction(req) print(rsp)
-
Click the "Save + Run" button in the CircuitPython Code Editor to flash this code to your device. After restart, the Serial monitor will update to display the response from the
note.add
request (the total number of Notes in the notefile) each time you add a new reading.{"req": "card.temp"} {"value":26.375,"calibration":-1.0} Temperature: 26.4 C Humidity: 46.5 % {"req": "note.add", "body": {"humidity": 46.5156, "temp": 26.375}, "sync": true, "file": "sensors.qo"} {"total":1}
If you are curious about how to interact with the Notecard using Python without
the note-python
library. We have provided
a sample script
for review.
You may also be interested in reviewing the Notecard Guide, Notecard Communication Without a Library.
View Data in Notehub
Once you start capturing readings, your Notecard will initiate a connection to Notehub and will start transferring Notes. Depending on signal strength and coverage in your area, it may take a few minutes for your Notecard to connect to Notehub and transfer data.
-
Return to notehub.io and open your project. You should see your notecard in the Devices view.
-
Now, click on the Events left menu item. Once your sensor Notes start syncing, they'll show up here.
Use Environment Variables
Environment variables are a Notehub state and settings management feature that allow you to set variables in key-value pairs, and intelligently synchronize those values across devices and fleets of devices.
In this section you'll learn how environment variables work by creating a variable that determines how often your firmware should take sensor readings.
Using Environment Variables in Firmware
The Notecard provides a set of requests for working with environment variables.
The most common of these requests is env.get
,
which allows you to retrieve the value of an environment variable.
Complete the steps below to use the env.get
request to retrieve and use the
reading_interval
environment variable.
-
First, adjust your existing
hub.set
configuration to set thesync
argument totrue
. Whensync
istrue
, the Notecard synchronizes inbound environment variable changes as soon as they're made in Notehub.req = {"req": "hub.set"} req["product"] = productUID req["mode"] = "continuous" req["sync"] = True # add this line rsp = card.Transaction(req)
-
Next, place the following new function before the existing
while True
loop.# This function assumes you’ll set the reading_interval environment variable to # a positive integer. If the variable is not set, set to 0, or set to an invalid # type, this function returns a default value of 60. def get_sensor_interval(): sensor_interval_seconds = 60 req = {"req": "env.get"} req["name"] = "reading_interval" rsp = card.Transaction(req) if rsp and rsp["text"] and int(rsp["text"]) > 0: sensor_interval_seconds = int(rsp["text"]) return sensor_interval_seconds
-
Finally, find the existing
time.sleep(15)
line in yourwhile True
loop, and replace it with the code below.sensor_interval_seconds = get_sensor_interval() print(f"Delaying {sensor_interval_seconds} seconds") time.sleep(sensor_interval_seconds)
Your firmware now uses the reading_interval
environment variable to determine how
many seconds to delay in between sensor readings.
If you save this code, after restart you should see your device using
the default reading_interval
value of 60 seconds.
Setting an Environment Variable
Now we have our device programmed to retrieve an Environment Variable from Notehub, we will create that variable. Environment variables can be set in the Notehub UI or through the Notehub API. In this tutorial you'll learn how to set the values through the Notehub UI. If you'd like to instead set environment variables through the Notehub API, refer to environment variable requests in the Project API.
-
Return to your Notehub project, go the the Devices page, and double click your device. You should see a screen that looks like this.
-
Click the Environment tab.
-
Under the Device environment variables header, define a new environment variable named
reading_interval
and set its value to30
.
Now that you have an environment variable set you should see it immediately reflected on your device.
And with that, you've used your first environment variable on your Notecard!
To see the real power of environment variables in action, try returning to Notehub
and updating your device's reading_interval
with your serial monitor open. Your
firmware will retrieve the updated value and start using it immediately.
This tutorial had you use several configuration settings that are best used when you have your Notecard connected to mains power.
-
In the
hub.set
request, settingmode
to"continuous"
tells the Notecard to maintain an active network connection. -
In the
hub.set
request, settingsync
totrue
tells the Notecard to immediately synchronize inbound Notes and environment variables from Notehub. -
In the
note.add
request, settingsync
totrue
tells the Notecard to immediately synchronize all outbound Notes to Notehub.
Because each of these settings cause the Notecard to use more power, you
may wish to disable them if you plan to transition your project to battery power.
You can run the command below to put your Notecard into periodic
mode with
the sync
argument turned off.
{
"req": "hub.set",
"mode": "periodic",
"sync": false,
"outbound": 60,
"inbound": 120
}
Learn more about optimizing the Notecard for low-power scenarios in Low Power Design.
Next Steps
Congratulations! You've successfully connected your Adafruit HUZZAH32 to your Notecard and built a basic IoT project.
If you're following the Blues Quickstart, next we recommend learning how to send (and visualize) your data in a cloud application:
Use the Notecard to Send DataSet Up Your MicrocontrollerBuild Your First IoT App With Blues- Send Data to Your Cloud
At any time, if you find yourself stuck, please reach out on the community forum.