i could really use your help. i have been building a programmable catfeeder and so far it work pretty well. For now i have one blynk button to feed manually and several timed tasks and they work just fine.
I wanted to add a physical button to my feeder, but i dont get right. I have to admit, that i had absolutly no knowledge of arduinos and I would be really glad, if someone could help me out.
I want two buttons, one physical and one blynk button to feed manually and several timers.
I am using an ELEGIANT NodeMcu Lua ESP8266 ESP-12E WIFI Development Board.
Here is my code
// Cat Feeder Wifi Sketch
#include <ESP8266WiFi.h> //needed for the wifi connection
#include <BlynkSimpleEsp8266.h> //needed for the blynk application
#include <Servo.h> //needed for the servos (you could also just also use only 1)
Servo myservo;
char auth[] = ; //here goes your blynk token
char ssid[] = ; //here goes your wifi SSID
char pass[] = ; //here goes your wifi password
const int servoPin = 14; //pin for the servos
int buttonPin = 3; //pin for the button
#define D5 14 //actually you don´t have to define these,
#define D9 3 //but since the nodemcu pin map is kind of different,
//virtual needed pins for the timers
//you can add as much virtual pins, as you need timers (in my case, I needed 5 timers at most)
BLYNK_WRITE(V1){
if (param.asInt()){
digitalWrite(buttonPin, HIGH);
} else {
digitalWrite(buttonPin, LOW);
}
}
BLYNK_WRITE(V2){
if (param.asInt()){
digitalWrite(buttonPin, HIGH);
} else {
digitalWrite(buttonPin, LOW);
}
}
void setup()
{
//this is needed for the blynk app
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
// this is the servo setup
pinMode(buttonPin, INPUT);
myservo.attach(servoPin);
myservo.write(175);
delay(500);
myservo.detach();
}
void loop()
{
Blynk.run();
// this is the servo loop
int buttonVal = digitalRead(buttonPin);
if(buttonVal == HIGH) {
myservo.attach(servoPin);
myservo.write(55);
delay(500);
myservo.write(175);
delay(500);
myservo.write(160);
delay(5000);
myservo.write(175);
delay(450);
myservo.detach();
delay(3000);
}
delay(13);
}
The picture of the cat just does it, that is one cute cat … you got me hooked.
First off, it’s not very smart to do anything but Blynk.run() in the loop. I see you have a lot of delays there. That is bound to be troublesome at some point.
If you check the “PushData” example of Blynk you can see an example of how to use SimpleTimer to do timed things. You should move the Servo loop to a timed running function. I’m not sure how to implement the delays, but I think with SimpleTimer we can achieve it.
I presume the Servo opens some sort of valve to allow for a certain amount of cat food to drop in the bowl? Can you show us a video of how it works? Does your code actually work? Because I’d be surprised if it’s stable with an ESP and all the delays.
-edit
Furthermore, electrical buttons have to be debounced, but there are a couple very elegant, yet small solutions for that out there, mostly with a capacitor and two resistors, so that shouldn’t be a problem.
actually it was just one simple delay. Though i had sometimes issues with the food getting stuck and my cats were smart enough to notice it and accomplished to open the “detached” servos a bit, so that some more food came out.
My first idea was, to use the delays to let the servo try to attempt to close the gap again. It didnt work well, so i just glued two little wooden things in the opening and now they can’t mess around anymore. So actually it will be just one delay again before detaching.
So what can i do about my problem with the buttons?
I tried different things and i did get the physical button to work on its own and also the blynk button. But when i tried to apply the the blynk button to the same digital button the physical one was hooked up, it didnt work. i changed the code over and over, once it never stopped opening and closing, once the physical button didnt react.
i think it has something to do with the HIGH and LOW states. The physical button works just, when it is on LOW, and my current code with the blynk buttons just works with HIGH.
It doesn’t really matter what states the buttons (virtual or otherwise) react to. What you have to do is track the state of a button. So you’ll need an extra variable. Your problem is very similar to this: 2 way lighting circuit control with blynk and feedback updates
Have you read there? There is a lot of viable code there to solve your problem I think. (especially at the end of the topic).
actually i dont understand, why i need to track the state of the button. i wanted a more simple solution.
i just wanted the buttons to run the servo loop, when pressed. here is what i thought.
cant i assign the physical button to another pin and let the same servo loop happen.
lets say something as if either button 1 (phyiscal) or button 2 (blynk button) is pushed, do task “A” (the servo routine).
I corrected the code without the obsolete delays
// Cat Feeder Wifi Sketch
#include <ESP8266WiFi.h> //needed for the wifi connection
#include <BlynkSimpleEsp8266.h> //needed for the blynk application
#include <Servo.h> //needed for the servos (you could also just also use only 1)
Servo myservo;
char auth[] = ; //here goes your blynk token
char ssid[] = ; //here goes your wifi SSID
char pass[] = ; //here goes your wifi password
const int servoPin = 14; //pin for the servos
int buttonPin = 3; //pin for the button
#define D5 14 //actually you don´t have to define these,
#define D9 3 //but since the nodemcu pin map is kind of different,
//virtual needed pins for the timers
//you can add as much virtual pins, as you need timers (in my case, I needed 5 timers at most)
BLYNK_WRITE(V1){
if (param.asInt()){
digitalWrite(buttonPin, HIGH);
} else {
digitalWrite(buttonPin, LOW);
}
}
BLYNK_WRITE(V2){
if (param.asInt()){
digitalWrite(buttonPin, HIGH);
} else {
digitalWrite(buttonPin, LOW);
}
}
void setup()
{
//this is needed for the blynk app
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
// this is the servo setup
pinMode(buttonPin, INPUT);
myservo.attach(servoPin);
myservo.write(175);
delay(500);
myservo.detach();
}
void loop()
{
Blynk.run();
// this is the servo loop
int buttonVal = digitalRead(buttonPin);
if(buttonVal == HIGH) {
myservo.attach(servoPin);
myservo.write(55);
delay(500);
myservo.write(175);
delay(500);
myservo.detach();
delay(3000);
}
}
You need to convert the following to a new function and use a SimpleTimer setTimeout function.
// this is the servo loop
int buttonVal = digitalRead(physicalbuttonPin);
if(buttonVal == HIGH) {
myservo.attach(servoPin);
myservo.write(55);
delay(500);
myservo.write(175);
delay(500);
myservo.detach();
delay(3000);
}
int buttonValPrev;
void loop(){
button();
}
void button(){
int buttonVal = digitalRead(physicalbuttonPin);
if(buttonVal == HIGH && buttonValPrev == LOW) {
// button pressed in, will stop the function looping
buttonValPrev = buttonVal; // stop a function loop
myservo.attach(servoPin);
myservo.write(55);
timer.setTimeout(500, servoStage1); // delay 500ms then do servoStage1
}
}
void servoStage1(){
myservo.write(175);
timer.setTimeout(500, servoStage2); // delay 500ms then do servoStage2
}
void servoStage2(){
myservo.detach();
}
Hey guys. First of all. Thanks for the very fast help. I really appreciate it! Especially because I am so very new to this world. Maybe I shouldn’t have started with a “sophisticated” project like this. But here I am… lucky me, the stand alone blynk button version worked from the beginning, as also my construction itself.
And although the new code is not my work, I already learned a lot by just looking at what you sent me. This is really encouraging.
For instance did I not yet ran into the problem false interrupts and I just learned about software and hardware debouncing. Although this has nothing to do with my code, I wanted to ask you, if I need this inverted schmitt trigger or if it could be done with a couple of resistors, the capacitor and a simple button.
Besides that I was looking at the code provided by Jamin and he very kindly changed the delays. So I tried to understand the logic behind it and to complete my code. It now looks like that and I wanted you to tell me, if this should work. I can’t really test it, because due to my work I am not at home for another week. I hope its going in the right way at least.