My Pet Bird Water Monitoring via Telegram App

Monitors the bird's water consumption and alerts you via Telegram instant messenger when the water level drops to low.
3h 0m
11× print file
0.20 mm
0.25 mm
0.40 mm
76.00 g
Prusa MK3.9S
5
2
0
69
updated April 21, 2025

Description

PDF

Description

To ensure the timely replenishment of my pet bird, Peanut’s, water supply, I devised an electronic project.  Previously, I would often forget to check on Peanut due to his ability to go days without water. This project aims to provide me with real-time notifications when Peanut requires water.

Function

The project serves as an automatic watering system for Peanut.  When Peanut’s water level gets low he stops moving, and the system triggers a message via the Telegram application. Additionally, Peanut emits peeping sounds to indicate its water need.

The primary communication mechanism is implemented using an Arduino Nano 33 ioT micro-controller.  While a water level sensor could have been employed, I opted against its use due to its size and potential interference with Peanut’s water tray. Instead, I strategically placed small wires near Peanut’s pivot point.  When these wires come into contact with Peanut’s body, the program interprets this as movement, indicating that Peanut has water in the tray.  Upon ceasing movement, the program triggers a message, prompting me to refill Peanut’s water supply.

An alternative approach involves utilizing an ESP8266MOD WiFi (WEMOS D1 MINI) module.  I have provided the code, hardware list, and STL files for constructing this project as well. Compared to the Arduino-based system, I found the ESP8266MOD to be more user-friendly.

Furthermore, I have included STL files for a bird cage, as pet birds typically reside in cages. While this feature was not necessary for my bird, it may be beneficial for others.

Hardware Used

  • Arduino Nano 33 ioT
  • Power TRC Magic Drinking Bird
  • DC3V 80 db Buzzer (Passive)
  • 30 AWG single core wire. About 1 yard.
  • Breadboard with 400 Tie Points (can use smaller breadboard)
  • Several Dupont wire pins for use on breadboard
  • USB-A to Micro USB Cable
  • USB Wall Charger (I used an old 5V iPhone charger)
  • PLA filament
  • Water glass (size: 82mm x 105mm, but any size similar will work).

Wiring Diagram

Please note that I lack formal training in electronic design or micro-controller programming, so any errors in design or implementation should be forgiven.

Program Code

The following Arduino code was utilized to program the Nano 33 ioT device.

The Nano monitors the bird via wires that extend up the bird’s legs.  When the bird swings back against the wire, an electrical contact is established. This indicates to the program that the bird is still dipping into the water.  If the bird ceases to dip for more than five minutes, the program emits a beeping sound through the passive buzzer.  Subsequently, it transmits the message “bird requires water” to my phone via the internet and the Telegram application. Additionally, the program generates a low chirp after every three dips to indicate its continued functionality.  This feature can be easily disabled by commenting out the corresponding section of the code.

For a comprehensive example of integrating the Telegram application with the Arduino, refer to the following link.

https://github.com/cotestatnt/AsyncTelegram2/blob/master/examples/echoBot_wifiNINA/echoBot_wifiNINA.ino

Please ensure that you upload the SSL certificate “api.telegram.org” as mentioned in the aforementioned example.  This certificate must be imported into the Arduino IDE prior to uploading your code to the Nano.

// Program: Bird_Monitor_Using_Nano_33_ioT

#include <SPI.h>
#include <WiFiNINA.h>
#include <AsyncTelegram2.h>

WiFiSSLClient client;
AsyncTelegram2 myBot(client);

const char* ssid  =  "NetworkName";     // SSID WiFi network
const char* pass  =  "NetworkPassword";     // Password  WiFi network
const char* token =  "TelegramToken";  // Telegram token
int64_t userid    =  "TelegramUserid;

int speaker       = 8;  // Nano pin # 26
int birdsignalpin = 2;  // Nano pin # 20

int loud   = 1; // Loud sounds from buzzer
int soft   = 0; // soft sounds from buzzer

int status = WL_IDLE_STATUS;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period    = 300000; // 5 minutes interval
const unsigned long shortbeep = 51000; // 51 second interval

