Wiznet makers

ronpang

Published October 21, 2025 © Apache License 2.0 (Apache-2.0)

138 UCC

81 WCC

32 VAR

0 Contests

1 Followers

0 Following

Original Link

Environmental monitoring with Adafruit IO and MQTT

Smart air quality guard. Monitors toxins, temp, and humidity. Auto-fan cooling with real-time cloud alerts to keep your space safe.

COMPONENTS Hardware components

WIZnet - W6300-EVB-PICO2

x 1


PROJECT DESCRIPTION

Step 1: Gather Components

For this project, you will need:

  • W6300-EVB-PICO2 Microcontroller
  • Sensirion SFA30 Sensor
  • USB Fan
  • Breadboard and jumper wires
 
Components Needs

 

 

Step 2: Hardware Setup

W5100S-EVB-PICO2 - Reliable IoT Foundation

  • RP2350 dual Cortex-M33 (150MHz) + 520KB SRAM
  • 16MB flash + 16KB network buffers
  • 4 simultaneous sockets, IPv4 only
  • Essential security with OTP memory
  • Cost-effective for basic IoT applications

W6300-EVB-PICO2 - Advanced IoT Solution

  • Same powerful RP2350 core foundation
  • 64KB network buffers + 8 simultaneous sockets
  • IPv4/IPv6 dual stack support
  • Enhanced security with TrustZone + secure boot
  • Wake-on-LAN and advanced power management

Key Difference: The W6300 doubles socket capacity, adds IPv6 future-proofing, and enhances security - making it ideal for complex multi-connection applications, while the W5100S handles basic IoT tasks reliably.

W6300-EVB-PICO2

 

 

 

Connections

SFA30 Sensor

  • TX → GP0
  • RX → GP1

Fan Control Circuit

  • MOSFET Trigger PWM → GP2 (control signal)
  • MOSFET GND → Pico Board GND (shared ground)
  • MOSFET VIN → 5V power source
  • MOSFET VOUT → Fan

Ethernet

- Built-in RJ45 to network router

Circuit Diagram

Important: Double-check all connections for security and accuracy before powering on the board.

 

 

 

Step 3: Software Configuration

 

 

 

Setting Up Adafruit IO

Create Feeds:

  • Temperature feed
  • Humidity feed
  • Formaldehyde concentration feed

Design Dashboard:

  • Go to the Dashboard section to design your control interface, adding components like switches and color pickers
Dashboard Design
 
Feeds

 

 

 

Code Implementation

 

 

 

Import Required Libraries

  • digitalio: For controlling GPIO pins.
  • time: For delays in the code.
  • board: Accesses board-specific pin definitions.
  • busio: Handles serial communication (like SPI).
  • adafruit_dht: For interacting with DHT temperature and humidity sensors.
  • WIZnet Ethernet: Imports WIZnet library functions if the board is one of the specified Ethernet boards.
  • MQTT Libraries: These libraries are for communicating with Adafruit IO using the MQTT protocol.
import digitalio
import time
import board
import busio
import adafruit_dht

# WIZnet Ethernet support
if board.board_id in ("wiznet_w55rp20_evb_pico", "wiznet_w6300_evb_pico2"):
    import wiznet

from adafruit_wiznet5k.adafruit_wiznet5k import *
import adafruit_wiznet5k.adafruit_wiznet5k_socketpool as socketpool

# MQTT and Adafruit IO
from adafruit_io.adafruit_io import IO_MQTT
import adafruit_minimqtt.adafruit_minimqtt as MQT

 

 

 

Secrets Management

This dictionary stores your Adafruit IO credentials. You should create a separate secrets.py file to keep sensitive information secure.

secrets = {
    "aio_username": "YOUR_ADAFRUIT_IO_USERNAME",
    "aio_key": "YOUR_ADAFRUIT_IO_KEY"
}

 

 

 

Network Configuration

Defines the MAC address, static IP address, subnet mask, gateway, and DNS server addresses for network connectivity.

MY_MAC = "00:01:02:03:04:05"
IP_ADDRESS = (192, 168, 1, 100)  # Static IP configuration
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192, 168, 1, 1)
DNS_SERVER = (8, 8, 8, 8)

 

 

 

Hardware Initialization

  • Ethernet Configurations: Configures pins for Ethernet connectivity and resets the WIZnet module.
  • Initialize Ethernet: The WIZnet module is initialized using SPI, with DHCP enabled to get an IP address auomatically.
