Science and technology

How I monitor my greenhouse with CircuitPython and open supply instruments

CircuitPython supplies a revolutionary method to work together with microcontroller boards. This article explains find out how to use CircuitPython to measure a greenhouse’s temperature, humidity, and ambient gentle and publish the outcomes to an MQTT dealer utilizing a CircuitPython MQTT consumer. You can subscribe any variety of packages to the MQTT queues to course of the data additional.

This mission makes use of a easy Python program that runs an internet server that publishes a Prometheus-formatted scrape endpoint and pulls these metrics into Prometheus for ongoing monitoring.

About CircuitPython

CircuitPython is an open supply Python distribution created by Adafruit to run on low-cost microcontroller boards. CircuitPython supplies a easy growth expertise for interacting with compatible boards. You can begin a program on the board by making a code.py file within the CIRCUITPYTHON root drive that mounts once you join your board. CircuitPython additionally supplies a serial connection out of your board that features an interactive read-evaluate-print loop (REPL) session that you should utilize to work together together with your board in actual time utilizing Python code.

Adafruit’s web site presents in depth documentation that will help you get began with CircuitPython. First, seek the advice of the Welcome to CircuitPython information. This will get you began working code in your microcontroller with CircuitPython and interacting with the REPL. It additionally paperwork find out how to set up Adafruit’s bundle of CircuitPython libraries and examples for most of the boards and sensors it sells. Next, learn the CircuitPython Essentials information to study extra about its capabilities and hyperlink to details about utilizing CircuitPython with particular, suitable boards. Finally, as with all open supply software program, you’ll be able to dig into CircuitPython’s code, publish points, and contribute.

Microcontroller setup

The microcontroller system may be very easy. To observe together with this demo, you will have:

  • Raspberry Pi four: You want a pc to program the microcontroller system, and that is what I used. 
  • A CircuitPython-compatible microcontroller: I used the Adafruit FeatherS2 with built-in WiFi, ambient gentle sensor, and Qwiic cable enter.
  • Microcontroller WiFi: The FeatherS2 has a built-in WiFi radio. If your microcontroller doesn’t, you will have to discover a WiFi enlargement board for it.
  • Sensors: The Feather S2 has a built-in ambient gentle sensor, so I wanted to get a temperature and humidity sensor. A range is obtainable from distributors, together with Adafruit, SparkFun, and Amazon. I used an Adafruit sensor with a Qwiic cable connection suitable with the Feather S2 enter. You could have to search out CircuitPython-compatible Python libraries for sensors not bought from Adafruit, though many SparkFun sensors work with Adafruit libraries.
  • Jumpers and cables: To keep away from utilizing a breadboard or soldering, I used an Adafruit Qwiic cable. SparkFun additionally sells them in a bundle of cables of various lengths.

Before plugging the microcontroller into your pc, join the sensors to the microcontroller.

Now you’ll be able to plug the microcontroller into your pc utilizing a USB information cable.

The MQTT Broker

You can use these instructions to put in the Mosquitto MQTT broker and Mosquitto shoppers on a Raspberry Pi four working Raspberry Pi OS. If you need to use the Raspberry Pi as a long-term server, set a static IP deal with for the Raspberry Pi four in your community. Once the Mosquitto dealer is working, create a user/password file that units the authentication parameters for shoppers to make use of when publishing and subscribing to the dealer.

You can check the MQTT dealer utilizing the Mosquitto shoppers on the Raspberry Pi. Open two terminals (or SSH classes in case you are working headless):

On Terminal 1, enter:

mosquitto_sub -h localhost -u $consumer -P $cross -t "mqtt/test"

This will begin a long-running course of that listens for messages revealed to the mqtt/check queue.

On Terminal 2, enter:

mosquitto_pub -h localhost -u $consumer -P $cross -t "mqtt/test" -m good day

This will publish a message to the mqtt/check queue, which ought to present up in Terminal 1’s output.

You can then kill the sub command working on Terminal 1.

The Mosquitto dealer permits shoppers to publish messages to any queue, even when it has no subscribers. These messages can be misplaced without end, however they won’t cease the consumer from publishing.

Start a 3rd terminal and subscribe to the next queues (the queues your microcontroller will publish messages to):

  • greenhouse/temperature
  • greenhouse/gentle
  • greenhouse/humidity

Code the microcontroller

You at the moment are able to code your microcontroller to publish its metrics to the MQTT dealer working in your Raspberry Pi four.

Adafruit has excellent documentation on utilizing the CircuitPython Library Bundle‘s libraries to attach your microcontroller to your WiFi router and get it publishing metrics to your MQTT dealer.

Install the next libraries, which the greenhouse monitor will use, into the CIRCUITPYTHON/lib listing. These are all obtainable within the Adafruit CircuitPython Library Bundle:

  • adafruit_bus_device: A Python bundle listing with a number of .mpy information (.mpy is a compressed Python file that saves house in your microcontroller)
  • adafruit_requests: A single .mpy file
  • adafruit_register: Another bundle listing
  • adafruit_minimqtt: Another bundle listing
  • adafruit_si7021: A single .mpy file that works with the temperature and humidity sensors

Once these libraries are put in, write the next into code.py within the CIRCUITPYTHON listing:

import time
import ssl
import socketpool
import wifi
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import board
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogIn
import adafruit_si7021
 
