Problem with my widgets led (I guess)

Sure, it’s shown below. I’m using two timers: one to turn on leds on the app which is working and the other, to count and display the total of times the leds come on.

//#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 <BlynkSimpleYun.h>
#include <Process.h>

#include <FileIO.h>
String dataString;

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

BlynkTimer timer;

//LEDs on counters
// S XL XXL S1 S2
int opCounter[5] = {0, 0, 0, 0, 0};
int lastRelayState[5] = {0, 0, 0, 0, 0};

//Blynk LEDs
WidgetLED ledS(V11);
WidgetLED ledXL(V12);
WidgetLED ledXXL(V13);
WidgetLED ledS1(V14);
WidgetLED ledS2(V15);

//hardware arduino Yun
//lines connected to N/O relays contactors
const int statusPinS = A5;
const int statusPinXL = A4;
const int statusPinXXL = A3;
const int statusPinS1 = A2;
const int statusPinS2 = A1;

void setup() {
  Bridge.begin();
  Console.begin();

  pinMode(statusPinS, INPUT_PULLUP);
  pinMode(statusPinXL, INPUT_PULLUP);
  pinMode(statusPinXXL, INPUT_PULLUP);
  pinMode(statusPinS1, INPUT_PULLUP);
  pinMode(statusPinS2, INPUT_PULLUP);

  timer.setInterval(5000L, ledTimers);    //used to turn on leds on app
  timer.setInterval(6000L, ledCounters);   //used to count times leds turn on

  Blynk.begin(auth);
}

void loop() {
  Blynk.run();
  timer.run();
}

void ledTimers() {
  bool pinState[5] {
    digitalRead(statusPinS) == HIGH,
    digitalRead(statusPinXL) == HIGH,
    digitalRead(statusPinXXL) == HIGH,
    digitalRead(statusPinS1) == HIGH,
    digitalRead(statusPinS2) == HIGH
  };

  delay(50);  //for debounce just in case

  if (pinState[0]) {
    ledS.off();
  }
  else {
    ledS.on();
  }

  if (pinState[1]) {
    ledXL.off();
  }
  else {
    ledXL.on();
  }

  if (pinState[2]) {
    ledXXL.off();
  }
  else {
    ledXXL.on();
  }

  if (pinState[3]) {
    ledS1.off();
  }
  else {
    ledS1.on();
  }

  if (pinState[4]) {
    ledS2.off();
  }
  else {
    ledS2.on();
  }
}

void ledCounters() {

  bool pinState[5] {
    digitalRead(statusPinS),
    digitalRead(statusPinXL),
    digitalRead(statusPinXXL),
    digitalRead(statusPinS1),
    digitalRead(statusPinS2)
  };

  delay(50);  //for debounce just in case

  if (!pinState[0] != lastRelayState[0]) {
    lastRelayState[0] = !pinState[0];

    opCounter[0] += 1;

    dataString = "";
    dataString += getTimeStamp();
    dataString += " S cnt: ";
    dataString += opCounter[0];
    writeSD(dataString);

    Blynk.virtualWrite(V18, opCounter[0]);
  }

  if (!pinState[1] != lastRelayState[1]) {
    lastRelayState[1] = !pinState[1];
    opCounter[1] += 1;

    dataString = "";
    dataString += getTimeStamp();
    dataString += " XL cnt: ";
    dataString += opCounter[1];
    writeSD(dataString);

    Blynk.virtualWrite(V20, opCounter[1]);
  }

  if (!pinState[2] != lastRelayState[2]) {
    lastRelayState[2] = !pinState[2];
    opCounter[2] += 1;

    dataString = "";
    dataString += getTimeStamp();
    dataString += " XXL cnt: ";
    dataString += opCounter[2];
    writeSD(dataString);

    Blynk.virtualWrite(V21, opCounter[2]);
  }

  if (!pinState[3] != lastRelayState[3]) {
    lastRelayState[3] = !pinState[3];
    opCounter[3] += 1;

    dataString = "";
    dataString += getTimeStamp();
    dataString += " S1 cnt: ";
    dataString += opCounter[3];
    writeSD(dataString);

    Blynk.virtualWrite(V22, opCounter[3]);
  }

  if (!pinState != lastRelayState[4]) {
    lastRelayState[4] = !pinState[4];
    opCounter[4] += 1;

    dataString = "";
    dataString += getTimeStamp();
    dataString += " S2 cnt: ";
    dataString += opCounter[4];
    writeSD(dataString);

    Blynk.virtualWrite(V23, opCounter[4]);
  }
}

