Feed the birds via Internet using NodeMCU








We were looking for an idea of a weekend project and just asked ourselves why not connect directly to Mother Nature. Feeding the birds is nice and can attract them to your backyard. You enjoy hearing them singing for you and have less insects on your fruit trees in the summer.
Although building a fully automated birds feeder requires a very simple mechanics without any moving parts involved, enabling yourself to control the process via Internet transformed our idea to an interesting geeky gadget.
The idea was very simple – a reservoir with grain or other free-flowing food and a servo motor opening and closing an aperture in a food tank to allow a portion of food to fall into the feeder.
A NodeMCU was chosen to control the servo motor and receive commands using MQTT protocol.
Architecture
The below diagram illustrates the architecture of the feeder. The NodeMCU controlling the feeder is not directly exposed to Internet and is hosted in a home network behind a firewall. Both NodeMCU and end user can subscribe to certain topics and publish messages on MQTT Server which is exposed to Internet and can handle substantial load.
Hardware design
This project is not focusing on great hardware design so if you ever decide to build your own feeder use your creativity and available tools and materials.
Hot glue a round piece of plastic matching in size the nozzle of a plastic bottle to make a food dispenser
Cut off the tip from a plastic bottle
Using plastic ties mount a small servo motor which will move the shutter when a servo motor changes the angle
Mount the tip from a small bottle to a bigger one to make sure you have enough stock of food to be able to operate unattended for a few days
Cut big enough holes in a plastic bucket to allow birds comfortably sit in your feeder. Make sure your bucket has a lid which will cover the food tank and electronics from rain. A construction putty bucket is just perfect for this
Use some creativity, duct tape and couple of screws to mount your food tank and electronics under the roof of your feeder. Make sure you make your NodeMCU easy accessible or add a usb cable to your design in order to be able to reprogram your NodeMCU later. Assemble all together and your hardware part is done (watch the video, it shows more details)
Electronics
All you need is
- NodeMCU
- Small servo motor
- A 5v power supply with enough current to drive both NodeMCU and the servo
Connect servo motor as shown on the diagram below
The code below is a full program running on NodeMCU. It subscribes to an MQTT topic on cloud.iotalot.com and upon receiving a message it opens the shatter for small amount of time to supply a small portion of food
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | local WIFI_SSID = "YOURSSID" local WIFI_PASS = "YOURWIFIPASS" local mqtt_client = {} local MQTT_CLIENTID = "YOURMQTTCLIENTID" local MQTT_USER = "YOURUSER" local MQTT_PASS = "YOURUSERPASSWORD" local MQTT_TOPIC = "iotalot/YOURTOPICTOSUBSCRIBE" local MQTT_REPORT_TOPIC = "iotalot/sensors/YOURAPIKEY" local MQTT_ADDR = "cloud.iotalot.com" local MQTT_PORT = 8181 local inFeed = false local feederDelay = 150 local feederClosedPos = 77 local feederOpenPos = 120 local feederOutPin = 1 local tmrId = 0 local lastFeedTime = 0 local feedInterval = 10 pwm.setup(feederOutPin, 50, feederClosedPos) pwm.start(feederOutPin) function mqtt_report() r = mqtt_client:publish(MQTT_REPORT_TOPIC, "{\"message\": \"OK\"}", 0, 0) end tmr.register(tmrId, feederDelay, tmr.ALARM_SEMI, function() pwm.setduty(feederOutPin, feederClosedPos) mqtt_report() inFeed = false end) function feed() local time = tmr.now() if(time - lastFeedTime < feedInterval * 1000000) then if feedInterval - (time - lastFeedTime) / 1000000 > feedInterval then lastFeedTime = tmr.now() end print("Can feed in ", feedInterval - (time - lastFeedTime) / 1000000, " sec.") return end if inFeed then return end lastFeedTime = tmr.now() inFeed = true pwm.setduty(feederOutPin, feederOpenPos) tmr.start(tmrId) end function mqtt_feeder_subscribe(client) client:subscribe(MQTT_TOPIC, 0, function(client) print("subscribe success") end) end function init_mqtt_client() -- init mqtt client with keepalive timer 120sec mqtt_client = mqtt.Client(MQTT_CLIENTID, 60, MQTT_USER, MQTT_PASS) mqtt_client:on("message", function(client, topic, data) print("Message: ", data) if data == 'feed' then feed() end end) mqtt_client:connect(MQTT_ADDR, MQTT_PORT, 0, 1, mqtt_feeder_subscribe, function(client, reason) print("failed reason: "..reason) end) end function wait_for_wifi_conn ( ) tmr.alarm (1, 1000, 1, function ( ) if wifi.sta.getip ( ) == nil then print ("Waiting for Wifi connection") else tmr.stop (1) print ("The mode is: " .. wifi.getmode ( )) print ("The module MAC address is: " .. wifi.ap.getmac ( )) print ("Config done, IP is " .. wifi.sta.getip ( )) -- creating the mqqt client init_mqtt_client() end end) end -- Configure the ESP as a station (client) wifi.setmode (wifi.STATION) wifi.sta.config (WIFI_SSID, WIFI_PASS) wifi.sta.autoconnect (1) -- Hang out until we get a wifi connection before the httpd server is started. wait_for_wifi_conn ( ) |
Have questions? Just write them in the comment to this article.
There are no many birds visiting the feeder at this time. We think it will be heavily used during winter period when birds can hardly find any insect or other natural food.
In the next article – how to organize video broadcast with Raspberry Pi 3 and an ordinary USB Webcam.
To get update follow us on Twitter or like our Facebook Page.







