Saved my Petnet smart feeder with a NodeMCU

After Petnet went belly up and left everyone stranded, I kept thinking to myself I need to integrate this and get it smart again. Using the magic of nodemcu and HubDuino I have now made this a reality.

If anyone else is in this same boat, or want to pick up a cheap one from eBay, feel free to follow my guide below.

The button on the device is optional, and my instructions will include it. If you don't care about using the button on the device, just skip those steps.

Perform this at your own risk as YMMV. I'm not responsible if you break anything or shock yourself on low voltage.

.================.
ITEMS YOU'LL NEED
.================.

.================.
THE CODE
.================.
Load the following code into your NodeMCU. Be sure to update the WiFi details and IP Address info for your local network

Summary

//******************************************************************************************
// File: ST_Anything_Multiples_ESP8266WiFi.ino
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
//
// Summary: This Arduino Sketch, along with the ST_Anything library and the revised SmartThings
// library, demonstrates the ability of one NodeMCU ESP8266 to
// implement a multi input/output custom device for integration into SmartThings.
// The ST_Anything library takes care of all of the work to schedule device updates
// as well as all communications with the NodeMCU ESP8266's WiFi.
//
// ST_Anything_Multiples implements the following ST Capabilities as a demo of what is possible with a single NodeMCU ESP8266
// - 1 x Alarm device (using a simple digital output)
// - 1 x Contact Sensor devices (used to monitor magnetic door sensors)
// - 1 x Switch devices (used to turn on a digital output (e.g. LED, relay, etc...)
// - 1 x Motion devices (used to detect motion)
// - 1 x Smoke Detector devices (using simple digital input)
// - 1 x Temperature Measurement devices (Temperature from Dallas Semi 1-Wire DS18B20 device)
// - 1 x Relay Switch devices (used to turn on a digital output for a set number of cycles And On/Off times (e.g.relay, etc...))
// - 2 x Button devices (sends "pushed" if held for less than 1 second, else sends "held"
// - 1 x Water Sensor devices (using the 1 analog input pin to measure voltage from a water detector board)
//
// Change History:
//
// Date Who What
// ---- --- ----
// 2015-01-03 Dan & Daniel Original Creation
// 2017-02-12 Dan Ogorchock Revised to use the new SMartThings v2.0 library
// 2017-04-17 Dan Ogorchock New example showing use of Multiple device of same ST Capability
// used with new Parent/Child Device Handlers (i.e. Composite DH)
// 2017-05-25 Dan Ogorchock Revised example sketch, taking into account limitations of NodeMCU GPIO pins
// 2018-02-09 Dan Ogorchock Added support for Hubitat Elevation Hub
//
//******************************************************************************************
//******************************************************************************************
// SmartThings Library for ESP8266WiFi
//******************************************************************************************
#include <SmartThingsESP8266WiFi.h>

//******************************************************************************************
// ST_Anything Library
//******************************************************************************************
#include <Constants.h> //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library
#include <Device.h> //Generic Device Class, inherited by Sensor and Executor classes
#include <Executor.h> //Generic Executor Class, typically receives data from ST Cloud (e.g. Switch)
#include <Everything.h> //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications

#include <EX_Switch.h> //Implements an Executor (EX) via a digital output to a relay
#include <IS_Button.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin for button presses

//*************************************************************************************************
//NodeMCU v1.0 ESP8266-12e Pin Definitions (makes it much easier as these match the board markings)
//*************************************************************************************************
//#define LED_BUILTIN 16
//#define BUILTIN_LED 16
//
//#define D0 16 //no internal pullup resistor
//#define D1 5
//#define D2 4
//#define D3 0 //must not be pulled low during power on/reset, toggles value during boot
//#define D4 2 //must not be pulled low during power on/reset, toggles value during boot
//#define D5 14
//#define D6 12
//#define D7 13
//#define D8 15 //must not be pulled high during power on/reset

//******************************************************************************************
//Define which Arduino Pins will be used for each device
//******************************************************************************************
#define PIN_SWITCH_1 D0 //SmartThings Capability "Switch"
#define PIN_BUTTON_1 D2 //SmartThings Capabilty Button / Holdable Button (Normally Open!)

//******************************************************************************************
//ESP8266 WiFi Information
//******************************************************************************************
String str_ssid = "YOUR_SSID"; // <---You must edit this line!
String str_password = "YOUR_PASSWORD"; // <---You must edit this line!
IPAddress ip(192, 168, X, X); //Device IP Address // <---You must edit this line!
IPAddress gateway(192, 168, X, X); //Router gateway // <---You must edit this line!
IPAddress subnet(255, 255, 255, 0); //LAN subnet mask // <---You must edit this line!
IPAddress dnsserver(192, 168, X, X); //DNS server // <---You must edit this line!
const unsigned int serverPort = 8090; // port to run the http server on

// Smarthings Hub Information
//IPAddress hubIp(192, 168, 1, 149); // smartthings hub ip // <---You must edit this line!
//const unsigned int hubPort = 39500; // smartthings hub port

