I am making a Cat feeder, but I am quite new on this field. Can somebody help me out? The problem I am facing with is Blynk shows that the device is offline, but my ESP8266 is well connected to the WiFi . I couldn’t find out the problem source… The board I am using is ESP8266 v3. Andriod and Blynk are at their latest version.
heres the code :
#include <Servo.h>
#define BLYNK_TEMPLATE_ID "TMPL6UI7rTJkz"
#define BLYNK_TEMPLATE_NAME "Cat Feeder"
#define BLYNK_AUTH_TOKEN "***"
#include <BlynkSimpleEsp8266.h>
Servo myservo;
int FeedStatus;
void setup() {
myservo.attach(2); // GPIO pin 2 = D4
myservo.write(0);
Serial.begin(115200);
WiFi.begin("HUAWEI-B315-ADEF" , "***");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("WiFi Connected");
Blynk.begin(BLYNK_AUTH_TOKEN, "HUAWEI-B315-ADEF" , "***");
Blynk.connect();
Serial.println("Blynk Connected");
}
void GiveFood() {
myservo.write(180);
delay(1000); // Add a delay to stay at 180 degrees for a second
// Exit the loop after one complete 180-degree movement
while (true) {
delay(1000);
}
}
void loop() {
Blynk.run();
if (FeedStatus == 1) {
GiveFood();
Blynk.virtualWrite(V0, 0);
FeedStatus = 0;
delay(2000);
}
}
// Read datastream on B.lynk
BLYNK_WRITE(V0) {
FeedStatus = param.asInt();
}
please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly. Triple backticks look like this: ```
I see … it seems like the void loop part should be as clean as possible but is this a new thing ? because the Youtuber that shared this code did not keep its void loop part clean but still works pretty well .
No, not at all. It’s one of the basic concepts of good Blynk programming and the article about it is at least 5 years old.
Just because someone publishes something on a Youtube channel doesn’t make them a good programmer.
The code is a complete mess for a variety of reasons…
It’s missing #include <ESP8266WiFi.h>
It manually creates the WiFi connection (via WiFi.begin()) then uses Blynk.Begin() - which creates a WiFi connection anyway, then uses Blynk.connect() which isn’t relevant when Blynk.behin() is used. these lines of code…
could all be replaced with…
Not only is the stuff in the void loop() bad practice in terms of Blynk programming, it’s totally unnecessary anyway. THis could all be removed…
I don’t do much with servos, but I seriously have my doubts about the commands that are being used to actuate the servo.
Pet feeder projects are quite popular on this forum, and if you do some searching you’ll find quite some recent examples that are far more sophisticated than this, with feeding schedules and well-written code.
I tried to fix it by following your instructions , still not able to connect with Blynk .In the Serial Monitor it says that i am facing a Soft WDT Reset , not sure what it is .
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define BLYNK_TEMPLATE_ID "TMPL6UI7rTJkz"
#define BLYNK_TEMPLATE_NAME "Cat Feeder"
#define BLYNK_AUTH_TOKEN "***"
Servo myservo;
int FeedStatus = 0; // Initialize the variable
void setup() {
myservo.attach(2); // GPIO pin 2 = D4
myservo.write(0);
Serial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, "HUAWEI-B315-ADEF", "***");
}
void GiveFood() {
myservo.write(180);
delay(1000); // Add a delay to ensure the servo has enough time to move
// Additional actions if needed
delay(1000); // Add a delay after the servo movement
myservo.write(0); // Return the servo to the initial position
}
void loop() {
Blynk.run();
}
BLYNK_WRITE(V0) {
GiveFood();
Blynk.virtualWrite(V0, 0);
}
It’s a WatchDog Timer issue.
Difficult to say without seeing the actual serial output (Copy the text and paste it with triple backticks the same way that you do with code.
The serial output might be more understandable if you change this line…
Alright, I will do it later. My laptop just ran out of battery. By the way, is it possible to make a hybrid one? Like adding physical buttons to control my cat feeder at the same time use Blynk to control it. I already have the code for the physical buttons one. Like I wanna mix it up with this one.
I solved the connectivity issue .Now , Blynk have shown that my device is online .Btw i have changed the code to the hybrid one that i said i would try to do earlier .
#define BLYNK_TEMPLATE_ID "TMPL6NCp9Uqjb"
#define BLYNK_TEMPLATE_NAME "Cat Feeder 8888"
#define BLYNK_AUTH_TOKEN "***"
#include <Servo.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266WiFi.h>
Servo servo_mot;
#define OLED_RESET 7
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RTC_DS3231 rtc;
// WiFi credentials
char ssid[] = "HUAWEI-B315-ADEF";
char pass[] = "G44A7GA7F2R";
// Blynk setup
char auth[] = "***";
// Inputs/Outputs
int but1 = D5;
int but2 = D6;
int but3 = D7;
int servo_pin = D3;
int Buzzer = D0;
int irSensorPin = D4;
// Variables
bool state_but1 = true;
bool state_but2 = true;
bool state_but3 = true;
int stop_angle = 92;
int rotate_angle = 180;
int portions = 1;
int interval = 1;
unsigned int millis_before = 0;
unsigned int millis_now = 0;
int OLED_refresh_rate = 200;
int max_portions = 10;
int min_portions = 1;
int Hour, Minute;
int last_feed_hour = 1;
int next_feed_hour = 1;
bool feed_active = true;
int portion_delay = 500;
const unsigned long debounceDelay = 450; // Adjust this value as needed
// Blynk timer interval (in milliseconds)
unsigned int blynkTimerInterval = 1000;
// Blynk Virtual Pins
#define SERVO_CONTROL_PIN V0
// Blynk Timer
BlynkTimer blynkTimer;
void setup() {
pinMode(irSensorPin, INPUT);
pinMode(but1, INPUT_PULLUP);
pinMode(but2, INPUT_PULLUP);
pinMode(but3, INPUT_PULLUP);
servo_mot.attach(servo_pin);
servo_mot.write(stop_angle);
pinMode(Buzzer, OUTPUT);
digitalWrite(Buzzer, LOW);
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(100);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.display();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// If the RTC lost power and if there is information on the EEPROM
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Blynk.begin(auth, ssid, pass);
blynkTimer.setInterval(blynkTimerInterval, blynkTimerEvent);
}
void blynkTimerEvent() {
Blynk.run();
}
void buzzerAlert(int duration) {
analogWrite(Buzzer, 200); // Turn on the buzzer
delay(300); // Wait for the specified duration (in milliseconds)
digitalWrite(Buzzer, LOW); // Turn off the buzzer
}
void manualFeed() {
EEPROM.write(2, Hour);
next_feed_hour = Hour + interval;
if (next_feed_hour >= 23) {
next_feed_hour = next_feed_hour - 24;
}
EEPROM.write(3, next_feed_hour);
feed_active = true;
}
void updateOledDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.print(portions);
display.print(" portions");
display.setCursor(100, 50);
display.print(Hour);
display.print(":");
display.print(Minute);
display.setCursor(0, 16);
display.print("Each ");
display.setTextSize(2);
display.print(interval);
display.print(" hour");
display.setTextSize(1);
display.display();
}
void rotateServo() {
int i = 0;
while (i < portions) {
servo_mot.write(rotate_angle); // START the motor
i++;
display.clearDisplay();
display.setCursor(23, 23);
display.setTextSize(2);
display.print("FEEDING");
display.setTextSize(1);
display.display();
display.display();
delay(portion_delay); // Delay for each portion in milliseconds
}
servo_mot.write(stop_angle); // STOP the motor
feed_active = false;
}
void loop() {
millis_now = millis();
if (millis_now - millis_before > OLED_refresh_rate) {
Hour = rtc.now().hour();
Minute = rtc.now().minute();
updateOledDisplay();
millis_before = millis_now;
}
if (Blynk.connected()) {
blynkTimer.run(); // Run Blynk timer events
}
if (feed_active) {
// Check if feeding is complete
if (millis_now - millis_before > (portion_delay * portions)) {
servo_mot.write(stop_angle);
feed_active = false;
}
} else {
// Check if it's time for feeding
if (Hour == next_feed_hour && Minute == 0) {
rotateServo();
buzzerAlert(300);
}
}
// Check if Button 1 is pressed
if (digitalRead(but1) == LOW && state_but1) {
portions++;
if (portions > max_portions) {
portions = max_portions;
}
state_but1 = false;
delay(debounceDelay);
} else if (digitalRead(but1) == HIGH) {
state_but1 = true;
}
// Check if Button 2 is pressed
if (digitalRead(but2) == LOW && state_but2) {
manualFeed();
buzzerAlert(300);
state_but2 = false;
delay(debounceDelay);
} else if (digitalRead(but2) == HIGH) {
state_but2 = true;
}
// Check if Button 3 is pressed
if (digitalRead(but3) == LOW && state_but3) {
interval++;
if (interval > 24) {
interval = 24;
}
state_but3 = false;
delay(debounceDelay);
} else if (digitalRead(but3) == HIGH) {
state_but3 = true;
}
// Check if the IR sensor beam is blocked
if (digitalRead(irSensorPin) == LOW) {
buzzerAlert(300);
}
}
The problem for now is that servo is not rotating when i press the physical button (button 2) and also the Blynk button that is supposed to act like button 2 cant make it rotate as well , the rest are working fine i guess. I assume it would be the power supply issue.