void printWiFiStatus() {
  Serial.print("Connected to wifi. ");
  Serial.print("SSID: ");
  Serial.print(WiFi.SSID());
}

void callForWater(int volume) {  // bird chirp routine
  if (volume == loud) {
      for (int j = 1; j <= 2; j++) {
        for (int i = 2600; i <= 2700; i = i + 50) {
          tone(speaker,i); delay(20); noTone(speaker); 
        }
        tone(speaker,2600); delay(20); noTone(speaker);
      } 
  } else {
      for (int j = 1; j <= 2; j++) {
        for (int i = 2000; i <= 2200; i = i + 50) {
          tone(speaker,i); delay(20); noTone(speaker); 
        }
        tone(speaker,2000); delay(20); noTone(speaker);
      } 
  }
}

void setup() {

  // init and wait for serial port to connect (needed for native USB port)
  Serial.begin(115200);
  while (!Serial && millis() < 5000) {;} 

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    while (true); // don't continue
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  printWiFiStatus();

  Serial.print("\nStarting TelegramBot... ");
  // Set the Telegram bot properies
  myBot.setUpdateTime(2000);
  myBot.setTelegramToken(token);

  // Set the JSON buffer size for receeved message parsing (default 1024 bytes)
  myBot.setJsonBufferSize(1024);

  // Check if all things are ok
  Serial.print("Test Telegram connection... ");

  myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

  // Send a message to specific user who has started your bot
  myBot.sendTo(userid, "Nano Peanut monitoring starts");

  pinMode(speaker,OUTPUT);
  pinMode(birdsignalpin,INPUT);
  
  startMillis = millis();
}

void loop() {
 
  currentMillis = millis();
  if (currentMillis - startMillis >= period) { // bird has stopped  
    myBot.sendTo(userid, "Peanut needs water");  // Tell Telegram bird needs water  
    for (int i = 1; i <= 5; i++) { callForWater(loud); delay(250);  }  
    startMillis = millis();
  }

// Comment this out unless you want the bird to chirp once after 3 dips in the water
  if (digitalRead(birdsignalpin) == 1) {  // movement detected
    if (currentMillis - startMillis >= shortbeep) {  // timing of beep sound
      callForWater(soft);
      startMillis = millis();    
      // myBot.sendTo(userid, "bird movement");
    }
  }
// end of Comment this out...

}

Printing Instructions

The stl files for 3D printing the required project are located in the folder “Arduino Nano.” Additional folders contain files for printing a bird cage, if desired, and for using a microprocessor other than the Arduino Nano.

  • Material used: PLA
  • Layer Height 0.2mm
  • Infill 15%
  • Supports not needed

Assembly Instructions

Attach the two wires from the Nano to the inside legs of the bird.  Wrap each wire as depicted in the accompanying photograph.

 

Demo and usage instructions

 

Click on the link below to view a short clip of Peanut drinking its water.

https://youtu.be/GZwpu31_KLs

Additional Notes and Tips

For this project, it is recommended to use distilled water exclusively.  Tap water may lead to mineral buildup on the bird’s head due to dissolved minerals.  A water sensing circuit is not recommended as its operation with distilled water was not reliable.  

Cage Add On

If you would like to keep your bird in a cage, I've provided bird cage files that you can print.  

Alternative Micro Controller

The Nano 33 ioT may present programming challenges, so an alternative is provided.  The ESP8266MOD WiFi (WEMOS D1Mini) is a more suitable option due to its ease of programming.  The following code demonstrates programming the ESP, and an alternative set of print files is available in the ESP8266MOD folder.

ESP8266 Code

 // Mr_Peanut_chirping_V2 using ESP8266MOD (Board: "LOLIN(WEMOS) D1 R2 & Mini")
 
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>

int speaker = D2;        // pin on the ESP8266MOD board
int birdsignalpin = D8;  // pin  on ESP8266MOD board
int i;

int loud   = 1; // Loud sounds from buzzer
int soft   = 0; // soft sounds from buzzer

const unsigned long period    = 300000; // 5 minutes interval
const unsigned long shortbeep = 51000; // 51 second interval
 