// Hubitat Hub Information
IPAddress hubIp(192, 168, X, X); // hubitat hub ip // <---You must edit this line!
const unsigned int hubPort = 39501; // hubitat hub port

//******************************************************************************************
//st::Everything::callOnMsgSend() optional callback routine. This is a sniffer to monitor
// data being sent to ST. This allows a user to act on data changes locally within the
// Arduino sktech.
//******************************************************************************************
void callback(const String &msg)
{
// Serial.print(F("ST_Anything Callback: Sniffed data = "));
// Serial.println(msg);

//TODO: Add local logic here to take action when a device's value/state is changed

//Masquerade as the ThingShield to send data to the Arduino, as if from the ST Cloud (uncomment and edit following line)
//st::receiveSmartString("Put your command here!"); //use same strings that the Device Handler would send
}

//******************************************************************************************
//Arduino Setup() routine
//******************************************************************************************
void setup()
{
//******************************************************************************************
//Declare each Device that is attached to the Arduino
// Notes: - For each device, there is typically a corresponding "tile" defined in your
// SmartThings Device Hanlder Groovy code, except when using new COMPOSITE Device Handler
// - For details on each device's constructor arguments below, please refer to the
// corresponding header (.h) and program (.cpp) files.
// - The name assigned to each device (1st argument below) must match the Groovy
// Device Handler names. (Note: "temphumid" below is the exception to this rule
// as the DHT sensors produce both "temperature" and "humidity". Data from that
// particular sensor is sent to the ST Hub in two separate updates, one for
// "temperature" and one for "humidity")
// - The new Composite Device Handler is comprised of a Parent DH and various Child
// DH's. The names used below MUST not be changed for the Automatic Creation of
// child devices to work properly. Simply increment the number by +1 for each duplicate
// device (e.g. contact1, contact2, contact3, etc...) You can rename the Child Devices
// to match your specific use case in the ST Phone Application.
//******************************************************************************************
//Interrupt Sensors
static st::IS_Button sensor1(F("button1"), PIN_BUTTON_1, 1000, HIGH, true, 500);

//Executors
static st::EX_Switch executor1(F("switch1"), PIN_SWITCH_1, LOW, false); //Inverted logic for "Active Low" Relay Board

//*****************************************************************************
// Configure debug print output from each main class
// -Note: Set these to "false" if using Hardware Serial on pins 0 & 1
// to prevent communication conflicts with the ST Shield communications
//*****************************************************************************
st::Everything::debug=true;
st::Executor::debug=true;
st::Device::debug=true;
st::InterruptSensor::debug=true;

//*****************************************************************************
//Initialize the "Everything" Class
//*****************************************************************************

//Initialize the optional local callback routine (safe to comment out if not desired)
st::Everything::callOnMsgSend = callback;

//Create the SmartThings ESP8266WiFi Communications Object
//STATIC IP Assignment - Recommended
st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, ip, gateway, subnet, dnsserver, serverPort, hubIp, hubPort, st::receiveSmartString);

//DHCP IP Assigment - Must set your router's DHCP server to provice a static IP address for this device's MAC address
//st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, serverPort, hubIp, hubPort, st::receiveSmartString);

//Run the Everything class' init() routine which establishes WiFi communications with SmartThings Hub
st::Everything::init();

//*****************************************************************************
//Add each executor to the "Everything" Class
//*****************************************************************************
st::Everything::addSensor(&sensor1);
st::Everything::addExecutor(&executor1);

//*****************************************************************************
//Initialize each of the devices which were added to the Everything Class
//*****************************************************************************
st::Everything::initDevices();

}

//******************************************************************************************
//Arduino Loop() routine
//******************************************************************************************
void loop()
{
//*****************************************************************************
//Execute the Everything run method which takes care of "Everything"
//*****************************************************************************
st::Everything::run();
}

.================.
INSTRUCTIONS
.================.
First, you need to pop off the outer shell. All you need is a small pry bar, go into the 4 holes on the bottom, push out and lift up.

Now that the shell is off, you'll be greeted by a bunch of wires, nothing to be scared of, just don't break any of them.


On the board, the wires will be as follows. To control it, all you'll need are the Power Source and Motor, I decided to use the Push Button as well to help keep old functionality.

Each of these harnesses can be pulled out and connected directly.

Since the NodeMCU only puts out 3.3V, I used the relay to trigger from the output pin, and pass 5V to the motor to operate.


If you don't care about using the button, it's straight forward (red = positive, black = negative). If you do care about using the button, we'll be using the brown and yellow wires.

Lastly just wire everything up and you'll be good to go.

UPDATE: Connect to D1 and update the code to use D1 to prevent the relay from triggering on bootup. Thanks @SteveZed . i'm not updating the original code to correspond to the wiring diagram above
.================.
CHANGES IN HUBITAT
.================.
To prevent the smart feeder from continuously dispensing food when triggered, I created a rule to turn off the switch after 1 second of it turning on. This turn off time can be adjusted to accommodate more food for your pet.

Since I am using the button, I also created a simple automation to turn the switch on the switch when the button gets pressed.

.================.
PROFIT
.================.
You too can save old hardware by using arduino boards and a little bit of exploration.

