Blynk going offline during loop

Hello all,

Loving Blynk and have had it working fine with examples but now I’m trying to integrate it with a sketch I’ve made to control a dog treat machine I’m having problems. Seems to connect to Blynk OK, but when it goes into the main look of the sketch I’m getting no Blynk connection. Presume this is something quite simple but it’s got me stumped. Any help gratefully received.
Here’s the full code… note that the Blynk variables are just dummies at the moment to test things are working…

/////////// BLYNK & ETHERNET SET-UP
#define BLYNK_PRINT Serial // Enables Serial Monitor
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h> // This part is for Ethernet stuff

char auth[] = "06a5a821b7c2478db27b99ad1da9d3e5"; // Put your Auth Token here. (see Step 3 above)

#define TREATS V1
#define STARTTIME V2
#define MINDELAY V3
#define MAXDELAY V4
#define COUNTDOWNS V5
WidgetLCD lcd(6);

/////////// LIBRARIES
#include <Servo.h>;                          // Includes the servo library
Servo treatServo;                            // Creates a servo object to allow control
#include <elapsedMillis.h>                   // Include the elapsedMillis library for checking times (from Arduino reset)
elapsedMillis timeElapsed;                   // set a global variable for elapsedMillis so it doesn't reset (until hard Arduino reset)

////////// TIMES & NUMBER OF TREATS 
const byte maxTreats = 20;                   // Maximum number of treats to dispense (1 less than max number required?)
byte readyText[maxTreats];                   // Sets up a count for the main for loop (runs maxTreat times)
unsigned long treatStartTime[maxTreats];     // Each treat time is stored in this array
unsigned long randNumber = 0;                // Sets variable for the random number used to creat the treat times array
int treatsDispensed = 0;                     // Number of treats actually dispensed
int countdownDelay = 250;                    // Delay between each countdown from 20 to 1

int unsigned long treatMinInterval = 0;
int unsigned long treatMaxInterval = 0;
int unsigned long firstTreatDial = 0;

int minIntervalPin = A1;
int maxIntervalPin = A2;
int firstTreatDialPin = A3;

int programFinished = 0;
int blynkCountdownCount;


////////// BUZZER
int countdownToneLength = 100; //insert length of countdown beep
int countdownTonePitch = 3000; //tone/frequency of countdown beep

////////// LEDs
byte LEDPower = 13;
byte LEDCountdown = 12;
byte LEDButtonPressed = 11;
byte LEDTreatComing = 10;

////////// BUTTONS
byte pushForTreat = 0;                       // Push (Button) for treat variable
byte treatButton = 7;                          // set the push for treat button to PIN 7

////////// SERVO
byte servoSpeed = 2;                         // Sets delay between each movement of servo
byte servoPos = 0;                           // Variable to store servo position

