If you have not yet set up a settings.toml file in your CIRCUITPY drive and connected to the internet using it, follow the directions in the Create Your settings.toml File and Internet Connect! pages in this guide.
You will need your Adafruit IO username, and Adafruit IO key. Head to io.adafruit.com and simply click the View AIO Key link on the left hand side of the Adafruit IO page to get this information.
Then, add them to the settings.toml file:
CIRCUITPY_WIFI_SSID = "your_wifi_ssid" CIRCUITPY_WIFI_PASSWORD = "your_wifi_password" AIO_USERNAME = "your_aio_username" AIO_KEY = "your_aio_key"
Add CircuitPython Code and Project Assets
In the embedded code element below, click on the Download Project Bundle button, and save the .zip archive file to your computer.
Then, uncompress the .zip file, it will unpack to a folder named PyPortal_Smart_Thermometer.
Copy the contents of the PyPortal_Smart_Thermometer directory to your PyPortal CIRCUITPY drive.
Make sure to save the fonts (Ninito-Black-17.bdf and Ninito-Light-75.bdf) into the fonts folder on the CIRCUITPY volume and save pyportal_splash.bmp into the icons folder.
# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # # SPDX-License-Identifier: MIT """ PyPortal Smart Thermometer ============================================== Turn your PyPortal into an internet-connected thermometer with Adafruit IO Author: Brent Rubell for Adafruit Industries, 2019 """ import time import board import neopixel import busio from digitalio import DigitalInOut from analogio import AnalogIn import adafruit_adt7410 from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # thermometer graphics helper import thermometer_helper # rate at which to refresh the pyportal screen, in seconds PYPORTAL_REFRESH = 2 # 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.) try: ADAFRUIT_IO_USER = secrets['aio_username'] ADAFRUIT_IO_KEY = secrets['aio_key'] except KeyError: raise KeyError('To use this code, you need to include your Adafruit IO username \ and password in a secrets.py file on the CIRCUITPY drive.') # Create an instance of the IO_HTTP client io = IO_HTTP(ADAFRUIT_IO_USER, ADAFRUIT_IO_KEY, wifi) # Get the temperature feed from Adafruit IO temperature_feed = io.get_feed('temperature') # init. graphics helper gfx = thermometer_helper.Thermometer_GFX(celsius=False) # init. adt7410 i2c_bus = busio.I2C(board.SCL, board.SDA) adt = adafruit_adt7410.ADT7410(i2c_bus, address=0x48) adt.high_resolution = True # init. the light sensor light_sensor = AnalogIn(board.LIGHT) def set_backlight(val): """Adjust the TFT backlight. :param val: The backlight brightness. Use a value between ``0`` and ``1``, where ``0`` is off, and ``1`` is 100% brightness. """ val = max(0, min(1.0, val)) try: board.DISPLAY.auto_brightness = False except AttributeError: pass board.DISPLAY.brightness = val while True: # read the light sensor light_value = light_sensor.value print('Light Value: ', light_value) # read the temperature sensor temperature = adt.temperature try: # WiFi Connection if light_value < 1000: # turn on the backlight set_backlight(1) print('displaying temperature...') gfx.display_temp(temperature) # Get and display date and time form Adafruit IO print('Getting time from Adafruit IO...') datetime = io.receive_time() print('displaying time...') gfx.display_date_time(datetime) else: # turn off the backlight set_backlight(0) try: # send temperature data to IO gfx.display_io_status('Sending data...') print('Sending data to Adafruit IO...') io.send_data(temperature_feed['key'], temperature) print('Data sent!') gfx.display_io_status('Data sent!') except AdafruitIO_RequestError as e: raise AdafruitIO_RequestError('IO Error: ', e) except (ValueError, RuntimeError, ConnectionError, OSError) as e: print("Failed to get data, retrying\n", e) wifi.reset() continue time.sleep(PYPORTAL_REFRESH)
This is what the final contents of the CIRCUITPY drive will look like:
The following libraries are used in this project. So grab them and install them into CIRCUITPY/lib now!
- adafruit_esp32spi - This is the library that gives you internet access via the ESP32 using (you guessed it!) SPI transport. You need this for anything Internet
- adafruit_requests - This library allows us to perform HTTP requests and get responses back from servers. GET/POST/PUT/PATCH - they're all in here!
- adafruit_pyportal - This is our friendly wrapper library that does a lot of our projects, displays graphics and text, fetches data from the internet. Nearly all of our projects depend on it!
- adafruit_touchscreen - a library for reading touches from the resistive touchscreen. Handles all the analog noodling, rotation and calibration for you.
- adafruit_io - this library helps connect the PyPortal to our free datalogging and viewing service
- adafruit_imageload - an image display helper, required for any graphics!
- adafruit_display_text - not surprisingly, it displays text on the screen
- adafruit_bitmap_font - we have fancy font support, and its easy to make new fonts. This library reads and parses font files.
- adafruit_slideshow - for making image slideshows - handy for quick display of graphics and sound
- neopixel - for controlling the onboard neopixel
- adafruit_adt7410 - library to read the temperature from the on-board Analog Devices ADT7410 precision temperature sensor
- adafruit_sdcard - support for reading/writing data from the onboard SD card slot.
- adafruit_bus_device - low level support for I2C/SPI
Your PyPortal will boot up to a splash screen displaying the PyPortal logo along with the Analog Devices and Adafruit IO logos.
While the PyPortal seems like it's just displaying a splash screen - it is doing a lot of work behind the scenes! The PyPortal is loads in the two fonts this project requires and sets up labels for displaying text.
Wave your hand in front of the PyPortal's light sensor to turn on the display's backlight!
Your PyPortal Thermometer will display the current temperature reading, pull in the date and time from Adafruit IO (based off of your IP address), and send the data to Adafruit IO.
When it finishes sending data, it'll turn the display back off but continue to send data to Adafruit IO.
When the backlight is turned on, it produces heat. This interferes with the ADT7410's ambient temperature readings.
Adafruit IO Usage
While the PyPortal thermostat can display its temperature along with the current date/time on its screen - what if you're physically away from the thermostat?
How do we know that the temperature data is being sent from the thermostat to Adafruit IO?
Open the Adafruit IO Dashboard you created earlier. Notice that the fill and values of the gauge changes 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.
Displaying temperature in Fahrenheit
Live in a region where Fahrenheit is the standard? The thermometer_helper
can handle displaying the temperature as either Fahrenheit or Celsius.
To display the temperature in Fahrenheit, modify the following line in code.py
from:
gfx = thermometer_helper.Thermometer_GFX()
to
gfx = thermometer_helper.Thermometer_GFX(celsius=False)
Changing fonts
Want to use a different font? The fonts for this project are referenced at the top of the thermometer_helper.py file as info_font
and temperature_font
.
The PyPortal reads .BDF (bitmap distribution format) fonts, so you'll need to convert a font into this format, and then modify the code to use the new font.
For more information about converting fonts, read the learning guide here...
Custom Wall Mount
The wall mount used in this project PyPortal was created by the Ruiz Brothers. For detailed instructions about how to print your own, check out the learning system guide here.
Text editor powered by tinymce.