// Wifi network station credentials
const char* ssid     = "NetworkName";
const char* password = "NetworkPassword";

// Initialize Telegram BOT
#define BOTtoken "TelegramTokin"
#define CHAT_ID "TelegramUserID"

#ifdef ESP8266
  X509List cert(TELEGRAM_CERTIFICATE_ROOT);
#endif

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
 
unsigned long startMillis;
unsigned long currentMillis;

void callForWater(int volume) {  // bird chirp routine
  if (volume == loud) {
      for (int j = 1; j <= 2; j++) {
        for (int i = 2600; i <= 2700; i = i + 50) {
          tone(speaker,i); delay(20); noTone(speaker); 
        }
        tone(speaker,2600); delay(20); noTone(speaker);
      } 
  } else {
      for (int j = 1; j <= 2; j++) {
        for (int i = 2000; i <= 2200; i = i + 50) {
          tone(speaker,i); delay(20); noTone(speaker); 
        }
        tone(speaker,2000); delay(20); noTone(speaker);
      } 
  }
}
  
void setup() { 
  
  Serial.begin(115200);

  #ifdef ESP8266
    configTime(0, 0, "pool.ntp.org");
    client.setTrustAnchors(&cert);
  #endif

// Connect to Wi-Fi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  #ifdef ESP32
    Client.setCACert(TELEGRAM_CERTIFICATE_ROOT);
  #endif

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000); Serial.println("Connecting to WiFi..");
  }
  Serial.println(WiFi.localIP());  // Print ESP8266 local IP Address

  bot.sendMessage(CHAT_ID, "ESP Peanut monitoring starts", "");

  pinMode(speaker,OUTPUT); //initialize the buzzer pin as an output
  pinMode(birdsignalpin, INPUT); 
  startMillis = millis(); 
}

void loop() {
  currentMillis = millis();
  if (currentMillis - startMillis >= period) // bird has stopped
  { 
    bot.sendMessage(CHAT_ID, "Peanut needs water", "");  // Tell Telegram bird needs water 
    for (int i = 1; i <= 5; i++) { callForWater(loud); delay(250); }
    startMillis = millis();
  }
  
// Comment this out unless you want the bird to chirp once after 3 dips in the water
  if (digitalRead(D8) == 1) {  // movement detected
    if (currentMillis - startMillis >= shortbeep) {  // timing of beep sound
    callForWater(soft);
      startMillis = millis();
      // bot.sendMessage(CHAT_ID, 'bird movement"); 
    }
  }
// end of Comment this out...
}

Photos of the ESP8266 version

The water container was printed in PETG, with an infill of 100%.  I never found it to leak using 100% infill.

 

Additional Notes

If you wish to add the additional tall water container, it can be purchased from Amazon.  The specific product is Berenti 20 PCS Plastic Test Tubes with Caps (115 ml) - 1.2×7.4 Inches/30×188 mm Gumball Tubes.

The connector used for connecting the DC input was also sourced from Amazon:  NFHK DIY OEM 5pcs/Set Type C Female Socket to 2Pin Header Cable Pitch=2.0mm Panel Mount Type DC 5V Power.

The quick wire connectors utilized were also obtained from Amazon:  100Pcs 2P CH2 + 3P CH3 Quick Connector Spring Wire Connector Screw Terminal Barrier Block for LED Strip Light Wire Connecting.

I have calculated how much water Peanut consumes.  Over an 8 day period Peanut consumed an average of 0.943 mL per hour of water.  With each dip it consumed an average of 0.004751 mL of water.  Some of the factors affecting the results were humidity, temperature, air currents, etc.  At various times during the day it would dip faster, or slower. I obtained these results by accurately measure the amount of water he started and ended with.  I devised temporary code in the program to monitor its rate of dipping, and times dipped.

Suggested enhancements

  • Utilize the Telegram application to silence the sound.
  • Enhance the bird sounds.
  • Monitor the water usage and post the data to Telegram.
  • Estimate the time and date when the water supply will be exhausted, and send that info to Telegram.

 

Tags



Model origin

The author marked this model as their own original creation.

License