Creating a Smart Pet Feeder with MQTT and Arduino

The Internet of Things (IoT) technology has enabled us to connect various devices around our homes. In this post, we are going to look at a simple IoT project, an automated pet feeder using an ESP8266 microcontroller and MQTT protocol. You can grab the full code here to follow along: https://github.com/ljmerza/cat-feeder

The MQTT is a machine-to-machine messaging protocol, designed for lightweight data transmission and is widely used in IoT applications.

Here’s the code breakdown:

Defining Constants and Variables

The following section of the code is dedicated to defining MQTT topics, credentials, and the pins for our motor, switch, and LED indicator.

// MQTT Topics
#define SET_TOPIC "petfeeder/feed"
#define SET_TOPIC_SUCCESS "petfeeder/feed/success"
#define SET_TOPIC_FAIL "petfeeder/feed/fail"

// Credentials
#define HOSTNAME "fetfeeder"
#define WIFI_SSID "Everyday Im Buffering"
#define WIFI_PASSWORD "thefoxjumpedoverthemoon"
#define MQTT_SERVER "192.168.1.76"
#define MQTT_PORT 1883

#define MOTOR_PIN D0
#define SWITCH_PIN D1
#define LED_PIN D7

Setting up WiFi and MQTT

The function setup_wifi is used to connect to the WiFi network, while the reconnect_mqtt function is for establishing a connection with the MQTT server.

void setup_wifi() {
    delay(10);

    // We start by connecting to a WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(WIFI_SSID);

    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

}

void reconnect_mqtt() {
    // Loop until we're reconnected
    while (!client.connected()) {
        // Attempt to connect
        if (client.connect(HOSTNAME, MQTT_USERNAME, MQTT_PASSWORD)) {
            Serial.println("connected");
            client.subscribe(SET_TOPIC);
        } else {
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}

Message Processing

The recieve_mqtt_message function is set as a callback function, which processes incoming messages. It parses the received JSON message to extract the number of scoops of food to dispense, operates the feeder, and then sends a success message.

void recieve_mqtt_message(char* topic, byte* payload, unsigned int length) {
    ...
    // run feeder and send success message
    run_feeder(root["scoops"]);
    client.publish(SET_TOPIC_SUCCESS, payload, true);
}

The Feeder Mechanism

The run_feeder function turns the motor on for a specific duration for each scoop, then turns it off.

void run_feeder(int scoopsOfFood) {
    digitalWrite(MOTOR_PIN, HIGH);
    for (int currentScoops = 0; currentScoops < scoopsOfFood; currentScoops++) {
        delay(100);
    }
    digitalWrite(MOTOR_PIN, LOW);
}

In essence, for each scoop, the motor is kept running for a brief period, after which it is stopped. This process is repeated as per the specified number of scoops.

Leave a Reply

Your email address will not be published. Required fields are marked *