////////// SET-UP ///////////////////////////////////////////////////////////////
void setup() {

  Serial.begin(9600);                         // Set up the serial port to allow output to monitor/usb
  Blynk.begin(auth);                          // Here your Arduino connects to the Blynk Cloud
  //while (! Serial);                           // Wait whilst the serial port sets up // IS THIS DOING ANYTHING
  while (Blynk.connect() == false) {        
    // Wait until connected
  }

  pinMode(treatButton, INPUT);                // Set treat push button to input
  pinMode(LEDPower, OUTPUT);                  // Set the LED power to 
  pinMode(LEDCountdown, OUTPUT);              // Set the LED countdown pin to output
  pinMode(LEDButtonPressed, OUTPUT);          // Set the LED button pressed pin to output
  pinMode(LEDTreatComing, OUTPUT);            // Set the LED treat coming notification pin to output

  pinMode(minIntervalPin, INPUT);             // Set min interval pin on dial to input
  pinMode(maxIntervalPin, INPUT);             // Set max interval pin on dial to input
  pinMode(firstTreatDialPin, INPUT);             // Set first treat dial pin to input
  
  digitalWrite(LEDPower, HIGH);               // Turns on power LED

  treatServo.attach(9);                       // Set servo to PIN 9
  treatServo.write(6);                        // Set servo to 5 degrees to stop jitter

  randomSeed(analogRead(0));

  Serial.println("Hello Arlo. I'm just preparing your treat program...");
  Serial.println("");
  Serial.println("Don't forget to check that I'm full of treats.");
  Serial.println("");

  /*
         Serial.println("Please set the mininmum treat interval and press the TREAT button");
   while (digitalRead(treatButton) == LOW) {    // Wait whilst you set the times and then press go
         treatMinInterval = analogRead(minIntervalPin);
         treatMinInterval = map(treatMinInterval, 0, 1023, 180000, 780000);       //Sets time between 3 mins and 13 mins
         Serial.print(treatMinInterval);
         Serial.print("\t");
         Serial.println(treatMinInterval / 1000/60);
         delay(250);
         ;
         }

         digitalWrite(LEDTreatComing, HIGH);
         delay(100);
         digitalWrite(LEDTreatComing, LOW);
         delay(100);
         

         delay(1000);                    // Inserts pause to make sure next read treatbutton doesn't take the last press into account
         Serial.println("");
         Serial.println("Please set the max treat interval and press the TREAT button");
   while (digitalRead(treatButton) == LOW) {    // Wait whilst you set the times and then press go
         treatMaxInterval = analogRead(maxIntervalPin);
         treatMaxInterval = map(treatMaxInterval, 0, 1023, 300000, 900000);         //Sets time between 5 mins and 15 mins
         Serial.print(treatMaxInterval);
         Serial.print("\t");
         Serial.println(treatMaxInterval / 1000/60);
         delay(250);
         ;
          }

         digitalWrite(LEDTreatComing, HIGH);
         delay(100);
         digitalWrite(LEDTreatComing, LOW);
         delay(100);

          delay(1000);                    // Inserts pause to make sure next read treatbutton doesn't take the last press into account
          Serial.println("");
          Serial.println("Please set the first countdown time and press the TREAT button");
   while (digitalRead(treatButton) == LOW) {    // Wait whilst you set the times and then press go
         firstTreatDial = analogRead(firstTreatDialPin);
         firstTreatDial = map(firstTreatDial, 0, 1023, 300000, 900000);           //Sets time between 5 mins and 15 mins
         Serial.print(firstTreatDial);
         Serial.print("\t");
         Serial.println(firstTreatDial / 1000/60);
         delay(250);
         ;
         }

         digitalWrite(LEDTreatComing, HIGH);
         delay(100);
         digitalWrite(LEDTreatComing, LOW);
         delay(100);

  for(int i = 0; i < 5; i++)
  {
         digitalWrite(LEDTreatComing, HIGH);
         delay(100);
         digitalWrite(LEDTreatComing, LOW);
         delay(100);
  }      

 */
 
  for (int i = 0; i < 20; i++)                                     // fill array with values
  {
      randNumber = random(treatMinInterval, treatMaxInterval);           // Fill array with random values between (x, and y)
       if (i == 0){                                                // Check to see if it's the first space in the array
          treatStartTime[i] = firstTreatDial;                      // If so, fill the first space in the array with the first treat start time
       }
       else {
          treatStartTime[i] =  randNumber + treatStartTime[i-1];  
       }
  }

  Serial.print("The total program time will take approx: ");      // Displays the total time the program will take by displaying the last array value
  Serial.print(treatStartTime[19]/1000/60);
  Serial.println(" minutes.");
  Serial.println("");
  Serial.println("The treat start times in minutes will be:");    
  
   for (int i = 0; i < 20; ++i)                                   // Prints out all the treat times 
  {
    Serial.print(treatStartTime[i]/1000/60);              
    Serial.print(" | ");
  }

  Serial.println("");
  Serial.println("Sending Y to RPi to trigger countdown started email");
  Serial.print("Y");
  Serial.println("");
  
}

// These functions tell Arduino (from Blynk) what to do if there is a Widget(s)
// which is requesting data for Virtual Pins

BLYNK_READ(TREATS)
{
  Blynk.virtualWrite(TREATS, programFinished);
  Blynk.virtualWrite(STARTTIME, programFinished);
  Blynk.virtualWrite(MINDELAY, programFinished);
  Blynk.virtualWrite(MAXDELAY, programFinished);
  Blynk.virtualWrite(COUNTDOWNS, programFinished);
}

// ******************** MAIN PROGRAM ******************** //

