First, the code imports the required libraries.
from os import getenv 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 settings.toml exists and then sets up the AirLift FeatherWing.
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
aio_username = getenv("ADAFRUIT_AIO_USERNAME")
aio_key = getenv("ADAFRUIT_AIO_KEY")
if None in [ssid, password, aio_username, aio_key]:
raise RuntimeError(
"WiFi and Adafruit IO settings are kept in settings.toml, "
"please add them there. The settings file must contain "
"'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', "
"'ADAFRUIT_AIO_USERNAME' and 'ADAFRUIT_AIO_KEY' at a minimum."
)
# ...
# 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_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password, status_pixel=status_pixel)
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=aio_username,
password=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)
Page last edited April 16, 2025
Text editor powered by tinymce.