CircuitPython Library Installation

To interface your PyPortal with the DYMO scale and the internet - you'll need to install the Adafruit CircuitPython Adafruit IO and the Adafruit CircuitPython DymoScale 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 matching your version of CircuitPython. PyPortal requires at least CircuitPython version 4.0.0.

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

  • adafruit_io
  • adafruit_dymoscale
  • adafruit_esp32spi
  • adafruit_bus_device 
  • adafruit_bitmap_font
  • adafruit_display_text
  • neopixel.mpy

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

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 secrets.py file:

Download: file
secrets = {
    'ssid' : '_your_wifi_ssid',
    'password : '_your_wifi_password',
    'aio_username' : '_your_adafruit_io_username',
    'aio_key' : '_your_big_huge_super_long_aio_key_'
    }

Add CircuitPython Code and Project Assets

In the embedded code element below, click on the Download: Project Zip link, and save the .zip archive file to your computer.

Then, uncompress the .zip file, it will unpack to a folder named PyPortal_IOT_Scale.

Copy the contents of the PyPortal_IOT_Scale directory to your PyPortal's CIRCUITPY drive.

Make sure to save the fonts (Helvetica-Bold-16.bdf and Helvetica-Bold-36.bdf) into the fonts folder on the CIRCUITPY volume.

Rename the pyportal_scale.py file to code.py so it will automatically run when the PyPortal restarts.

"""
PyPortal Smart Scale
an internet of things smart-scale for Adafruit IO

Brent Rubell for Adafruit Industries, 2019
"""
import time
import board
import adafruit_dymoscale
import busio
import digitalio

import displayio
from adafruit_display_text.label import Label
from adafruit_bitmap_font import bitmap_font

from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager
import neopixel
from adafruit_io.adafruit_io import IO_HTTP

# 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

# the current working directory (where this file is)
cwd = ("/"+__file__).rsplit('/', 1)[0]
large_font = cwd+"/fonts/Helvetica-Bold-36.bdf"
small_font = cwd+"/fonts/Helvetica-Bold-16.bdf"

root_group = displayio.Group(max_size=3)
print('loading fonts...')
weight_font = bitmap_font.load_font(large_font)
weight_font.load_glyphs(b'0123456789.goz-SCALEROIO ')

text_font = bitmap_font.load_font(small_font)
text_font.load_glyphs(b'sendig!t.')

print('making labels...')
weight_label = Label(weight_font, max_glyphs=20)
weight_label.x = 75
weight_label.y = 120
root_group.append(weight_label)
weight_label.text = "---"

title_label = Label(weight_font, max_glyphs=20)
title_label.x = 65
title_label.y = 20
root_group.append(title_label)
title_label.text = "IO SCALE"

text_label = Label(text_font, max_glyphs=25)
text_label.x = 100
text_label.y = 200
text_label.color = 0xFFFFFF
root_group.append(text_label)

board.DISPLAY.show(root_group)

# PyPortal ESP32 Setup
esp32_cs = digitalio.DigitalInOut(board.ESP_CS)
esp32_ready = digitalio.DigitalInOut(board.ESP_BUSY)
esp32_reset = digitalio.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.)
aio_username = secrets['aio_username']
aio_key = secrets['aio_key']

# Create an instance of the IO_HTTP client
io = IO_HTTP(aio_username, aio_key, wifi)

# Get the weight feed from IO
weight_feed = io.get_feed('weight')

# initialize the dymo scale
units_pin = digitalio.DigitalInOut(board.D3)
units_pin.switch_to_output()
dymo = adafruit_dymoscale.DYMOScale(board.D4, units_pin)

# take a reading of the current time, used for toggling the device out of sleep
time_stamp = time.monotonic()

while True:
    try:
        reading = dymo.weight
        text = "%0.1f g"%reading.weight
        print(text)
        weight_label.text = text
        weight_label.color = 0xFFFFFF
        try:
            print('Sending to Adafruit IO...')
            text_label.text = 'sending...'
            # send data to Adafruit IO (rounded to one decimal place)
            io.send_data(weight_feed['key'], round(reading.weight, 1))
        except (ValueError, RuntimeError) as e:
            print("failed to send data..retrying...")
            wifi.reset()
            continue
        print('Data sent!')
        text_label.text = 'sent!'
        # to avoid sleep mode, toggle the units pin every 2mins.
        if (time.monotonic() - time_stamp) > 120:
            print('toggling units button')
            dymo.toggle_unit_button()
            # reset the time
            time_stamp = time.monotonic()
    except RuntimeError as e:
        weight_label.text = "SCALE\nERROR"
        weight_label.color = 0xFF0000
        print("Error: ", e)

This is what the final contents of the CIRCUITPY drive will look like:

Code Usage

Ensure that the scale's data pin is plugged into D3 on the PyPortal and the units button is plugged into D4 on the PyPortal.

Then, the PyPortal will display IOT Scale and should display the current weight shown on the scale's LCD display.

If your scale is displaying SCALE ERROR, the scale is not turned on yet. Press the power button (the button all the way on the left) to turn on the scale's power.

Since you're not running the scale off of batteries, you'll need to perform this step each time you disconnect/reset the PyPortal.

When you place something on the scale, the PyPortal's display will update with a new value and send it to Adafruit IO.

Every two minutes, the scale's LCD will switch between grams and ounces to avoid going into sleep mode (see the Removing the Auto Shut Off section below) 

This guide was first published on Apr 02, 2019. It was last updated on Apr 02, 2019.
This page (CircuitPython Code) was last updated on Sep 26, 2020.