Run 8 Pumps From Blynk

@myggle only looked through the last few posts in this thread but I see you already have:

pumpPin[x]

Which is an array from 0 to 7, inclusive.

You can use this same array for Blynk LED’s.

Blynk.virtualWrite(pumpPin[x] + 14, 255); // for ON or 0 for OFF

Thanks Costas. How would I correlate each LED widget to an array position? I don’t comprehend how the array position associates to any of the virtual pins. Can you expound?

I was going to add this text.

I like to see virtual pins referenced as Vx but the clever Blynk guys allow you to access them without the V prefix i.e. the virtualWrite knows you want to access a virtual pin and not a digital pin.

I believe you can actually do something like this but it’s not necessary:

Blynk.virtualWrite( "V" + String(pumpPin[x] + 14), 255); // for ON or 0 for OFF

1 Like

I’m confused about what (“V” + String( means. I think I understand what the rest means though. Also, would I need to name and initialize each position of the array of virtual pins?

WidgetLED LED1(V14);
WidgetLED LED2(V15);
WidgetLED LED3(V16);
WidgetLED LED4(V17);
WidgetLED LED5(V18);
WidgetLED LED6(V19);
WidgetLED LED7(V20);
WidgetLED LED8(V21);
int indicators[8] = { LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8 };

You don’t need all that WidgetLED stuff, just complicates things. The widget is simply a virtual pin that you write 255 or 0 to with virtualWrite.

As I say you don’t actually need the “V” but what that bit means is:

take the array number (0 to 7) and add 14 to give 14 to 21 and then convert this number to it’s String format and prefix it with a V.

Hio Costas.

I havn’t ever seen a virtualwrite in any code, with first parameter as a string,
I’m just curious have you tried it and it worked?

As Costas mentioned, you can skip the WidgetLED object.

Widget Leds have two states, a value of 0 equals off and 1 equals on, therefore you need no other interaction or special code other than doing a virtual write on desired led.

You need a way to store your “array of leds”, This you did fine ealier but you need to save it as an array of integers because that is what the virtual pin references are defined as.

int dosingLEDs[8]  = { V14, V15, V16, V17, V18, V19, V20, V21 };

Then just find your appropriate places in code to add

Blynk.virtualWrite(dosingLEDs[x], 1)  // for on
Blynk.virtualWrite(dosingLEDs[x], 0)  // for off

When you want it to turn on/off

2 Likes

Thanks again @Fettkeewl, your suggestions gave me what I needed yet again. Thanks also to @Costas for the guidance!

For anyone that uses this, apologies for lack of order with Virtual pins. This is derived from my larger project.


/*

*/
#include <SPI.h>                      //Used by Blynk
#include <Ethernet.h>                 //Used by Blynk
#include <BlynkSimpleEthernet.h>      //Used by Blynk
#include <SimpleTimer.h>
#define BLYNK_PRINT Serial
char auth[] = "PasteAuthKeyBetweenQuotes";       //Paste code that app emailed you between "quotes"

//-Digital Pins - Peristaltic Pump Variables - 00 Series Pins
const int pumpPin[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
int dosingLEDs[8]  = { V14, V15, V16, V17, V18, V19, V20, V21 };
uint32_t multiplier[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; //ms per ml
uint32_t startPump = 0;
uint32_t runCount;
bool pumpRunning = false;
const char *nuteType[8] = { "GH Armor Si", "GH Flora Blend", "GH CALiMAGic", "GH Kool Bloom",
                            "GH Flora Gro", "GH Flora Micro", "GH Flora Bloom", "GH pH Down"
                          }; //Text Printed to Terminal Widget^^

float DOSEml;      //Step Widget (0.25 per step, send step/NO, loop values ON)
int button = 0;   //Button Widget set to Switch
int x;           //Correlates Array Positions with Pump Motor Pins
int calibration;

BLYNK_WRITE(V4) {
  x = param.asInt() - 1;
}
BLYNK_WRITE(V5) {
  DOSEml = param.asFloat();
}
BLYNK_WRITE(V6) {
  button = param.asInt();
}
BLYNK_WRITE(V13) {
  calibration = param.asInt();
}

SimpleTimer timer;                    // SimpleTimer instance named timer
WidgetTerminal terminal(V8);

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth);
  while (Blynk.connect() == false) {}
  timer.setInterval(200L, dosingPumps);
  for (int p = 0; p <= 7; p++)
  {
    pinMode(pumpPin[p], OUTPUT);
  }
  Blynk.virtualWrite(V4, 0);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V6, 0);
  Blynk.virtualWrite(V13, 0);
}

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

void dosingPumps()
{
  if (button == 1 && pumpRunning == false)
  {
    multiplier[x] = calibration;
    Blynk.virtualWrite(V4, 0);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V6, 0);
    pumpRunning = true;
    digitalWrite(pumpPin[x], HIGH);
    Blynk.virtualWrite(dosingLEDs[x], 1);
    startPump = millis();
    runCount = DOSEml * multiplier[x];
    terminal.print("Dosing in: ");
    terminal.print(DOSEml);
    terminal.print(" milliliters of ");
    terminal.println(nuteType[x]);
  }
  if (millis() - startPump > runCount)
  {
    digitalWrite(pumpPin[x], LOW);
    Blynk.virtualWrite(dosingLEDs[x], 0);
    pumpRunning = false;
    button = 0;
  }
  terminal.flush();
}

Edit - As it turns out, the LED needs an analog value to illuminate the LED accordingly, so the value of “1” illuminated the LED to it’s dimmest setting. I simply changed it to 255, and viola!

