First, the code imports the required libraries.

import time

import board
from digitalio import DigitalInOut
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import neopixel
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_io.adafruit_io import IO_MQTT
from adafruit_seesaw.seesaw import Seesaw
import busio

Next, the values we'll need in the main loop are created. The first variable, low, makes sure that you don't get a message every second when your plant needs to be watered, and min should match the value you are comparing the feed to in the Adafruit IO Action.

LOW = False
MIN = 500

Then, the moisture sensor gets initialized.

i2c_bus = board.I2C()
seesaw = Seesaw(i2c_bus, addr=0x36)

After that, the code checks to see if secrets.py exists and then sets up the AirLift FeatherWing.

# 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

# Set up WiFi
esp32_cs = DigitalInOut(board.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

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)

The callback functions are then defined which will be run when the device establishes a connection with Adafruit IO, when a new feed is subscribed to, and when a new message is received, respectively.

# Define callback functions which will be called when certain events happen.
# pylint: disable=unused-argument
def connected(client):
    # This method is called when the client connects to Adafruit IO
    client.subscribe("plant")

def subscribe(client, userdata, topic, granted_qos):
    # This method is called when the client subscribes to a new feed.
    print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos))

def message(client, feed_id, payload):
    # This method is called when a feed receives a new message
    print("Feed {0} received new value: {1}".format(feed_id, payload))

After the callback functions, the code connects to the internet and then to Adafruit IO.

# Connect to WiFi
print("Connecting to WiFi...")
wifi.connect()
print("Connected!")

# Initialize MQTT interface with the esp interface
MQTT.set_socket(socket, esp)

# Initialize a new MQTT Client object
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=secrets["aio_username"],
    password=secrets["aio_key"],
)

# Initialize an Adafruit IO MQTT Client
io = IO_MQTT(mqtt_client)

# Connect the callback methods defined above to Adafruit IO
io.on_connect = connected
io.on_subscribe = subscribe
io.on_message = message

# Connect to Adafruit IO
print("Connecting to Adafruit IO...")
io.connect()

Before the main loop, the code defines a variable, start. This variable is used to make sure that the feed isn't published to more often than desired.

START = 0

The first thing that happens in the main loop is the sensor's temperature and moisture are read. The temperature isn't used in this code, but I left it in there just in case someone wants to add temperature to their project.

Then the code checks if the value from the sensor is below the specified threshold. It then checks to see if this is the first time since it was last above the threshold that it has published a value. This is done so that when the sensor is below the threshold, the webhook isn't activated all the time. It then publishes the value.

In the next if block, the code checks to see if the sensor value is above the threshold and then checks to see if it's been 10 seconds since the last value was published and if it has been ten seconds it publishes the value.

Finally, the code prints the sensor values and the loop starts over again.

while True:
    # read moisture level through capacitive touch pad
    touch = seesaw.moisture_read()

    # read temperature from the temperature sensor
    temp = seesaw.get_temp()

    if touch < MIN:
        if not LOW:
            io.publish("plant", touch)
            print("published")
        LOW = True

    elif touch >= MIN and time.time() - START > 10:
        io.publish("plant", touch)
        print("published to Adafruit IO")
        START = time.time()
        LOW = False

    print("temp: " + str(temp) + "  moisture: " + str(touch))
    time.sleep(1)

This guide was first published on Jun 02, 2021. It was last updated on May 24, 2021.

This page (Code Run-Through) was last updated on May 24, 2021.

Text editor powered by tinymce.