# Ethernet reset pin
ethernetRst = digitalio.DigitalInOut(board.W5K_RST)
ethernetRst.direction = digitalio.Direction.OUTPUT

# SPI configuration for Ethernet
cs = digitalio.DigitalInOut(board.W5K_CS)
spi_bus = busio.SPI(board.W5K_SCK, MOSI=board.W5K_MOSI, MISO=board.W5K_MISO)

# Reset W5x00
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True

# Initialize Ethernet
eth = WIZNET5K(spi_bus, cs, is_dhcp=True, mac=MY_MAC, debug=False)

 

 

 

SFA30 Sensor Setup

 

 

 

1. UART Setup

# SFA30 device using UART
SFA30 = busio.UART(board.GP0, board.GP1, baudrate=115200, bits=8, parity=None, stop=1)
  • UART Initialization: This line initializes the SFA30 sensor using UART (Universal Asynchronous Receiver-Transmitter) for serial communication.
  • Pin Definitions: board.GP0 and board.GP1 are used for TX and RX communication, respectively.
  • Baud Rate: Set to 115200 for fast data transmission.

 

 

 

2. Sensor Reset

# Reset sensor and wait for initialization
SFA_reset = bytearray([0x7E, 0x00, 0xD3, 0x00, 0x2C, 0x7E])
SFA30.write(SFA_reset)
print("Preparing SFA30 - waiting 10 seconds")
time.sleep(10)
  • Reset Command: The SFA_reset array contains a command to reset the SFA30 sensor. The command format typically includes start and end bytes (0x7E) and specific operation codes.
  • Waiting Period: After sending the reset command, the code waits for 10 seconds to ensure the sensor completes its initialization process. This is crucial for reliable readings.

 

 

 

3. Configuration Command

# Configuration command
SFA_config = bytearray([0x7E, 0x00, 0x00, 0x01, 0x00, 0xFE, 0x7E])
SFA30.write(SFA_config)
time.sleep(0.2)
  • Configuration Command: The SFA_config array contains the settings for the sensor to start measuring. Similar to the reset command, it includes start and end bytes.
  • Short Wait: A brief wait of 0.2 seconds is implemented after sending the configuration command to allow the sensor to process the settings before taking measurements.

 

 

 

Data Processing Functions

set_reading_values(recv_data) processes raw data from the sensor:

  • Checks for a valid response frame.
  • Extracts and converts raw values into meaningful measurements (formaldehyde, humidity, temperature).
def set_reading_values(recv_data):
    """Process raw sensor data and extract readings"""
    if len(recv_data) < 9 or recv_data[0] != 0x7E or recv_data[-1] != 0x7E:
        print("Invalid response frame")
        return None, None, None

    # Extract values from data frame
    formaldehyde_raw = (recv_data[3] << 8) | recv_data[4]
    humidity_raw = (recv_data[5] << 8) | recv_data[6]
    temperature_raw = (recv_data[7] << 8) | recv_data[8]
    
    # Convert to physical values
    formaldehyde = formaldehyde_raw / 5.0   # Scale by 5 ppb
    humidity = humidity_raw / 100.0         # Scale by 100 %RH
    temperature = temperature_raw / 200.0   # Scale by 200 °C

    return formaldehyde, humidity, temperature

get_reading_value: Sends a command to the sensor to request data, reads the response, and processes it using the set_reading_values function.

def get_sensor_readings():
    """Read data from SFA30 sensor"""
    SFA_get_data = bytearray([0x7E, 0x00, 0x03, 0x01, 0x02, 0xF9, 0x7E])
    SFA30.write(SFA_get_data)
    time.sleep(0.1)

    recv_data = bytearray()
    segmented_frame = SFA30.readline()

    while segmented_frame:
        recv_data.extend(segmented_frame)
        segmented_frame = SFA30.readline()

    return set_reading_values(recv_data)

 

 

 

Fan Control System

Initializes a pin to control a fan:

  • The control_fan function turns the fan on if the temperature exceeds 27°C.
# Set up digital output for fan control
fan_control = digitalio.DigitalInOut(board.GP2)
fan_control.direction = digitalio.Direction.OUTPUT

