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.