Problem with Yun running with v0.4.7 library

Hi,

I just updated my Yun code with the new v0.4.7 library from v0.4.6 and it stopped working.

When the code compiles, I get:

“Sketch uses 20080 bytes (70%) of program storage space. Maximum is 28672 bytes. Global variables use 2497 bytes (97%) of dynamic memory, leaving 63 bytes for local variables. Maximum is 2560 bytes. Low memory available, stability problems may occur.”

while with the v0.4.6 I was getting this:

“Sketch uses 20094 bytes (70%) of program storage space. Maximum is 28672 bytes. Global variables use 1885 bytes (73%) of dynamic memory, leaving 675 bytes for local variables. Maximum is 2560 bytes.”

What changed? It appears that the new library is taking much more memory space than the older one.

@vshymanskyy I leave this one to you… no more “misled” memory assumptions for me… well at least for today :stuck_out_tongue_winking_eye:

@Emilio, I verified the Blynk library and it actually shows better results than previous one.
Most probably your sketch uses some non-usual features, or itself causes the problem.
Please show your full sketch

Hi @ Vhymanskyy thanks for getting back to me.

I’ve been using the following code for the last year or so. During this period I added and removed lines of codes but never had a memory issue.

What the code does is actuate few relays via Blynk or a web server. The reason I’m using the latter is because, at times, I found the Blynk server non responsive and I needed to get to my actuators via remote ASAP.

I’m using Arduino IDE v.1.8.2 to compile the code.

Surely you can find improvements in my code so I’d appreciate your comments as I’m a hobbyist and not a pro.

//#define BLYNK_DEBUG // Optional, this enables lots of prints
//#define BLYNK_PRINT Serial // Comment this out to disable prints and save space

#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>
#include <BlynkSimpleYun.h>
#include <Process.h>
#include <SimpleTimer.h>

/* set timers */
SimpleTimer timerV1;  // used by Blynk
SimpleTimer timerV2;  // "
SimpleTimer timerWeb;  // used for the web page
SimpleTimer timerSiren;  // used by Blynk
SimpleTimer timerLed;  // used by Blynk
//SimpleTimer timerEmail;  // used or the email sub
unsigned long previousMillisM = 0; //==== used for mail sub
const long interval = 10000;  // 1 min delay
String emailBody = "";

//=== set pin numbers ===
const int blindsSensorPin = 12; // (digital in) ??  when open
const int blindsOpenRelayPin = 5; // (digital out) open main blinds (persiana)
const int centralitaRelayPin = 6;  // (digital out) reset centralita
const int sirenPin = 8;  // (digital out) siren
const int VACsensorPin = A0; // (analog in) sensor 220Vac (4. Vdc through a R, a zener and a cap)

/* Blynk auth token */
char auth[] = "";

WidgetLED led1(V4);

void repeatTask() {
  bool pinState = (digitalRead(blindsSensorPin) == LOW);

  if (!pinState) {
    Console.println("Switch closed");
    led1.off(); // if switch is closed turn off led
  }
  else {
    Console.println("Switch open");
    led1.on();
  }
}

/* web page */
BridgeServer server;

void setup()
{

  pinMode(blindsSensorPin, INPUT);
  pinMode(blindsOpenRelayPin, OUTPUT);
  pinMode(centralitaRelayPin, OUTPUT);
  pinMode(sirenPin, OUTPUT);
  //keep relays OFF at start
  digitalWrite(blindsOpenRelayPin, HIGH);
  digitalWrite(centralitaRelayPin, HIGH);
  digitalWrite(sirenPin, HIGH);

  Bridge.begin();
  Console.begin();

  server.listenOnLocalhost();
  server.begin();

  //while (!Console); // Wait for Console port to connect
  Blynk.begin(auth);

  timerLed.setInterval(5000, repeatTask);

}

void loop() {

  timerV1.run();  // used by Blynk
  timerV2.run();  // "
  timerWeb.run();  // used for the web page
  timerSiren.run();  // used by Blynk
  timerLed.run();  // used by Blynk

  // reset mail body text
  emailBody = "";

  Console.print("\n"); // carriage return
  Console.println("Today's Date/Time is: " + getTimeStamp());

  // if it's 9AM open blinds
  isOpeningTime();

  /* if mains 220Vac are missing, send alert */
  if (checkACline()) {
    Console.println("No hay luz!!");
    emailBody = "No hay luz!!"; // send email
    sendMail();
  }

  /* ctr from web */
  getCmdFromWeb();

  // update Blynk
  Blynk.run(); // has to be last line
}
//// END void loop

bool checkACline() {
  int acDetection = analogRead(VACsensorPin);  //take a reading
  float voltage = (acDetection / 1024.0) * 5.0; // convert in V approx. 3,40V
  //Console.println(voltage);

  if (voltage >= 3.0) return true;
  else return false;

}

/* is opening hour? */
void isOpeningTime() {
   // get hours & minutes, convert to int and compare
  String timeString = getTimeStamp(); // jump to sub
  String hourString = timeString.substring(9, 11); // strip hours
  String minString = timeString.substring(12, 14); // strip minutes
  int hours = hourString.toInt(); // convert string to int
  int minutes = minString.toInt();

  // if it's 9AM and the blinds are closed, open them
  if (hours == 9 && minutes == 0) {

    digitalWrite(blindsOpenRelayPin, LOW); // activate relay
    delay(1000); // activate relay w/900 ms (pulse)
    digitalWrite(blindsOpenRelayPin, HIGH); // desactivate relay
    delay(61000); // wait a minute to pass -- DON'T NEED IF USING IR SWITCH

    emailBody = "Door opened at ";
    emailBody += getTimeStamp();
    sendMail();
  }
}
//// END isOpeningTime