def control_fan(temperature):
    """Control fan based on temperature threshold"""
    if temperature > 27:  # Threshold set to 27°C
        fan_control.value = True
        print("Fan ON - Temperature above threshold")
    else:
        fan_control.value = False
        print("Fan OFF - Temperature normal")

 

 

 

MQTT Configuration

Socket Pool: Creates a socket pool for network communications.

  • MQTT Client: Initializes the MQTT client with broker details and credentials from the secrets dictionary.
# Socket pool for network connections
pool = socketpool.SocketPool(eth)

# MQTT Client setup
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    username=secrets["aio_username"],
    password=secrets["aio_key"],
    socket_pool=pool,
    is_ssl=False,
)

# Adafruit IO MQTT Client
io = IO_MQTT(mqtt_client)

# Feed definitions
temp_feed = secrets["aio_username"] + "/feeds/Temperature"
humi_feed = secrets["aio_username"] + "/feeds/Humidity"
form_feed = secrets["aio_username"] + "/feeds/Formaldehyde"
  • MQTT Callbacks: Define functions to handle MQTT events:
  • connected: Confirms connection to the broker.
  • disconnected: Notifies when disconnected.
  • message: Handles incoming messages.
  • publish: Logs when a message is successfully published.
# MQTT callback functions
def connected(client, userdata, flags, rc):
    print("Connected to MQTT broker!")

def disconnected(client, userdata, rc):
    print("Disconnected from MQTT broker!")

def message(client, topic, message):
    print(f"Received message on {topic}: {message}")

def publish(client, userdata, topic, pid):
    print(f"Published to {topic} with PID {pid}")
  • Callback Assignment: Links the previously defined callback functions to the MQTT client.
Connect to Broker: Attempts to connect to the MQTT broker, with a message printed to indicate the status.

# Assign callbacks
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message
mqtt_client.on_publish = publish

# Connect to MQTT broker
print("Connecting to MQTT broker...")
mqtt_client.connect()

 

 

 

Main Application Loop

  • Handles MQTT tasks.
  • Reads data from the SFA30 sensor.
  • If valid readings are obtained, it applies a calibration offset to the temperature and controls the fan.
  • Prints the sensor readings and publishes them to Adafruit IO
  • Waits for 3 seconds before the next reading.
temperature_offset = -5.0  # Calibration offset if needed

while True:
    mqtt_client.loop()  # Handle MQTT tasks
    
    readings = get_sensor_readings()
    
    if None not in readings:
        # Apply temperature calibration
        temperature = readings[2] + temperature_offset
        
        # Automatic fan control
        control_fan(temperature)
        
        # Print readings to console
        print("HCHO Concentration:", readings[0], "ppb")
        print("Humidity:", readings[1], "%")
        print("Temperature:", temperature, "°C")
        
        # Publish to Adafruit IO
        mqtt_client.publish(form_feed, readings[0])
        mqtt_client.publish(humi_feed, readings[1])
        mqtt_client.publish(temp_feed, temperature)
        
        # Blink LED to indicate successful reading
        led.value = True
        time.sleep(0.1)
        led.value = False
    else:
        print("Failed to retrieve valid sensor readings.")
    
    time.sleep(3)  # Wait 3 seconds between readings

 

 

 

Step 4: Features and Benefits

 

 

 

Real-time Monitoring

  • Continuous tracking of environmental parameters
  • Immediate fan activation when temperature exceeds 27°C
  • Live data streaming to Adafruit IO dashboard

 

 

 

Safety Features

  • Automatic temperature regulation
  • Formaldehyde level monitoring for air quality
  • Robust error handling for sensor communication

 

 

 

Data Visualization

  • Real-time gauges for current readings
  • Historical data charts for trend analysis
  • Remote monitoring from any device

 

 

 

Step 5: Applications

This system is perfect for:

Home environmental monitoring

Office air quality assessment

Laboratory safety systems

HVAC system integration

Smart greenhouse controls

 

 

 

Step 6: Video Demonstration

Coming Soon

 

 

 

Conclusion

This environmental monitoring system provides a comprehensive solution for environmental monitoring with real-time data transmission and automated control. The combination of the W6300-EVB-PICO2's reliable Ethernet connectivity and Adafruit IO's robust cloud platform creates a powerful IoT application that's both educational and practical.

The project demonstrates important IoT concepts including sensor integration, real-time data processing, MQTT communication, and automated control systems - making it an excellent learning platform for IoT enthusiasts and developers.

Documents
Comments Write