5 Likes

NodeMCU’s are very handy using them as a garage door opener, monitoring my alarm system, controlling seven RF fans and saving and automating a broken child’s nightlight.

1 Like

That’s scary. How does your broken child feel about being automated?

3 Likes

Great post :slight_smile:
If you ever want to move from WiFi to zigbee you can use one of these;

SmartThings Shield

I've used one already to monitor my furnace. For your project I don't think you will even need the arduino, just the cc2530 board. They work great.

1 Like

This is my first experience with a NodeMCU I plugged it into my computer with a USB cable and saw it show up as com3 and downloaded the arduino ide then in board manager I installed the esp8266 board package and saw them all show up. I then pasted the code above into a new IDE window and modified the IP info and other settings like Hub IP and saved then when I tried to send the code to the board it said #include expects "FILENAME" or And it seems to be talking about the #include <IS_Button.h> line. Not sure what I need to do here, hopefully someone can tell me where I went wrong.

Thanks.

Did you include all the ST_Anything libraries on your local machine for Arduino IDE to reference?

1 Like

I just noticed that I was supposed to download the libraries, is there a way to download a bunch of files at once? All I'm seeing Is the code and no download option on github.

I finally figured out I could download a zip at the root. Got the libraries downloaded now. And it compiled now. Thanks.

2 Likes

@dadarkgtprince I was confused by the button going to power but it seems you'r using that plus the 10k resistor to drop the voltage to the D2 input on press so it can dispense a certain amount on button push? Sorry it's been too many years since I had an electronics class and haven't done much with electrical components at this level since.

Thanks.

I followed the button wiring from Control LED Using PushButton With NodeMCU : 6 Steps (with Pictures) - Instructables, test it with a push button. Once it was working, I just replaced the push button with the button from the Petnet feeder

1 Like

My Petnet is the Gen2 so it’s a little different, although similar.


The Button connector is 10 wires instead of 8 and the actual button wires are the brown and red next to each other.

I should have opened it ahead of time to make sure I was ordering the right connectors I got the two position 2.0mm JST-PH connectors which will be plug and play but I ordered only the eight position so I just ordered a box with 8,9, and 10 position connectors so they won’t be here until Monday.
It also came apart differently there is a false bottom that just pops off then there are four screws to remove. You will need a T10 screwdriver for these screws.

Here is the 2.0mm JST-PH connector

I bought a 32 position socket since I couldn't find a 30 position one, the ones I found weren't wide enough either so i just cut the supports to spread it to the right width, this way I can replace the ESP8266 if necessary and I didn't have to solder directly to it taking a chance at heating a pin to much.

It fit perfectly on the botton of the feeder so I used double sided tape to stick it in place.

1 Like

awesome work on the gen2. i was too lazy to get a pcb for mine, i just used a solderless breadboard and some jumper wires xD

@dadarkgtprince You don't happen to have a better picture of your breadboard with it all wired do you?

Mine is all ready except the connector for the button and I bought a socket for the ESP8622 so if I ever need to replace the ESP8622 I can without unsoldering anything. Both the socket and 10 pin JST-PH connector should be here Monday.

i don't have a better pic of the breadboard, and it's full of food so i don't feel like having to pull it apart to take the pic, sorry. honestly my breadboard is a mess because i didn't cut wires to size, i used premade jumpers, so there was tons of slack on them

is the final pic of the wiring diagram not sufficient?

1 Like

No it's fine i was still just trying to wrap my head around the switch thing. I looked at that link you got it from and he mentioned the switch being connected to 3.3v but he had it connected to the VIn pin which should be 5v like your diagram shows so I was just looking to verify that piece before I soldered them, but I just soldered the wires like your diagram so it's ready when the 10 pin connector is here. I'll post a finished picture when I'm done.

By the way the Petnet didn't adjust to standard time when Daylight time finished last weekend so feedings are off an hour now so it will be nice to have more control over it again.

Thanks!

@dadarkgtprince Thanks again, it's working great so far. That 10pin JST-PH connector doesn't use standard PCB spacing but luckily I only really needed the first two pins because i had to bend over a few of the others to get the spacing right, i soldered in as many as I could to hold the connector in place well. I updated my previous post with finished pictures. Does your relay engage for a split second when you first apply power too?

1 Like

awesome, glad your feeder is back up. in regards to the connector, i was just being lazy, but you could always strip the wires and connect that directly since we're no longer using the board on the feeder

yea, when i first apply power, it does for like a second

Yeah i could have soldered all the wires directly but it was more fun tracking down the right connectors and making it so it could easily be switched back to the original board eventhough in this circumstance there is no chance the Petnet service will come back online.

This is happening because the particular pin you chose to run the relay (D0) goes high when the NodeMCU boots up. If you had chosen D1, that would not happen. See below for the behavior of pins on NodeMCU boot:

4 Likes

Great tutorial! I had the same idea and it was really helpful. I was going to use esphome on the nodemcu
Petnet v1 also has an optical sensor going accross the food drum, have you tried integrating this too? I guess it gives a low food alert?

1 Like