//========= Send Email sub =============0
/* https://forum.arduino.cc/index.php?topic=362659.0 */
void sendMail() {

  /* http://forum.arduino.cc/index.php?topic=362659.0;nowap
    http://ibuyopenwrt.com/index.php/8-yun-compatible/80-command-line-with-gmail-msmtp
    to test gmail: /mnt/sda1/sendemail.sh 'testing gmail - this will show in the body'
  */

  unsigned long currentMillis = millis();  //catch the current value of millis()
  if (currentMillis - previousMillisM >= interval * 15) { // wait 15 minutes to resend email

    Process p;
    p.begin("/mnt/sda1/sendemail.sh");
    p.addParameter(emailBody);
    p.run();
    Console.println("Sending mail");
    while (p.running());
    while (p.available() > 0) {
      char c = p.read();
      Console.println(c);
    }
    previousMillisM = currentMillis;
  }
  //  timerEmail.setTimeout(6000, limitSendingEmails);
}

void limitSendingEmails() {
  // do nothing
}
//// END Send Email sub

/* ===== BLYNK CONTROLS ===== */
BLYNK_WRITE(V1)
{
  if ( param.asInt() == 1)
  {
    digitalWrite(blindsOpenRelayPin, LOW); // activate relay
    timerV1.setTimeout(1000, deactivateRelayV1);
  }
}

void deactivateRelayV1() {
  digitalWrite(blindsOpenRelayPin, HIGH); // deactivate relay
}

BLYNK_WRITE(V2)
{
  if ( param.asInt() == 1)
  {
    digitalWrite(centralitaRelayPin, LOW); // activate relay
    timerV2.setTimeout(10000, deactivateRelayV2);
  }
}

void deactivateRelayV2() {
  digitalWrite(centralitaRelayPin, HIGH); // deactivate relay
}

BLYNK_WRITE(V3)
{
  if ( param.asInt() == 1)
  {
    digitalWrite(sirenPin, LOW); // activate relay
    timerSiren.setTimeout(2000, deactivateRelaySiren);
  }
}

void deactivateRelaySiren() {
  digitalWrite(sirenPin, HIGH); // deactivate relay
}
/* ===== --- ===== */

//**** Get Time Stamp ****
String getTimeStamp() {
  String result;
  Process time;
  time.begin("date");
  time.addParameter("+%D-%T");
  time.run();

  while (time.available() > 0) {
    char c = time.read();
    if (c != '\n')
      result += c;
  }

  return result;
}
//// END getTimeStamp

/* Web pages */
void getCmdFromWeb() {
  BridgeClient client = server.accept();

  //==== There is a new client?
  if (client) {
    String command = client.readString();
    command.trim(); //kill whitespace

    if (command == "activateRelay") {

      digitalWrite(blindsOpenRelayPin, LOW);
      timerWeb.setTimeout(1000, deactivateRelayBlinds);

      emailBody = "Se ha activado el relay de la persiana"; // send email
      sendMail();

      Console.println("***************** Relay Pulsed **************************");
    }

    if (command == "resetCentralita") {

      digitalWrite(centralitaRelayPin, LOW);
      timerWeb.setTimeout(10000, deactivateRelayCentralita);

      emailBody = "Se ha re-iniciada la centralita"; // send email
      sendMail();

      Console.println("===== Relay Centralita Pulsed =====");
    }

    // Close connection and free resources.
    client.stop();
  }
  delay(50); //==== 50ms delay
}

void deactivateRelayBlinds() {
  digitalWrite(blindsOpenRelayPin, HIGH); // deactivate relay
}

void deactivateRelayCentralita() {
  digitalWrite(centralitaRelayPin, HIGH); // deactivate relay
}

Okay, I think I see the issue: you use many SimpleTimer objects, but actually just one SimpleTimer can hold up to time 10 events… With BlynkTimer, this is increased to 16, so that’s why your overall memory consumption increased significantly

Oh, an easter egg :wink: I had questions, but I moved them over to the relevant topic.

@Emilio Here is a snippet of the timer routine I have in one of my projects… this should help you visualise what Vhymanskyy means about multiple events:

In this case a single Timer, called timer ;), has 8 individual events

// ===== Timer Setup =====
  timer.setInterval(1000L, whiteLED);  // White LED on CodeShield
  timer.setInterval(1000L, clockDisplay);  // Time and Date Widget
  timer.setInterval(1000L, PIR);  // PIR motion
  timer.setInterval(3000L, CurrentII);  // Current Reading Widget
  timer.setInterval(2000L, AnalogSensors);  // Misc analog sensors on CodeShield
  timer.setInterval(5000L, HeartBeat);  // Heartbeat LED
  timer.setInterval(10000L, thermTemp);  // Thermistor  on CodeShield
  timer.setInterval(60000L, sendUptime);  // Up Time Widget
1 Like

Ok, that fixed it. Thank you