CircuitPython Code

CircuitPython Library Installation

The Adafruit_CircuitPython_AdafruitO module allows you to easily write CircuitPython code which can interact with Adafruit IO.

You'll need to install the Adafruit CircuitPython Adafruit IO and the Adafruit CircuitPython ADT7410 libraries on your PyPortal.

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  For example the Circuit Playground Express guide has a great page on how to install the library bundle for both express and non-express boards.

Before continuing make sure your board's lib folder has the following files and folders copied over.

  • Adafruit_CircuitPython_AdafruitIO
  •  Adafruit_CircuitPython_ESP32SPI
  • adafruit_adt7410.mpy
  • adafruit_bus_device 

Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.

Once you have your CircuitPython libraries installed, let's get your PyPortal connected to Adafruit IO and the internet. To this, you'll create a secrets file.

Secrets File Setup

If you have not yet set up a secrets.py file in your CIRCUITPY drive and connected to the internet using it, follow this guide and come back when you've successfully connected to the internet

Next, you should add your Adafruit IO Username and Adafruit IO Key to the secrets.py file.

Your secrets.py file should look like this:

Download: file
secrets = {
    'ssid' : 'home ssid',
    'password' : 'my password',
    'timezone' : "America/New_York", # http://worldtimeapi.org/timezones
    'aio_username' : 'MY_ADAFRUIT_IO_USERNAME',
    'aio_key' : 'MY_ADAFRUIT_IO_KEY',
    }

Change MY_ADAFRUIT_USERNAME and MY_ADAFRUIT_IO_KEY to your Adafruit IO username and the secret key.

After you finish editing secrets.py, make sure to save the file (cmd/ctrl+s).

Code

Using a text-editor (we like Mu since it has a built-in serial REPL), copy the code below to your CircuitPython board,and save it as code.py. 

"""
PyPortal IOT Data Logger for Adafruit IO

Dependencies:
    * CircuitPython_ADT7410
        https://github.com/adafruit/Adafruit_CircuitPython_ADT7410

    * CircuitPython_AdafruitIO
        https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO
"""
import time
import board
import busio
from digitalio import DigitalInOut
from analogio import AnalogIn

# ESP32 SPI
from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager

# Import NeoPixel Library
import neopixel

# Import Adafruit IO HTTP Client
from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError

# Import ADT7410 Library
import adafruit_adt7410

# Timeout between sending data to Adafruit IO, in seconds
IO_DELAY = 30

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

# PyPortal ESP32 Setup
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)

# Set your Adafruit IO Username and Key in secrets.py
# (visit io.adafruit.com if you need to create an account,
# or if you need your Adafruit IO key.)
ADAFRUIT_IO_USER = secrets['aio_username']
ADAFRUIT_IO_KEY = secrets['aio_key']

# Create an instance of the Adafruit IO HTTP client
io = IO_HTTP(ADAFRUIT_IO_USER, ADAFRUIT_IO_KEY, wifi)

try:
    # Get the 'temperature' feed from Adafruit IO
    temperature_feed = io.get_feed('temperature')
    light_feed = io.get_feed('light')
except AdafruitIO_RequestError:
    # If no 'temperature' feed exists, create one
    temperature_feed = io.create_new_feed('temperature')
    light_feed = io.create_new_feed('light')

# Set up ADT7410 sensor
i2c_bus = busio.I2C(board.SCL, board.SDA)
adt = adafruit_adt7410.ADT7410(i2c_bus, address=0x48)
adt.high_resolution = True

# Set up an analog light sensor on the PyPortal
adc = AnalogIn(board.LIGHT)

while True:
    try:
        light_value = adc.value
        print('Light Level: ', light_value)

        temperature = adt.temperature
        print('Temperature: %0.2f C'%(temperature))

        print('Sending to Adafruit IO...')

        io.send_data(light_feed['key'], light_value)
        io.send_data(temperature_feed['key'], temperature, precision=2)
        print('Sent to Adafruit IO!')
    except (ValueError, RuntimeError) as e:
        print("Failed to get data, retrying\n", e)
        wifi.reset()
        continue
    print('Delaying {0} seconds...'.format(IO_DELAY))
    time.sleep(IO_DELAY)
If you run into any errors, such as "ImportError: no module named `adafruit_display_text.label`" be sure to update your libraries to the latest release bundle!

Before running the code, verify CIRCUITPY looks like the following.

From the Mu Editor, click the Serial button to open the REPL. You should see the REPL displaying the temperature and light values from the PyPortal's onboard sensors, and sending the data to Adafruit IO:

Download: file
Light Level:  37376
Temperature: 31.60 C
Sending to Adafruit IO...
Sent to Adafruit IO!
Delaying 30 seconds...

Your PyPortal should also display what is currently printed to the REPL.

Open the Adafruit IO Dashboard you created earlier. Notice that the fill and values of the gauges change as values are sent from your PyPortal to Adafruit IO. 

Then, leave the PyPortal running for a while and come back later to see new data appear on the line graph.

Want to send data less frequently to Adafruit IO?

Change the IO_DELAY value at the top of the program.

For example, if you wish to send data to Adafruit IO every minute, change the following line from:

IO_DELAY = 30

to

IO_DELAY= 60

Note: Setting this value lower than 30 seconds will likely cause Adafruit IO to throw a throttling error - you can only send 30 data points per minute (or 60 data points per minute with Adafruit IO Plus) to Adafruit IO.

Too much precision? Too little?

By default, Adafruit IO supports six points of precision (decimal places). However, in the code, you are only sending two .

To increase the precision of the temperature values you're sending from 2 to 4, modify the following line from:

io.send_data(temperature_feed['key'], temperature, precision=2)

to:

io.send_data(temperature_feed['key'], temperature, precision=4)

Taking it Further

For more examples and ideas - check out the Adafruit IO category on the Adafruit Learning System.

On the CircuitPython Adafruit IO library repository, you'll find we've included lots of examples for sending data, interacting with your CircuitPython board's digital inputs and outputs, feed/group/data interaction, and more

This guide was first published on Feb 28, 2019. It was last updated on Feb 28, 2019. This page (CircuitPython Code) was last updated on Aug 24, 2019.