void writeSD(String data) {
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  // The FileSystem card is mounted at the following "/mnt/FileSystema1"
  File dataFile = FileSystem.open("/mnt/sd/cntlog.txt", FILE_APPEND);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(data);
    dataFile.close();
    // print to the Console port too:
    Console.print("Data written to SD: ");
    Console.println(data);
  }
  // if the file isn't open, pop up an error:
  else {
    Console.println("error opening datalog.txt");
  }
}

// This function return a string with the time stamp
String getTimeStamp() {
  String result;
  Process time;
  // date is a command line utility to get the date and the time
  // in different formats depending on the additional parameter
  time.begin("date");
  time.addParameter("+%D-%T");  // parameters: D for the complete date mm/dd/yy
  //             T for the time hh:mm:ss
  time.run();  // run the command

  // read the output of the command
  while (time.available() > 0) {
    char c = time.read();
    if (c != '\n') {
      result += c;
    }
  }
  return result;
}

As those functions start in sequential order, the placement of the Blynk.run() can allow the Blynk Library to maintain housekeeping in the middle of the functions instead of waiting until they all finish, at which time it is possibly too late.

If you have a particularly long function running, then just place a Blynk.run() somewhere in the midst of that functions code.

Also, this is in the void loop:

whereas the alternative example was in a function being called by a timer.

But maybe it was a rhetorical question?

Pete.

Good catch, I was referring to the placement of extra Blynk.run() commands, I didn’t notice the overall placement in the void loop().

So in that case the difference is all those functions trying to run thousands of times a second in the void loop() vs trying to run at a more reasonable pace via a timed call :stuck_out_tongue:

1 Like

That seems a bit of a cumbersome way to do it. Wouldn’t it make more sense just to increment your counter at the same time that you activate your LED/Motors?

In your original post you said:

then later you said:

So I’m confused about exactly what is and isn’t working in Blynk, and also what data you’re getting on your SD card compared to Blynk.

Also, you said:

but all of your pin declarations and reads are digital rather than analogue. I have to admit that I’ve never tried doing a digital read on an analogue pin, but it seems a bit strange to me!

Pete.

I think the answer has already been given, but let me elaborate nonetheless:

What you suggest is running those functions a few 1000 times a second, thats one hell of a way to brea it. What I’m suggesting is to replace ALL timed function with theOneThatLaunchesThemAll, so:

void setup(){
...
  timer.setInterval(5000L, oneFunctionToLaunchThemAll);
...
}

AND place a blynk.run() in the middle for good measure (to keep the heartbeat)

This is interesting and I’d never considered doing this. What is considered to be “a particularly long function”?

I have a timing issue with a PM sensor that sends out serial data every 2.3 seconds regardless, this means that my program could wait at the first “if start character == 0x**” statement for 4.6 seconds (minus a little bit) before continuing with the rest of the function. Because this timer function has to sometimes wait it then effects the rest of the timed functions and possibly Blynk.run, I don’t know.

I don’t fully understand how the Blynk timers work, even after reading the excellent tutorial by @Gunner several times. I realize inserting a Blynk.run() command before this possible delay won’t have any effect, but maybe I should insert it once the start character has been read.

My CO2 and CH2O sensors both require a serial request command to get data which is great because I can control the event rather than the sensor controlling me!

Richard

They are based on SimpleTimer, an Arduino library you can read a bit more about here…

https://playground.arduino.cc/Code/SimpleTimer#Functions

If you have long runs or Blocking code in which you can insert them, then additional Blynk.run() and timer.run() calls could be placed there to help keep the rest of the code ticking away as they basically call each’s respective library and keeps them updated and “in the loop”. Trial and error is a good way to see what works where.

Hi @PeteKnight,

When a thread gets long, the likelihood to produce errors or confusion is high so, I summarize my dilemma as follow:

I’m using 5 analog pins programmed as INPUT_PULLUP and connected to the N/O contactor of a relay. So, there’s a constant HIGH on the input. When the relay is actuated, a LOW is applied to the analog pins. I’m using analog pins because all my digital once are in use.

//hardware arduino Yun
//lines connected to N/O relays contactors
const int statusPinS = A5;
const int statusPinXL = A4;
const int statusPinXXL = A3;
const int statusPinS1 = A2;
const int statusPinS2 = A1;

In my original code which is not posted, I used 5 timers to read the inputs and turn on the LEDs on the Blynk app and that worked fine for months. Then I decided to count the times the LEDs come on. The code to do that is shown on my first post. The modification applied caused the LEDs not to turn on as designed but, the counter did work.

Based on suggestions received on this thread, I consolidated the timers into one and tested the turn on of LEDs only and worked. Then I tested the counters and didn’t work.

For troubleshooting purposes, I created two timers, one to turn on the LEDs and the other to count the times the LEDs are turned on. I know it’s a cumbersome way of programming but it’s an easy way to identify the problem, at least for me.

So, that’s where I’m now, trying to understand why the counters are producing an erratic reading.

1 Like