# Add a secrets and techniques.py to your filesystem that has a dictionary known as secrets and techniques with "ssid" and
# "password" keys together with your WiFi credentials. DO NOT share that file or commit it into Git or different
# supply management.
# pylint: disable=no-name-in-module,wrong-import-order
strive:
        from secrets and techniques import secrets and techniques
besides ImportError:
        print("WiFi secrets are kept in secrets.py, please add them there!")
        elevate
 
print("Connecting to %s" % secrets and techniques["ssid"])
wifi.radio.join(secrets and techniques["ssid"], secrets and techniques["password"])
print("Connected to %s!" % secrets and techniques["ssid"])
### Feeds ###
light_feed = "greenhouse/light"
temp_feed = "greenhouse/temperature"
humidity_feed = "greenhouse/humidity"
 
# Define callback strategies that are known as when occasions happen
# pylint: disable=unused-argument, redefined-outer-name
def related(consumer, userdata, flags, rc):
        # This operate can be known as when the consumer is related
        # efficiently to the dealer.
        print("Connected to MQTT!")
 
def disconnected(consumer, userdata, rc):
        # This methodology known as when the consumer is disconnected
        print("Disconnected from MQTT!")
 
 
def get_voltage(pin):
        return (pin.worth * three.three) / 65536
 
# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)
 
# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
        dealer=secrets and techniques["broker"],
        port=secrets and techniques["port"],
        username=secrets and techniques["aio_username"],
        password=secrets and techniques["aio_key"],
        socket_pool=pool,
        ssl_context=ssl.create_default_context(),
)
 
# Setup the callback strategies above
mqtt_client.on_connect = related
mqtt_client.on_disconnect = disconnected
 
# Connect the consumer to the MQTT dealer.
print("Connecting to MQTT...")
mqtt_client.join()
 
# Create library object utilizing our Bus I2C port
sensor = adafruit_si7021.SI7021(board.I2C())
light_pin = AnalogIn(board.IO4)
 
whereas True:
        # Poll the message queue
        mqtt_client.loop()
 
        # get the present temperature
        light_val = get_voltage(light_pin)
        temp_val = ((sensor.temperature * 9)/5) + 32
        humidity_val = sensor.relative_humidity
 
        # Send a brand new messages
        mqtt_client.publish(light_feed, light_val)
        mqtt_client.publish(temp_feed, temp_val)
        mqtt_client.publish(humidity_feed, humidity_val)
        time.sleep(zero.5)

Save your code. Then connect to the serial monitor and watch it hook up with your MQTT dealer. You can even see the output by switching to the terminals in your Raspberry Pi four subscribed to the queues the place this publishes.

Process the metrics

Publish/subscribe workflows like MQTT provide many benefits for microcontroller methods. You can have a number of microcontroller + sensor installations reporting completely different metrics about the identical system or reporting many readings of the identical metric in parallel. You can even have many various processes that subscribe to every queue to reply to these messages in parallel. It is even doable to have a number of completely different processes subscribed to the identical queue for various actions, reminiscent of sending an electronic mail when a price will get too excessive or publishing a message to a different MQTT queue.

Another choice is to have a microcontroller subscribe to an exterior queue that sends indicators to inform the microcontroller to carry out an motion, reminiscent of turning off or beginning a brand new session. Finally, pub/sub workflows will be higher for low-power microcontroller installations (reminiscent of these utilizing battery or solar energy) as a result of these gadgets can ship metrics in batches separated by lengthy delays and switch off the power-hungry WiFi radio through the intervals between stories.

To course of these metrics, I created a Python consumer that makes use of the Paho Python MQTT client to subscribe to the metrics queues. I additionally use the official Prometheus Python client to create an internet server that produces a Prometheus-compliant scrape endpoint with these metrics as gauges. I run this, a Prometheus server, and the Mosquitto MQTT dealer on the identical Raspberry Pi four.

from prometheus_client import start_http_server, Gauge
import random
import time
import paho.mqtt.consumer as mqtt

gauge =

strive:
        from mqtt_secrets import mqtt_secrets
besides ImportError:
        print("WiFi secrets are kept in secrets.py, please add them there!")
        elevate

def on_connect(consumer, userdata, flags, rc):
        print("Connected with result code "+str(rc))
        # Subscribing in on_connect() signifies that if we lose the connection and
        # reconnect then subscriptions can be renewed.
        consumer.subscribe("greenhouse/light")
        consumer.subscribe('greenhouse/temperature')
        consumer.subscribe('greenhouse/humidity')

def on_message(consumer, userdata, msg):
        subject = msg.subject
        payload = msg.payload
        gauge[subject].set(payload)

consumer = mqtt.Client()
consumer.username_pw_set(mqtt_secrets["mqtt_user"],mqtt_secrets['mqtt_password'])
consumer.on_connect = on_connect
consumer.on_message = on_message
consumer.join('localhost',1883,60)

if __name__ == '__main__':
        # Start up the server to reveal the metrics.

        consumer = mqtt.Client()
        consumer.username_pw_set('london','abc123')
        consumer.on_connect = on_connect
        consumer.on_message = on_message
        consumer.join('localhost',1883,60)

        start_http_server(8000)
        consumer.loop_forever()

Then I configure the Prometheus server to scrape that endpoint on localhost:8000.

You can entry all of the code for this mission in my MIT-licensed Greenhouse MQTT Microcontroller repository on GitHub.

Most Popular

To Top