void loop() {

  Blynk.run(); // All the Blynk Magic happens here...
  
 
 for (int treatNumber=0; treatNumber < maxTreats; treatNumber++)                     //loops for the maxTreat value
 {
   if((timeElapsed > treatStartTime[treatNumber]) && (readyText[treatNumber] == 0))   //enter countdown if time elapsed - time array
    {
    Serial.println(" ");
    Serial.println(" ");
    Serial.println("----------------------------------------------------------------------");
    Serial.print("Countdown started at ");
    Serial.print(timeElapsed / 1000 / 60);
    Serial.println(" minutes");
    Serial.print("Countdown Number: ");                                               // Print the countdown digit (from 20 to 1) 
    Serial.println(treatNumber + 1);                                                  // Prints the number of times the countdown has run | CHANGE TO CYCLE NUMBER?
    readyText[treatNumber] = readyText[treatNumber] + 1;                              // Adds one to the readyText variable used in the if statement (incrementer)
    blynkCountdownCount = readyText[treatNumber]; 
      for (int i=20; i >= 1; i--)                                                     // Loop for 20 times to print out the countdown digits
      {
          digitalWrite(LEDCountdown, HIGH);
          tone(6, countdownTonePitch, countdownToneLength);                           // Beeps to indicate countdown is in progress
          Serial.print(i);                                                            // Prints the current countdown digit
          Serial.print(" ");
          delay(countdownDelay);                                                      // This needs to CHANGE for without delay/millis
          digitalWrite(LEDCountdown, LOW);
          delay(countdownDelay);
               
               pushForTreat = digitalRead(treatButton);                               // Reads the treatButton and sets the value to pushForTreat
               if (pushForTreat == HIGH)
                {
                  digitalWrite(LEDButtonPressed, HIGH);
                }
               
               if (pushForTreat == HIGH) {                                            // If the button is pressed, notify and break to the dispense loop
                Serial.println(" ");
                Serial.println(" ");
                Serial.println("The button was pushed");
               break; 
               }                                                                     // End of check for button press loop
      }                                                                              // End of countdown loop

              if(pushForTreat == HIGH){                                              // If treat button pressed inform treat coming
              digitalWrite(LEDTreatComing, HIGH);
              Serial.println("Here you go have your first treat");
              Serial.println(" ");
              tone(6, 3200, 80);                                                     //play tone to make dog aware treat is coming (check)
              delay(150);
              tone(6, 3200, 80);
              delay(150);
              tone(6, 3200, 80);

                  for (servoPos = 5; servoPos <= 110; servoPos += 1) {               // goes from 5 degrees to 180 degrees - in steps of 1 degree
                  treatServo.write(servoPos);                                        // tell servo to go to position in variable 'servoPos'
                  delay(servoSpeed);                                                 // waits for a delay to let the servo to reach the position
                  }
                  for (servoPos = 110; servoPos >= 5; servoPos -= 1) {               // goes from 180 degrees to 5 degrees
                  treatServo.write(servoPos);                                        // tell servo to go to position in variable 'servoPos'
                  delay(servoSpeed);                                                 // waits for a delay to let the servo to reach the position 
                  }
                  Serial.println("You scoffed it... You'll have to wait until I give you the next signal");   //
                  treatsDispensed = treatsDispensed + 1;                                                      // Add one to the number of treats actually dispensed.
                  Serial.print("So far you've gobbled up ");
                  Serial.print(treatsDispensed); 
                  Serial.println(" treats.");
                  Serial.println("----------------------------------------------------------------------");
                  Serial.println("");
                  
                  Serial.println("Sending Z to RPi to trigger treat given email");
                  Serial.print("Z");
                  Serial.println("");
                  
                  digitalWrite(LEDButtonPressed, LOW);
                  digitalWrite(LEDTreatComing, LOW);
             
              }   // End of dispense treat loop

                if (treatNumber == 19) {
                         Serial.println("");
                         Serial.println("----------------------------------------------------------------------");
                         Serial.println("PROGRAM FINISHED");
                         Serial.print("after ");
                         Serial.print(timeElapsed/1000/60);
                         Serial.println(" minutes.");
                         Serial.print(treatsDispensed);
                         Serial.print(" treats have been dispensed out of ");
                         Serial.print(maxTreats);
                         Serial.println(" possible treats.");
                         
                         Serial.println("");
                         Serial.println("Sending X to RPi to trigger program finished email");
                         Serial.print("X");
                         Serial.println("");
                         programFinished = treatNumber;
                         
                         }
              }                // End of main if loop controlled by elapsedTime
      }                // End of main for loop (for the amount of maxTreats)
      
      while (programFinished == 19)
      {
        digitalWrite(LEDPower, LOW);
        delay(500);
        digitalWrite(LEDPower, HIGH);
        delay(500);  
      }
}

5 to 10 second hearbeat timeout with Blynk. Move everything out of loop so you just have

void loop() {

  Blynk.run();
  YourTimer.run();

}

Simple timer requires the headers so something like:

#include <SimpleTimer.h>
SimpleTimer YourTimer;

And the following in setup:

YourTimer.setInterval(1000L, previousstuffinloop); // move your loop part to a function called previousstuffinloop(); and it will be called every second.

It looks like you’ve got a lot of serial.prints and delays in your sketch which I believe will cause Blynk to disconnect from the server. I see a lot on here people being advised to use the simple timer library instead of delays and its strongly advised only to have Blynk.run() and simple timer.run() within the loop so Blynk stays connected. If you can stick to these rules Blynk is pretty bullet proof and very rarely disconnects :wink:

Thanks very both, the serial prints are just in for development purposes really. It’s my first attempt at programming for about 20 years!
Key part of Blynk will be to report what serial print is doing, i.e. number of treats given etc.
Just heading out for the day but will have a go this evening and report back.
Just ordered a photon to create a wifi button instead of a wired button… this is all too addictive.
Cheers
C.

I’ve just returned to programming (only games on commodore Amiga!) after a few years away and found Blynk addictive :blush: It’s taking over our house! Tv lift bathroom humidity fan,mood lamp, garage temp and humidity monitor and aquarium control and monitor :sunglasses:.
Not sure what other projects you have planned but these are really fantastic value and worth the 2/3 week wait from China :wink:

http://www.aliexpress.com/store/product/D1-mini-Mini-NodeMcu-4M-bytes-Lua-WIFI-Internet-of-Things-development-board-based-ESP8266/1331105_32529101036.html

Watch out for China addiction too they sell all sorts of sensors and modules , I get a delivery almost twice a week it’s so cheap from aliexpress

1 Like

no, i think he meant the DELAYS were not helping, the serial prints are not too bad…

A post was split to a new topic: Problem when using SimpleTimer