That’s not true, they can be off and partly on all the way up to fully on (255).

@myggle notice your array of pumps is defined as:

int pumpPin[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };

So the addition is plus 12 not plus 14 e.g.

  for(int x = 0; x < 8; x++){
    Blynk.virtualWrite( pumpPin[x] + 12, 255); // for fully ON
  }
  delay(1000);

  for(int x = 0; x < 8; x++){
    Blynk.virtualWrite( pumpPin[x] + 12, 0); // for fully OFF 
  }

Ay true that my bad :stuck_out_tongue:

The line that Fettkeewl offered;

int dosingLEDs[8]  = { V14, V15, V16, V17, V18, V19, V20, V21 };

achieved the desired result in the array, so no added math was needed.

Plus also;

EEK!?!?!?:grimacing:

1 Like

Costas approach saves you the need to define that array “dosingLeds” since ultimateley the value that goes into virtualWrite will be the same in both cases, an integer between 14 and 21 with appropriate value.:slight_smile:

if x = 0

Blynk.virtualWrite(dosingLEDs[0], 1)   == Blynk.virtualWrite(14, 1)  // as in V14.
Blynk.virtualWrite(pumpPin[0] + 12, 1)  == Blynk.virtualWrite(2 + 12, 1)  // pumpPin[0] = 2 (your digital pin #)
2 Likes

Yes sorry about that @myggle. I just knocked up a quick "Knight Rider2 project for testing purposes and the proper way is with BlynkTimer (formerly known as SimpleTimer).

Precisely, we have projects with huge arrays for IR and RF and we can’t afford to duplicate them unnecessarily or the ESP’s will run out of memory. Not an issue in smaller projects but a good habit to get into.

@Fettkeewl tested Blynk.virtualWrite( "V" + String(pumpPin[x] + 12), 0);// for fully OFF and it fails to compile but pretty sure it worked a long time ago when we last checked. Will investigate further.

1 Like

Could only find these :slight_smile:

 void virtualWrite(int pin, Args... values) {
        char mem[BLYNK_MAX_SENDBYTES];
        BlynkParam cmd(mem, 0, sizeof(mem));
        cmd.add("vw");
        cmd.add(pin);
        cmd.add_multi(values...);
        static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE, 0, cmd.getBuffer(), cmd.getLength()-1);
    }

    /**
     * Sends buffer to a Virtual Pin
     *
     * @param pin  Virtual Pin number
     * @param buff Data buffer
     * @param len  Length of data
     */
 
    /**
     * Sends BlynkParam to a Virtual Pin
     *
     * @param pin  Virtual Pin number
     * @param param
     */
    void virtualWrite(int pin, const BlynkParam& param) {
        virtualWriteBinary(pin, param.getBuffer(), param.getLength());
    }

    void virtualWrite(int pin, const BlynkParamAllocated& param) {
        virtualWriteBinary(pin, param.getBuffer(), param.getLength());
    }

@Fettkeewl I was just trying to find the entries in the library and as you have shown the pins are defined as integers, not Strings. Not sure where the system changes Vx to simply x.

@Fettkeewl ok I see, in BlynkHandlers.h we have:

#define V0  0
#define V1  1
#define V2  2
#define V3  3
#define V4  4
#define V5  5
#define V6  6
#define V7  7
#define V8  8
#define V9  9
#define V10 10
#define V11 11
#define V12 12
#define V13 13
#define V14 14
#define V15 15
#define V16 16
#define V17 17
#define V18 18
#define V19 19
#define V20 20
#define V21 21
#define V22 22
#define V23 23
#define V24 24
#define V25 25
#define V26 26
#define V27 27
#define V28 28
#define V29 29
#define V30 30
#define V31 31 

And more for V32 to V127 etc

2 Likes
  #define Physical2VirtualMap 12 // so digital 2 is virtual 14, through to digital 9 is virtual 21 
  byte pumpPin[8] = { 2, 3, 4, 5, 6, 7, 8, 9 }; // pumps attached to these digital pins (on an Arduino not an ESP)
  byte firstPin = pumpPin[0];
  byte lastPin  = pumpPin[7];
  #define FullON 255
  #define FullOFF  0
  
  for(byte LEDvirtualPin = firstPin + Physical2VirtualMap; LEDvirtualPin <= lastPin + Physical2VirtualMap; LEDvirtualPin++){
    Serial.println( "V" + String(LEDvirtualPin) + " was turned ON"); 
    Blynk.virtualWrite( LEDvirtualPin, FullON); // for fully ON
  }
  
  for(byte LEDvirtualPin = firstPin + Physical2VirtualMap; LEDvirtualPin <= lastPin + Physical2VirtualMap; LEDvirtualPin++){
    Serial.println( "V" + String(LEDvirtualPin) + " was turned OFF");  
    Blynk.virtualWrite( LEDvirtualPin, FullOFF); // for fully OFF 
  } 

Using virtual writes like that in a loop, I wonder if it could possible crash the connection? If there is a lot of subsequent writes, would you recommend tossing in a if statement for yield every 4-5 writes or is it not necessary?

1 Like

It works ok on my WeMos, even though the pump settings are for Arduino pins 2 to 9.
Serial.println() will slow the loop down a little but if it’s a problem I would include something like this in the loop:

delay(smallValuefromSlider); // guess 1 to 5ms

Much more likely to be needed on the super slow Arduinos.

I wasn’t worried about the mcu not coping it, more like software wd timeout or blynk disconnection from server due to spamming writes! Guess I’ll find out the day I need it :smile: